class Safrano::Media::Static
Simple static File/Directory based media store handler similar to Rack::Static with a flat directory structure
Public Class Methods
new(root: nil, mediaklass:)
click to toggle source
# File lib/odata/collection_media.rb, line 22 def initialize(root: nil, mediaklass:) @root = File.absolute_path(root || Dir.pwd) @file_server = ::Rack::File.new(@root) @media_class = mediaklass @media_dir_name = mediaklass.to_s register end
Public Instance Methods
abs_filename(entity)
click to toggle source
absolute filename
# File lib/odata/collection_media.rb, line 78 def abs_filename(entity) File.absolute_path(filename(entity), @root) end
abs_path(entity)
click to toggle source
/@root/Photo/1
# File lib/odata/collection_media.rb, line 73 def abs_path(entity) File.absolute_path(media_path(entity), @root) end
create_abs_class_dir()
click to toggle source
# File lib/odata/collection_media.rb, line 34 def create_abs_class_dir FileUtils.makedirs @abs_klass_dir unless Dir.exist?(@abs_klass_dir) end
filename(entity)
click to toggle source
relative to @root eg Photo/1/1
# File lib/odata/collection_media.rb, line 63 def filename(entity) Dir.chdir(abs_path(entity)) do # simple design: one file per directory, and the directory # contains the media entity-id --> implicit link between the media # entity File.join(media_path(entity), Dir.glob('*').max) end end
finalize()
click to toggle source
# File lib/odata/collection_media.rb, line 38 def finalize create_abs_class_dir end
in_media_directory(entity) { || ... }
click to toggle source
# File lib/odata/collection_media.rb, line 89 def in_media_directory(entity) mpi = media_directory(entity) Dir.mkdir mpi unless Dir.exist?(mpi) Dir.chdir mpi do yield end end
media_directory(entity)
click to toggle source
this is relative to abs_klass_dir(entity) eg to /@root/Photo simplest implementation is media_directory
= entity.media_path_id –> we get a 1 level depth flat directory structure
# File lib/odata/collection_media.rb, line 85 def media_directory(entity) entity.media_path_id end
media_path(entity)
click to toggle source
this is relative to @root eg. Photo/1
# File lib/odata/collection_media.rb, line 57 def media_path(entity) File.join(@media_dir_name, media_directory(entity)) end
odata_delete(entity:)
click to toggle source
# File lib/odata/collection_media.rb, line 97 def odata_delete(entity:) Dir.chdir(@abs_klass_dir) do in_media_directory(entity) do Dir.glob('*').each { |oldf| File.delete(oldf) } end end end
odata_get(request:, entity:)
click to toggle source
minimal working implementation…
Note: @file_server works relative to @root directory
# File lib/odata/collection_media.rb, line 44 def odata_get(request:, entity:) media_env = request.env.dup media_env['PATH_INFO'] = filename(entity) fsret = @file_server.call(media_env) if fsret.first == 200 # provide own content type as we keep it in the media entity fsret[1]['Content-Type'] = entity.content_type end fsret end
register()
click to toggle source
# File lib/odata/collection_media.rb, line 30 def register @abs_klass_dir = File.absolute_path(@media_dir_name, @root) end
replace_file(data:, filename:, entity:)
click to toggle source
Here as well, MVP implementation
# File lib/odata/collection_media.rb, line 127 def replace_file(data:, filename:, entity:) Dir.chdir(@abs_klass_dir) do in_media_directory(entity) do version = nil Dir.glob('*').sort.each do |oldf| version = oldf File.delete(oldf) end filename = (version.to_i + 1).to_s File.open(filename, 'wb') { |f| IO.copy_stream(data, f) } end end end
ressource_version(entity)
click to toggle source
needed for having a changing media ressource “source” metadata after each upload, so that clients get informed about new versions of the same media ressource
# File lib/odata/collection_media.rb, line 118 def ressource_version(entity) Dir.chdir(@abs_klass_dir) do in_media_directory(entity) do Dir.glob('*').max end end end
save_file(data:, filename:, entity:)
click to toggle source
Here as well, MVP implementation
# File lib/odata/collection_media.rb, line 106 def save_file(data:, filename:, entity:) Dir.chdir(@abs_klass_dir) do in_media_directory(entity) do filename = '1' File.open(filename, 'wb') { |f| IO.copy_stream(data, f) } end end end