trabajo-afectivo/app/models/store/provider/file.rb

69 lines
1.6 KiB
Ruby
Raw Normal View History

2022-01-01 13:38:12 +00:00
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class Store::Provider::File
2015-04-27 21:44:41 +00:00
# write file to fs
def self.add(data, sha)
location = get_location(sha)
# write file to file system
if !File.exist?(location)
Rails.logger.debug { "storge write '#{location}' (600)" }
File.binwrite(location, data)
end
2015-04-27 21:44:41 +00:00
File.chmod(0o600, location)
validate_file(sha)
rescue # .validate_file will raise an error if contents do not match SHA
delete(sha)
fail_count ||= 0
fail_count.zero? ? (fail_count += 1) && retry : raise
end
2015-04-27 21:44:41 +00:00
# read file from fs
def self.get(sha)
location = get_location(sha)
Rails.logger.debug { "read from fs #{location}" }
content = File.binread(location)
local_sha = Digest::SHA256.hexdigest(content)
2015-04-27 21:44:41 +00:00
# check sha
raise "File corrupted: path #{location} does not match SHA digest (#{local_sha})" if local_sha != sha
content
end
2015-04-27 21:44:41 +00:00
class << self
alias validate_file get
end
# unlink file from fs
def self.delete(sha)
location = get_location(sha)
if File.exist?(location)
Rails.logger.info "storage remove '#{location}'"
File.delete(location)
end
# remove empty ancestor directories
storage_fs_path = Rails.root.join('storage/fs')
location.parent.ascend do |path|
break if !Dir.empty?(path)
break if path == storage_fs_path
Dir.rmdir(path)
end
end
2015-04-27 21:44:41 +00:00
# generate file location
def self.get_location(sha)
parts = sha.scan(%r{^(.{4})(.{4})(.{5})(.{5})(.{7})(.{7})(.*)}).first
Rails.root.join('storage/fs', *parts).tap { |path| FileUtils.mkdir_p(path.parent) }
end
end