-
Notifications
You must be signed in to change notification settings - Fork 23
/
disk.rb
55 lines (48 loc) · 1.71 KB
/
disk.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# frozen_string_literal: true
module Valkyrie::Storage
class Disk
attr_reader :base_path, :path_generator, :file_mover
def initialize(base_path:, path_generator: BucketedStorage, file_mover: FileUtils.method(:mv))
@base_path = Pathname.new(base_path.to_s)
@path_generator = path_generator.new(base_path: base_path)
@file_mover = file_mover
end
# @param file [IO]
# @param resource [Valkyrie::Resource]
# @return [Valkyrie::StorageAdapter::File]
def upload(file:, resource: nil)
new_path = path_generator.generate(resource: resource, file: file)
FileUtils.mkdir_p(new_path.parent)
file_mover.call(file.path, new_path)
find_by(id: Valkyrie::ID.new("disk://#{new_path}"))
end
# @param id [Valkyrie::ID]
# @return [Boolean] true if this adapter can handle this type of identifer
def handles?(id:)
id.to_s.start_with?("disk://")
end
def file_path(id)
id.to_s.gsub(/^disk:\/\//, '')
end
# Return the file associated with the given identifier
# @param id [Valkyrie::ID]
# @return [Valkyrie::StorageAdapter::File]
def find_by(id:)
return unless handles?(id: id)
Valkyrie::StorageAdapter::File.new(id: Valkyrie::ID.new(id.to_s), io: ::File.open(file_path(id), 'rb'))
end
class BucketedStorage
attr_reader :base_path
def initialize(base_path:)
@base_path = base_path
end
def generate(resource:, file:)
Pathname.new(base_path).join(*bucketed_path(resource.id)).join(file.original_filename)
end
def bucketed_path(id)
cleaned_id = id.to_s.delete("-")
cleaned_id[0..5].chars.each_slice(2).map(&:join) + [cleaned_id]
end
end
end
end