dragonfly-cache 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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