dragonfly-cache 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69db42bcdd7613f8f7738bec974e989b3863d508b24757fff67b4e003b6b5a04
4
- data.tar.gz: 5b48ec8599fb6aed358fb281d6f4c137aa75c427cc22554557cf61f99e0ee9f1
3
+ metadata.gz: d9c2bd6a296538d40627ac2d72d59b22899b939f058df6733c536cb8ccb31154
4
+ data.tar.gz: c42cb333f27257b8b2522433dc1a303768eb8eca01c829793e7e30ac1e51aa23
5
5
  SHA512:
6
- metadata.gz: 789d49580b89f059a1086466fc22975e71bcc8cd435467efe4000dc3b1da7609187442f1514687b42df1d5ba1bd5f6543b034a6b5cb046f36a9ff3bcb1b6092c
7
- data.tar.gz: cf0a7cd0b9d29a7470ea057e085c2f92cb495bf74cb87cff5d6151776d51db06f1d8b44058a7d8919eba2b0cd261ba363a4c407ac396924dfa242c102b57aacd
6
+ metadata.gz: 405297344133ee35cb4547dd1d7499020cb77f751e3e81e23cf2378a77e6e6d5cb83e91fc11e60d105cd131bf54d67364bf197ab244299e700ba8f41ea4e7b75
7
+ data.tar.gz: fbbf31316483fd3721015225e25145967ad0dc2a929b68e042d5a0a064ca23958eba53c1328aace339dce28aa7b926e430c44e978722541f12b6743f96fa1fa4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dragonfly-cache (0.1.2)
4
+ dragonfly-cache (0.1.3)
5
5
  dragonfly (~> 1.1.5)
6
6
  i18n
7
7
 
@@ -42,7 +42,7 @@ GEM
42
42
  diff-lcs (>= 1.2.0, < 2.0)
43
43
  rspec-support (~> 3.8.0)
44
44
  rspec-support (3.8.0)
45
- rubocop (0.58.2)
45
+ rubocop (0.59.0)
46
46
  jaro_winkler (~> 1.5.1)
47
47
  parallel (~> 1.10)
48
48
  parser (>= 2.5, != 2.5.1.1)
