breezy_pdf 0.0.14 → 0.0.15

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
  SHA1:
3
- metadata.gz: 5c79358f8f51d3ebf15997ad7c33afb65208ba61
4
- data.tar.gz: 885a161d944e8660535adef975eb8b2443d60d01
3
+ metadata.gz: 57bddc027c8cdfec7911f2cc59222a96c6122f87
4
+ data.tar.gz: 98ab1ae786bfa5b1a9f402ff07d2d3bea9268a8d
5
5
  SHA512:
6
- metadata.gz: 61d82471163ed28064662b8f453c365d8ac7f36e0e536db7eb418e741b12268a327482a94f6027f03def5cf18ca80c4d85dfe4e6104da67b7e7592c1eff2caa3
7
- data.tar.gz: db0752316cabec4f9b04d7ccd82f142bd5ac500bb15616641a977b942f9b2de7fdf9666d6276c2ee07d2ba8d069ae2fee0a02b0cb8b381932289891bf1bcccb9
6
+ metadata.gz: 4ac74f57b8b524fa6b2c30c940eef02a791a98602739b82133ab71bff13d3e9999743ad5f48c958b44f6d631e81028197944dec6827ecf03d136ba0df36cbc24
7
+ data.tar.gz: 1b2a275727eeac5f202907d89689053762d1e97eea896cad4710ce782770ff291b0ba32c221c9c8123571dd8302339acb5cb51e19b977d7426dd4e3ae0a3d24d
data/README.md CHANGED
@@ -8,6 +8,8 @@ No binaries to install. No reinventing the wheel to match HTML layouts. Just sim
8
8
 
