2016-10-19 03:11:36 +00:00
|
|
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
2015-04-27 22:21:30 +00:00
|
|
|
class Store::Provider::File
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-05-06 12:56:12 +00:00
|
|
|
# write file to fs
|
2015-04-27 22:21:30 +00:00
|
|
|
def self.add(data, sha)
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-05-06 12:56:12 +00:00
|
|
|
# install file
|
2016-02-29 11:58:21 +00:00
|
|
|
location = get_location(sha)
|
2015-05-06 12:56:12 +00:00
|
|
|
permission = '600'
|
2016-02-29 11:58:21 +00:00
|
|
|
if !File.exist?(location)
|
|
|
|
Rails.logger.debug "storge write '#{location}' (#{permission})"
|
|
|
|
file = File.new(location, 'wb')
|
2016-02-02 12:50:49 +00:00
|
|
|
file.write(data)
|
2015-05-06 12:56:12 +00:00
|
|
|
file.close
|
2015-04-27 22:21:30 +00:00
|
|
|
end
|
2016-02-29 11:58:21 +00:00
|
|
|
File.chmod(permission.to_i(8), location)
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-05-06 12:56:12 +00:00
|
|
|
# check sha
|
2016-02-02 12:50:49 +00:00
|
|
|
local_sha = Digest::SHA256.hexdigest(get(sha))
|
2015-05-06 12:56:12 +00:00
|
|
|
if sha != local_sha
|
2016-03-01 14:26:46 +00:00
|
|
|
raise "ERROR: Corrupt file in fs #{location}, sha should be #{sha} but is #{local_sha}"
|
2015-04-27 22:21:30 +00:00
|
|
|
end
|
2015-05-06 12:56:12 +00:00
|
|
|
|
|
|
|
true
|
2015-04-27 22:21:30 +00:00
|
|
|
end
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-04-27 22:21:30 +00:00
|
|
|
# read file from fs
|
2015-05-06 12:56:12 +00:00
|
|
|
def self.get(sha)
|
2016-02-29 11:58:21 +00:00
|
|
|
location = get_location(sha)
|
|
|
|
Rails.logger.debug "read from fs #{location}"
|
|
|
|
if !File.exist?(location)
|
2016-03-01 14:26:46 +00:00
|
|
|
raise "ERROR: No such file #{location}"
|
2015-04-27 22:21:30 +00:00
|
|
|
end
|
2016-02-29 11:58:21 +00:00
|
|
|
data = File.open(location, 'rb')
|
2015-04-27 22:21:30 +00:00
|
|
|
content = data.read
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-04-27 22:21:30 +00:00
|
|
|
# check sha
|
2016-02-02 12:50:49 +00:00
|
|
|
local_sha = Digest::SHA256.hexdigest(content)
|
2015-04-27 22:21:30 +00:00
|
|
|
if local_sha != sha
|
2016-03-01 14:26:46 +00:00
|
|
|
raise "ERROR: Corrupt file in fs #{location}, sha should be #{sha} but is #{local_sha}"
|
2015-04-27 22:21:30 +00:00
|
|
|
end
|
|
|
|
content
|
|
|
|
end
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-05-06 12:56:12 +00:00
|
|
|
# unlink file from fs
|
|
|
|
def self.delete(sha)
|
2016-02-29 11:58:21 +00:00
|
|
|
location = get_location(sha)
|
|
|
|
if File.exist?(location)
|
|
|
|
Rails.logger.info "storge remove '#{location}'"
|
|
|
|
File.delete(location)
|
2015-04-27 22:21:30 +00:00
|
|
|
end
|
2016-02-29 11:58:21 +00:00
|
|
|
|
|
|
|
# check if dir need to be removed
|
|
|
|
base = "#{Rails.root}/storage/fs"
|
|
|
|
locations = location.split('/')
|
2016-06-30 20:04:48 +00:00
|
|
|
(0..locations.count).reverse_each { |count|
|
2016-02-29 11:58:21 +00:00
|
|
|
local_location = locations[0, count].join('/')
|
|
|
|
break if local_location =~ %r{storage/fs/{0,4}$}
|
|
|
|
break if !Dir["#{local_location}/*"].empty?
|
|
|
|
FileUtils.rmdir(local_location)
|
|
|
|
}
|
2015-05-06 12:56:12 +00:00
|
|
|
end
|
2015-04-27 21:44:41 +00:00
|
|
|
|
2015-05-06 12:56:12 +00:00
|
|
|
# generate file location
|
2016-02-29 11:58:21 +00:00
|
|
|
def self.get_location(sha)
|
2015-04-27 22:21:30 +00:00
|
|
|
|
2015-05-06 12:56:12 +00:00
|
|
|
# generate directory
|
2016-02-29 11:58:21 +00:00
|
|
|
base = "#{Rails.root}/storage/fs/"
|
|
|
|
parts = []
|
|
|
|
length1 = 4
|
|
|
|
length2 = 5
|
|
|
|
length3 = 7
|
|
|
|
last_position = 0
|
2016-06-30 20:04:48 +00:00
|
|
|
(0..1).each { |_count|
|
2016-02-29 11:58:21 +00:00
|
|
|
end_position = last_position + length1
|
|
|
|
parts.push sha[last_position, length1]
|
|
|
|
last_position = end_position
|
|
|
|
}
|
2016-06-30 20:04:48 +00:00
|
|
|
(0..1).each { |_count|
|
2016-02-29 11:58:21 +00:00
|
|
|
end_position = last_position + length2
|
|
|
|
parts.push sha[last_position, length2]
|
|
|
|
last_position = end_position
|
|
|
|
}
|
2016-06-30 20:04:48 +00:00
|
|
|
(0..1).each { |_count|
|
2016-02-29 11:58:21 +00:00
|
|
|
end_position = last_position + length3
|
|
|
|
parts.push sha[last_position, length3]
|
|
|
|
last_position = end_position
|
|
|
|
}
|
|
|
|
path = parts[ 0..6 ].join('/') + '/'
|
|
|
|
file = sha[last_position, sha.length]
|
2015-05-06 12:56:12 +00:00
|
|
|
location = "#{base}/#{path}"
|
|
|
|
|
|
|
|
# create directory if not exists
|
2016-02-02 12:50:49 +00:00
|
|
|
if !File.exist?(location)
|
|
|
|
FileUtils.mkdir_p(location)
|
2015-05-06 12:56:12 +00:00
|
|
|
end
|
2016-02-29 11:58:21 +00:00
|
|
|
full_path = location += file
|
|
|
|
full_path.gsub('//', '/')
|
2014-05-03 12:34:36 +00:00
|
|
|
end
|
2015-05-06 12:56:12 +00:00
|
|
|
|
2015-04-27 14:15:29 +00:00
|
|
|
end
|