data/README.md CHANGED
@@ -43,3 +43,7 @@ Configured as this, cached files will be stored in `/public/media-cache/:sha/:na
43
43
  ## How does it work?
44
44
 
45
45
  `dragonfly-cache` use a method similar to [the one described in the Dragonfly documentation to process files on-the-fly and serve them remotely](http://markevans.github.io/dragonfly/cache#processing-on-the-fly-and-serving-remotely) but use only `define_url`.
46
+
47
+ ## Credits
48
+
49
+ The dragonfly photography used in specs is a work from [André Karwath](https://commons.wikimedia.org/wiki/User:Aka) and is licensed under the [Creative Commons Attribution-Share Alike 2.5 Generic](https://creativecommons.org/licenses/by-sa/2.5/deed.en) license.
@@ -15,6 +15,13 @@ module Dragonfly
15
15
  rewrite_url_format!
16
16
  end
17
17
 
18
+ def base_dir
19
+ @base_dir ||= begin
20
+ path_format = File.join(servers_options[:server_root], servers_options[:url_format])
21
+ path_format.split('/').take_while { |p| p != ':shaish' }.join('/')
22
+ end
23
+ end
24
+
18
25
  protected
19
26
 
20
27
  def validate!
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dragonfly/cache/storage'
3
+ require 'dragonfly/cache/mapper/yaml'
4
+ require 'dragonfly/cache/storage/local'
4
5
 
5
6
  module Dragonfly
6
7
  module Cache
@@ -10,79 +11,65 @@ module Dragonfly
10
11
  MIN_SHA_SIZE = 2
11
12
  MAX_SHA_SIZE = 16 # Length of SHA identifier generated by Dragonfly
12
13
 
13
- attr_reader :plugin, :storage, :sha_size
14
+ attr_reader :plugin, :storage, :map
14
15
 
15
- delegate %i[servers_options] => :plugin
16
- delegate %i[write writen? current_max_sha_size base_dir] => :storage
16
+ delegate %i[config] => :plugin
17
17
 
18
18
  def initialize(plugin)
19
- @plugin = plugin
20
- @storage = Dragonfly::Cache::Storage.new(self)
21
- initialize!
19
+ @plugin = plugin
20
+ @map = Dragonfly::Cache::Mapper::Yaml.new(config.servers_options)
21
+ @storage = Dragonfly::Cache::Storage::Local.new(config.servers_options)
22
22
  end
23
23
 
24
- def valid_uri?(job, uri)
25
- return true unless wrong_key?(job, uri) || wrong_value?(job, uri)
26
- increase_sha_size!
27
- false
28
- end
29
-
30
- def store(job, uri)
31
- write(job, uri) unless writen?(job, uri)
32
- map(job, uri) unless mapped?(job, uri)
33
- rescue Dragonfly::Cache::Error => e
34
- Dragonfly.warn(e.message)
35
- end
24
+ def cache(job)
25
+ return @map[job.sha] if @map.key?(job.sha)
36
26
 
37
- protected
38
-
39
- def wrong_key?(job, uri)
40
- @cache_map.value?(uri.path) && @cache_map.key(uri.path) != job.sha
27
+ store(job, yield)
41
28
  end
42
29
 
43
- def wrong_value?(job, uri)
44
- @cache_map.key?(job.sha) && @cache_map[job.sha] != uri.path
30
+ def valid?(job, uri)
31
+ valid = (@map.key?(job.sha) && @map[job.sha] == uri) || !@map.key?(job.sha)
32
+ increase_sha_size! unless valid
33
+ valid
45
34
  end
46
35
 
47
- def initialize!
48
- detect_sha_size
49
- load_map
50
- rescue ::StandardError => e
51
- raise Dragonfly::Cache::Error, e.message
36
+ def job_options(job)
37
+ {
38
+ shaish: shaish(job),
39
+ normalized_name: normalized_name(job)
40
+ }
52
41
  end
53
42
 
54
- def detect_sha_size
55
- @sha_size = [current_max_sha_size, MIN_SHA_SIZE].compact.max
56
- @sha_size = [@sha_size, MAX_SHA_SIZE].min
57
- end
58
-
59
- def increase_sha_size!
60
- raise Error, "Can't build longer :sha identifier" if @sha_size == MAX_SHA_SIZE
61
- @sha_size += 1
43
+ protected
62
44
 
63
- @cache_map.clear
64
- save_map
45
+ def shaish(job)
46
+ job.sha[0..(sha_size - 1)]
65
47
  end
66
48
 
67
- def map_path
68
- @map_path ||= File.join(base_dir, 'map.yml')
49
+ def normalized_name(job)
50
+ basename = job.basename || job.signature
51
+ sanitized = basename.gsub(/[[:space:][:punct:][:cntrl:]]/, ' ').squeeze(' ').strip
52
+ transliterated = I18n.transliterate(sanitized, replacement: ' ').squeeze(' ').strip
53
+ downcased = (transliterated.empty? ? job.signature : transliterated).downcase.tr(' ', '-')
54
+ [downcased, job.ext].compact.join('.')
69
55
  end
70
56
 
71
- def load_map
72
- @cache_map = File.size?(map_path) ? YAML.load_file(map_path) : {}
57
+ def sha_size
58
+ @sha_size ||= [[storage.sha_size, MIN_SHA_SIZE].compact.max, MAX_SHA_SIZE].min
73
59
  end
74
60
 
75
- def save_map
76
- File.open(map_path, 'wb') { |f| YAML.dump(@cache_map, f) }
77
- end
61
+ def increase_sha_size!
62
+ raise Error, "Can't build longer :sha identifier" if @sha_size == MAX_SHA_SIZE
78
63
 
79
- def map(job, uri)
80
- @cache_map[job.sha] = uri.path
81
- save_map
64
+ @sha_size += 1
82
65
  end
83
66
 
84
- def mapped?(job, _uri)
85
- @cache_map.key?(job.sha)
67
+ def store(job, url)
68
+ storage.store(url, job)
69
+ map.store(job.sha, url)
70
+ url
71
+ rescue Dragonfly::Cache::Error => e
72
+ Dragonfly.warn(e.message)
86
73
  end
87
74
  end
88
75
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Dragonfly
6
+ module Cache
7
+ module Mapper
8
+ class Yaml
9
+ extend Forwardable
10
+
11
+ attr_reader :root, :internal
12
+ delegate %i[[] key? value? keys values] => :internal
13
+
14
+ def initialize(config)
15
+ @root = config[:server_root]
16
+ @internal = {}
17
+ end
18
+
19
+ def store(key, value)
20
+ @internal[key] = value
21
+ save!
22
+ end
23
+
24
+ alias []= store
25
+
26
+ protected
27
+
28
+ def path
29
+ @path ||= File.join(root, 'map.yml')
30
+ end
31
+
32
+ def load!
33
+ @internal = File.size?(path) ? YAML.load_file(path) : {}
34
+ end
35
+
36
+ def save!
37
+ File.open(path, 'wb') { |f| YAML.dump(@internal, f) }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -17,12 +17,11 @@ module Dragonfly
17
17
 
18
18
  attr_reader :config, :manager
19
19
 
20
- delegate %i[servers_options] => :config
21
- delegate %i[sha_size valid_uri? store] => :manager
20
+ delegate %i[cache valid? job_options] => :manager
22
21
 
23
22
  def call(app, cache_servers_options = {})
24
- @config = Dragonfly::Cache::Config.new(cache_servers_options)
25
- @manager = Dragonfly::Cache::Manager.new(self)
23
+ @config = Dragonfly::Cache::Config.new(cache_servers_options)
24
+ @manager = Dragonfly::Cache::Manager.new(self)
26
25
 
27
26
  app.define_url do |app, job, opts|
28
27
  url_for(app, job, opts)
@@ -32,41 +31,24 @@ module Dragonfly
32
31
  end
33
32
  end
34
33
 
35
- protected
36
-
37
34
  def url_for(app, job, opts)
38
- uri = find_valid_url_for(app, job, opts)
39
- # File are stored on url building instead of in a before_serve block to allow use of assets host
40
- store(job, uri)
41
- uri.to_s
35
+ cache(job) { build_url_for(app, job, opts) }
42
36
  end
43
37
 
44
- def find_valid_url_for(app, job, opts)
38
+ protected
39
+
40
+ def build_url_for(app, job, opts)
45
41
  loop do
46
- url = server_for(app).url_for(job, options_for(job).merge(opts))
47
- uri = URI.parse(url)
48
- uri.query = nil
49
- uri.fragment = nil
50
- return uri if valid_uri?(job, uri)
42
+ url = server_for(app).url_for(job, job_options(job).merge(opts))
43
+ path = URI.parse(url).path
44
+ return path if valid?(job, path)
51
45
  end
52
46
  end
53
47
 
54
- def options_for(job)
55
- basename = job.basename || job.signature
56
- sanitized = basename.gsub(/[[:space:][:punct:][:cntrl:]]/, ' ').squeeze(' ').strip
57
- transliterated = I18n.transliterate(sanitized, replacement: ' ').squeeze(' ').strip
58
- downcased = (transliterated.empty? ? job.signature : transliterated).downcase.tr(' ', '-')
59
-
60
- {
61
- shaish: job.sha[0..(sha_size - 1)],
62
- normalized_name: [downcased, job.ext].join('.')
63
- }
64
- end
65
-
66
48
  def server_for(app)
67
49
  @@servers[app.name] ||= begin
68
50
  server = app.server.dup
69
- servers_options.each do |name, value|
51
+ config.servers_options.each do |name, value|
70
52
  server.send("#{name}=", value) if server.respond_to?("#{name}=")
71
53
  end
72
54
  server
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dragonfly
4
+ module Cache
5
+ module Storage
6
+ class Local
7
+ attr_reader :root, :format
8
+
9
+ def initialize(config)
10
+ @root = config[:server_root]
11
+ @format = config[:url_format]
12
+ end
13
+
14
+ def store(url, job)
15
+ job.to_file(path(url), mode: 0o644)
16
+ end
17
+
18
+ def sha_size
19
+ longest = Dir["#{base_dir}/*"].select { |p| File.directory?(p) }.max { |a, b| a <=> b }
20
+ (longest ? File.basename(longest).size : nil)
21
+ end
22
+
23
+ protected
24
+
25
+ def path(url)
26
+ File.join(root, url)
27
+ end
28
+
29
+ def base_dir
30
+ @base_dir ||= begin
31
+ path_format = File.join(root, format)
32
+ path_format.split('/').take_while { |p| p != ':shaish' }.join('/')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dragonfly
4
4
  module Cache
5
- VERSION = '0.1.2'
5
+ VERSION = '0.1.3'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gaël-Ian Havard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-07 00:00:00.000000000 Z
11
+ date: 2018-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dragonfly
@@ -113,8 +113,9 @@ files:
113
113
  - lib/dragonfly/cache.rb
114
114
  - lib/dragonfly/cache/config.rb
115
115
  - lib/dragonfly/cache/manager.rb
116
+ - lib/dragonfly/cache/mapper/yaml.rb
116
117
  - lib/dragonfly/cache/plugin.rb
117
- - lib/dragonfly/cache/storage.rb
118
+ - lib/dragonfly/cache/storage/local.rb
118
119
  - lib/dragonfly/cache/version.rb
119
120
  homepage: https://github.com/notus-sh/dragonfly-cache
120
121
  licenses:
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dragonfly
4
- module Cache
5
- class Storage
6
- extend Forwardable
7
-
8
- attr_reader :manager
9
-
10
- delegate %i[servers_options] => :manager
11
-
12
- def initialize(manager)
13
- @manager = manager
14
- check_directory!(base_dir)
15
- end
16
-
17
- def current_max_sha_size
18
- longest = Dir["#{base_dir}/*"].select { |p| File.directory?(p) }.max { |a, b| a <=> b }
19
- (longest ? File.basename(longest).size : nil)
20
- end
21
-
22
- def write(job, uri)
23
- path = cache_path(uri)
24
- check_directory!(File.dirname(path))
25
- with_umask(0o022) do
26
- job.to_file(path, mode: 0o644, mkdirs: false)
27
- end
28
- end
29
-
30
- def writen?(_job, uri)
31
- File.exist?(cache_path(uri))
32
- end
33
-
34
- def base_dir
35
- @base_dir ||= begin
36
- path_format = File.join(servers_options[:server_root], servers_options[:url_format])
37
- path_format.split('/').take_while { |p| p != ':shaish' }.join('/')
38
- end
39
- end
40
-
41
- protected
42
-
43
- def check_directory!(directory)
44
- return if File.exist?(directory) && File.directory?(directory) && File.writable?(directory)
45
- with_umask(0o022) do
46
- File.unlink(directory) if File.exist?(directory) && !File.directory?(directory)
47
- FileUtils.mkdir_p(directory, mode: 0o755) unless File.exist?(directory)
48
- File.chmod(0o755, directory) unless File.writable?(directory)
49
- end
50
- rescue ::StandardError => e
51
- raise Dragonfly::Cache::Error, e.message
52
- end
53
-
54
- def with_umask(umask)
55
- original_umask = File.umask(umask)
56
- begin
57
- yield
58
- ensure
59
- File.umask(original_umask)
60
- end
61
- end
62
-
63
- def cache_path(uri)
64
- File.join(servers_options[:server_root], uri.path)
65
- end
66
- end
67
- end
68
- end