9
9
  [Sign Up](https://BreezyPDF.com/) for an account to get started.
10
10
 
11
+ [View the Demo](https://ruby.demo.breezypdf.com) and the [Demo's Source Code](https://github.com/danielwestendorf/breezy_pdf-ruby-demo)
12
+
11
13
  ## Installation
12
14
 
13
15
  Add this line to your application's Gemfile:
@@ -134,6 +136,27 @@ BreezyPDF.setup do |config|
134
136
  # src: %r{^\/\w+}
135
137
  # }
136
138
 
139
+ # Asset Cache
140
+ #
141
+ # Cache asset URL's to prevent re-uploading of assets. Assets are cached based on asset_path,
142
+ # so fingerprinting or digests are recommended before turning on. The default cache store is
143
+ # a null store, which won't actuall store anything. An in-memory store is also provided, but
144
+ # this store won't share values across threads. Alternatively, use an external store which
145
+ # implements a `fetch(key, opts={}, &blk) API, such as the Rails.cache.
146
+ #
147
+ # Only applicable when `config.treat_urls_as_private == true`
148
+ # Only applicable when `config.upload_assets == true`
149
+ #
150
+ # config.asset_cache = BreezyPDF::Cache::Null.new
151
+ #
152
+ # or
153
+ #
154
+ # config.asset_cache = BreezyPDF::Cache::InMemory.new
155
+ #
156
+ # or
157
+ #
158
+ # config.asset_cache = Rails.cache
159
+
137
160
 
138
161
  # Extract Metadata
139
162
  #
@@ -154,6 +177,10 @@ BreezyPDF.setup do |config|
154
177
  # Only applicable when `config.upload_assets == true`
155
178
  #
156
179
  # config.threads = 1
180
+ #
181
+ # or
182
+ #
183
+ # config.theads = Concurrent.processor_count
157
184
 
158
185
 
159
186
  # Filter Elements
@@ -8,6 +8,7 @@ require "securerandom"
8
8
  require "zlib"
9
9
  require "stringio"
10
10
  require "open-uri"
11
+ require "monitor"
11
12
 
12
13
  require "nokogiri"
13
14
  require "concurrent"
@@ -23,6 +24,7 @@ module BreezyPDF
23
24
  autoload :Intercept, "breezy_pdf/_intercept"
24
25
  autoload :Resources, "breezy_pdf/_resources"
25
26
  autoload :HTML, "breezy_pdf/_html"
27
+ autoload :Cache, "breezy_pdf/_cache"
26
28
 
27
29
  autoload :VERSION, "breezy_pdf/version"
28
30
  autoload :RenderRequest, "breezy_pdf/render_request"
@@ -58,6 +60,9 @@ module BreezyPDF
58
60
  src: %r{^\/\w+}
59
61
  }
60
62
 
63
+ mattr_accessor :asset_cache
64
+ @@asset_cache = Cache::Null.new
65
+
61
66
  mattr_accessor :extract_metadata
62
67
  @@extract_metadata = true
63
68
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BreezyPDF
4
+ # :nodoc
5
+ module Cache
6
+ autoload :InMemory, "breezy_pdf/cache/in_memory"
7
+ autoload :Null, "breezy_pdf/cache/null"
8
+ end
9
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BreezyPDF::Cache
4
+ # In Memory cache store for assets
5
+ class InMemory
6
+ def initialize
7
+ @map = {}
8
+ @monitor = Monitor.new
9
+ end
10
+
11
+ def write(key, value, opts = {})
12
+ synchronize do
13
+ write_value(key, value, opts)
14
+ end
15
+ end
16
+
17
+ def read(key)
18
+ synchronize do
19
+ get_value(key)
20
+ end
21
+ end
22
+
23
+ def fetch(key, opts = {}, &blk)
24
+ synchronize do
25
+ fetch_value(key, opts, blk)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def synchronize(&block) # :nodoc:
32
+ @monitor.synchronize(&block)
33
+ end
34
+
35
+ def write_value(key, value, opts)
36
+ hash = { value: value, last_accessed: Time.now }
37
+ hash[:expires_at] = (Time.now + opts[:expires_in].to_f) if opts[:expires_in]
38
+
39
+ @map[key] = hash
40
+ remove_last_accessed!
41
+
42
+ true
43
+ end
44
+
45
+ def get_value(key)
46
+ key_value = read_key(key)
47
+
48
+ if key_value && key_value[:expires_at]
49
+ if key_value[:expires_at] <= Time.now
50
+ @map.delete(key) # The key has expired
51
+ BreezyPDF.logger.info("[BreezyPDF] Cache miss for #{key}")
52
+ nil
53
+ else
54
+ BreezyPDF.logger.info("[BreezyPDF] Cache hit for #{key}")
55
+ key_value[:value]
56
+ end
57
+ elsif key_value
58
+ BreezyPDF.logger.info("[BreezyPDF] Cache hit for #{key}")
59
+ key_value[:value]
60
+ else
61
+ BreezyPDF.logger.info("[BreezyPDF] Cache miss for #{key}")
62
+ nil
63
+ end
64
+ end
65
+
66
+ def read_key(key)
67
+ return unless @map[key]
68
+
69
+ @map[key][:last_accessed] = Time.now
70
+ @map[key]
71
+ end
72
+
73
+ def fetch_value(key, opts, blk)
74
+ stored_value = read(key)
75
+ return stored_value if stored_value
76
+
77
+ value = blk.call if blk
78
+ write(key, value, opts)
79
+
80
+ value
81
+ end
82
+
83
+ def remove_last_accessed!
84
+ return if @map.size <= 1000
85
+
86
+ sorted_map = @map.sort_by { |_k, v| v[:last_accessed] }
87
+ @map.delete(sorted_map.first.first)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BreezyPDF::Cache
4
+ # Null cache store for assets. Doesn't actually store anything.
5
+ class Null
6
+ def write(_key, _value, _opts = {})
7
+ true
8
+ end
9
+
10
+ def read(key); end
11
+
12
+ def fetch(_key, _opts = {})
13
+ yield if block_given?
14
+ end
15
+ end
16
+ end
@@ -47,11 +47,13 @@ module BreezyPDF::HTML
47
47
 
48
48
  def replace_asset_element_attr(asset_element, attr)
49
49
  thread_pool.post do
50
- asset = BreezyPDF::Resources::Asset.new(@base_url, asset_element[attr])
50
+ asset_element[attr] = BreezyPDF.asset_cache.fetch(asset_element[attr], expires_in: 601_200) do
51
+ asset = BreezyPDF::Resources::Asset.new(@base_url, asset_element[attr])
51
52
 
52
- asset_element[attr] = BreezyPDF::Uploads::Base.new(
53
- asset.filename, asset.content_type, asset.file_path
54
- ).public_url
53
+ BreezyPDF::Uploads::Base.new(
54
+ asset.filename, asset.content_type, asset.file_path
55
+ ).public_url
56
+ end
55
57
  end
56
58
  end
57
59
 
@@ -49,13 +49,18 @@ module BreezyPDF::Uploads
49
49
  end
50
50
 
51
51
  def resource
52
- BreezyPDF.logger.info(%([BreezyPDF] Initiating presign of private asset upload #{@filename}))
53
- @resource ||= client.post("/uploads", filename: @filename, size: file.size, content_type: @content_type)
52
+ @resource ||= client.post("/uploads", resource_options).tap do
53
+ BreezyPDF.logger.info(%([BreezyPDF] Initiating presign of private asset upload #{@filename}))
54
+ end
54
55
  rescue Net::HTTP => error
55
56
  BreezyPDF.logger.fatal(%([BreezyPDF] Unable to presign private asset upload for #{@filename}))
56
57
  raise PresignError, error.message
57
58
  end
58
59
 
60
+ def resource_options
61
+ @resource_options ||= { filename: @filename, size: file.size, content_type: @content_type }
62
+ end
63
+
59
64
  def upload_uri
60
65
  @upload_uri ||= URI.parse(resource.presigned_upload_url)
61
66
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BreezyPDF
4
- VERSION = "0.0.14"
4
+ VERSION = "0.0.15"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: breezy_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Westendorf
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-29 00:00:00.000000000 Z
11
+ date: 2018-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -142,10 +142,13 @@ files:
142
142
  - bin/setup
143
143
  - breezy_pdf.gemspec
144
144
  - lib/breezy_pdf.rb
145
+ - lib/breezy_pdf/_cache.rb
145
146
  - lib/breezy_pdf/_html.rb
146
147
  - lib/breezy_pdf/_intercept.rb
147
148
  - lib/breezy_pdf/_resources.rb
148
149
  - lib/breezy_pdf/_uploads.rb
150
+ - lib/breezy_pdf/cache/in_memory.rb
151
+ - lib/breezy_pdf/cache/null.rb
149
152
  - lib/breezy_pdf/client.rb
150
153
  - lib/breezy_pdf/gzip.rb
151
154
  - lib/breezy_pdf/html/publicize.rb