From d30231e983c019fbe3fcd6a2a06a461fefa58dab Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 1 Jul 2017 00:04:19 +0200 Subject: [PATCH] Go with site instead of store Better fit for upload/download terminology. --- lib/active_file/blob.rb | 6 ++- lib/active_file/{store.rb => site.rb} | 12 +++++- lib/active_file/sites/disk_site.rb | 53 +++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) rename lib/active_file/{store.rb => site.rb} (53%) create mode 100644 lib/active_file/sites/disk_site.rb diff --git a/lib/active_file/blob.rb b/lib/active_file/blob.rb index 201edf24df..d3bc831926 100644 --- a/lib/active_file/blob.rb +++ b/lib/active_file/blob.rb @@ -1,3 +1,5 @@ +require "active_file/site" + # Schema: id, key, filename, content_type, metadata, byte_size, digest, created_at class ActiveFile::Blob < ActiveRecord::Base self.table_name = "active_file_blobs" @@ -6,7 +8,7 @@ class ActiveFile::Blob < ActiveRecord::Base store :metadata, coder: JSON class_attribute :verifier, default: -> { Rails.application.message_verifier('ActiveFile') } - class_attribute :storage + class_attribute :site class << self def find_verified(signed_id) @@ -31,7 +33,7 @@ class ActiveFile::Blob < ActiveRecord::Base end def delete - storage.delete token + site.delete token end def purge diff --git a/lib/active_file/store.rb b/lib/active_file/site.rb similarity index 53% rename from lib/active_file/store.rb rename to lib/active_file/site.rb index bdac4eab9e..8a915c2e17 100644 --- a/lib/active_file/store.rb +++ b/lib/active_file/site.rb @@ -1,4 +1,7 @@ -class ActiveFile::Store +class ActiveFile::Site + def initialize + end + def upload(key, data) end @@ -23,4 +26,11 @@ class ActiveFile::Store def move(from_key:, to_key:) end + + + private + def normalize_key(key) + # disallow "." and ".." segments in the key + key.split(%r[/]).reject { |s| s == "." || s == ".." } + end end diff --git a/lib/active_file/sites/disk_site.rb b/lib/active_file/sites/disk_site.rb new file mode 100644 index 0000000000..71dc8d078b --- /dev/null +++ b/lib/active_file/sites/disk_site.rb @@ -0,0 +1,53 @@ +class ActiveFile::Sites::DiskSite < ActiveFile::Site + attr_reader :root + + def initialize(root) + @root = root + end + + def upload(key, data) + File.open(make_path_for(key), "wb") do |file| + while chunk = data.read(65536) + file.write(chunk) + end + end + end + + def download(key) + if block_given? + open(key) do |file| + while data = file.read(65536) + yield data + end + end + else + open(key, &:read) + end + end + + def delete(key) + File.delete(path_for(key)) + true + end + + def size(key) + File.size(path_for(key)) + end + + def checksum(key) + Digest::MD5.file(path_for(key)).hexdigest + end + + private + def path_for(key) + File.join(root, folder_for(key), normalize(key)) + end + + def folder_for(key) + [key[0..1], key[2..3]].join("/") + end + + def make_path_for(key) + path_for(key).tap { |path| FileUtils.mkdir_p File.dirname(path) } + end +end