123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
- class Store::Provider::File
- # write file to fs
- def self.add(data, sha)
- # install file
- location = get_location(sha)
- permission = '600'
- if !File.exist?(location)
- Rails.logger.debug "storge write '#{location}' (#{permission})"
- file = File.new(location, 'wb')
- file.write(data)
- file.close
- end
- File.chmod(permission.to_i(8), location)
- # check sha
- local_sha = Digest::SHA256.hexdigest(get(sha))
- if sha != local_sha
- raise "ERROR: Corrupt file in fs #{location}, sha should be #{sha} but is #{local_sha}"
- end
- true
- end
- # read file from fs
- def self.get(sha)
- location = get_location(sha)
- Rails.logger.debug "read from fs #{location}"
- if !File.exist?(location)
- raise "ERROR: No such file #{location}"
- end
- data = File.open(location, 'rb')
- content = data.read
- # check sha
- local_sha = Digest::SHA256.hexdigest(content)
- if local_sha != sha
- raise "ERROR: Corrupt file in fs #{location}, sha should be #{sha} but is #{local_sha}"
- end
- content
- end
- # unlink file from fs
- def self.delete(sha)
- location = get_location(sha)
- if File.exist?(location)
- Rails.logger.info "storge remove '#{location}'"
- File.delete(location)
- end
- # check if dir need to be removed
- base = "#{Rails.root}/storage/fs"
- locations = location.split('/')
- (0..locations.count).reverse_each { |count|
- 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)
- }
- end
- # generate file location
- def self.get_location(sha)
- # generate directory
- base = "#{Rails.root}/storage/fs/"
- parts = []
- length1 = 4
- length2 = 5
- length3 = 7
- last_position = 0
- (0..1).each { |_count|
- end_position = last_position + length1
- parts.push sha[last_position, length1]
- last_position = end_position
- }
- (0..1).each { |_count|
- end_position = last_position + length2
- parts.push sha[last_position, length2]
- last_position = end_position
- }
- (0..1).each { |_count|
- 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]
- location = "#{base}/#{path}"
- # create directory if not exists
- if !File.exist?(location)
- FileUtils.mkdir_p(location)
- end
- full_path = location += file
- full_path.gsub('//', '/')
- end
- end
|