breezy_pdf 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +18 -0
- data/.travis.yml +6 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +51 -0
- data/LICENSE.txt +5 -0
- data/README.md +254 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/breezy_pdf.gemspec +36 -0
- data/lib/breezy_pdf/client.rb +39 -0
- data/lib/breezy_pdf/gzip.rb +27 -0
- data/lib/breezy_pdf/html/publicize.rb +62 -0
- data/lib/breezy_pdf/html/strip.rb +29 -0
- data/lib/breezy_pdf/html.rb +8 -0
- data/lib/breezy_pdf/intercept/base.rb +13 -0
- data/lib/breezy_pdf/intercept/private_url.rb +69 -0
- data/lib/breezy_pdf/intercept/public_url.rb +34 -0
- data/lib/breezy_pdf/intercept.rb +10 -0
- data/lib/breezy_pdf/interceptor.rb +48 -0
- data/lib/breezy_pdf/middleware.rb +14 -0
- data/lib/breezy_pdf/private_assets/asset.rb +47 -0
- data/lib/breezy_pdf/private_assets/html.rb +66 -0
- data/lib/breezy_pdf/private_assets.rb +9 -0
- data/lib/breezy_pdf/render_request.rb +21 -0
- data/lib/breezy_pdf/response.rb +44 -0
- data/lib/breezy_pdf/uploads/base.rb +76 -0
- data/lib/breezy_pdf/uploads/file_form_data.rb +60 -0
- data/lib/breezy_pdf/uploads.rb +13 -0
- data/lib/breezy_pdf/util.rb +49 -0
- data/lib/breezy_pdf/version.rb +5 -0
- data/lib/breezy_pdf.rb +78 -0
- data/test.html +8 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 51ab1fda7ecf5c352d77df5fc07e2ba2e9b4116c
|
4
|
+
data.tar.gz: 1e80909046b6fe970e499abc0ac0ed0cbad88e1a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2861c609191489fb38d112d8f495e37b38ccd0fbc803c2afc1b84a43a60fb0568686535e7e17f6542cb3b75694754b33f639e6801981672dcb88c3aab589fd66
|
7
|
+
data.tar.gz: 287fcee5ebd2fdf7ac0f6a87e1717abda8586deeaa24b3082778d0fb6fca8ccf4b803cbd9b200d994431226e392eb330f20399a3259ebd6b3e36303e425b68b4
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
Style/StringLiterals:
|
4
|
+
EnforcedStyle: double_quotes
|
5
|
+
Metrics/LineLength:
|
6
|
+
Max: 110
|
7
|
+
Metrics/MethodLength:
|
8
|
+
Max: 20
|
9
|
+
Style/ClassAndModuleChildren:
|
10
|
+
Enabled: false
|
11
|
+
Style/ClassVars:
|
12
|
+
Enabled: false
|
13
|
+
Metrics/CyclomaticComplexity:
|
14
|
+
Enabled: false
|
15
|
+
Metrics/PerceivedComplexity:
|
16
|
+
Enabled: false
|
17
|
+
Metrics/AbcSize:
|
18
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
breezy_pdf (0.0.1)
|
5
|
+
concurrent-ruby
|
6
|
+
nokogiri
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
ast (2.4.0)
|
12
|
+
concurrent-ruby (1.0.5)
|
13
|
+
mini_portile2 (2.3.0)
|
14
|
+
minitest (5.11.3)
|
15
|
+
minitest-stub-const (0.6)
|
16
|
+
nokogiri (1.8.2)
|
17
|
+
mini_portile2 (~> 2.3.0)
|
18
|
+
parallel (1.12.1)
|
19
|
+
parser (2.5.0.5)
|
20
|
+
ast (~> 2.4.0)
|
21
|
+
powerpack (0.1.1)
|
22
|
+
rack (2.0.4)
|
23
|
+
rack-test (0.8.3)
|
24
|
+
rack (>= 1.0, < 3)
|
25
|
+
rainbow (2.2.2)
|
26
|
+
rake
|
27
|
+
rake (10.5.0)
|
28
|
+
rubocop (0.49.0)
|
29
|
+
parallel (~> 1.10)
|
30
|
+
parser (>= 2.3.3.1, < 3.0)
|
31
|
+
powerpack (~> 0.1)
|
32
|
+
rainbow (>= 1.99.1, < 3.0)
|
33
|
+
ruby-progressbar (~> 1.7)
|
34
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
35
|
+
ruby-progressbar (1.9.0)
|
36
|
+
unicode-display_width (1.3.0)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
breezy_pdf!
|
43
|
+
bundler (~> 1.16)
|
44
|
+
minitest (~> 5.0)
|
45
|
+
minitest-stub-const
|
46
|
+
rack-test
|
47
|
+
rake (~> 10.0)
|
48
|
+
rubocop (= 0.49)
|
49
|
+
|
50
|
+
BUNDLED WITH
|
51
|
+
1.16.0
|
data/LICENSE.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,254 @@
|
|
1
|
+
# BreezyPDF
|
2
|
+
|
3
|
+
Make PDF generation a breezy-easy.
|
4
|
+
|
5
|
+
No binaries to install. No reinventing the wheel to match HTML layouts. Just simple HTML to PDF generation as a Rack Middleware with support for modern CSS and JavaScript. `.pdf` any of your app's URL's for fast, out-of-process, PDF generation of that URL. Support for public and authenticated views, local development and production.
|
6
|
+
|
7
|
+
[Sign Up](https://BreezyPDF.com/) for an account to get started.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'breezy_pdf'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install breezy_pdf
|
24
|
+
|
25
|
+
## Usage - Ruby on Rails
|
26
|
+
|
27
|
+
To add the middleware:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# config/application.rb
|
31
|
+
|
32
|
+
BreezyPDF.secret_api_key = "YOUR_SECRET_API_KEY" # Remove if specified elsewhere
|
33
|
+
config.middleware.use BreezyPDF::Middleware
|
34
|
+
```
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# view.html.erb
|
38
|
+
<%= link_to "Download as PDF", my_resource_path(format: :pdf) %>
|
39
|
+
```
|
40
|
+
|
41
|
+
Proceed to configuration.
|
42
|
+
|
43
|
+
## Usage - Sinatra/Hamani/Rack
|
44
|
+
|
45
|
+
To add the middleware:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# app.rb
|
49
|
+
|
50
|
+
BreezyPDF.secret_api_key = "YOUR_SECRET_API_KEY" # Remove if specified elsewhere
|
51
|
+
use BreezyPDF::Middleware
|
52
|
+
```
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
# view.html
|
56
|
+
<a href="/this/url.pdf">Download as PDF</a>
|
57
|
+
```
|
58
|
+
|
59
|
+
Proceed to configuration.
|
60
|
+
|
61
|
+
## Configuration
|
62
|
+
|
63
|
+
BreezyPDF supports extensive configuration for how want PDF's to render:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
# config/initializers/breezy_pdf.rb
|
67
|
+
|
68
|
+
BreezyPDF.setup do |config|
|
69
|
+
# Secret API Key
|
70
|
+
#
|
71
|
+
# Obtain an API key from https://breezypdf.com
|
72
|
+
# Store your API key in a secure location with the rest of your app secrets
|
73
|
+
config.secret_api_key = "YOUR_SECRET_API_KEY"
|
74
|
+
|
75
|
+
|
76
|
+
# Middleware Path Matchers
|
77
|
+
#
|
78
|
+
# An array for Regular Expressions which identify which URL's should be
|
79
|
+
# intercepted by the Middleware. Defaults to [/\.pdf$/], which will match
|
80
|
+
# all requests ending with a .pdf extension.
|
81
|
+
# config.middleware_path_matchers = [/\.pdf$/]
|
82
|
+
|
83
|
+
|
84
|
+
# Treat URL's as Private
|
85
|
+
#
|
86
|
+
# This indicates if the URL requested is protected or unaccessible for the
|
87
|
+
# public Internet. Examples of this would be when hosted on localhost (development)
|
88
|
+
# URL's which are protected by authentication, or URL's that depend on session/cookie
|
89
|
+
# data to display correctly. Default is true.
|
90
|
+
#
|
91
|
+
# config.treat_urls_as_private = true
|
92
|
+
|
93
|
+
|
94
|
+
# Upload Assets
|
95
|
+
#
|
96
|
+
# Express your desire to upload assets within the requested HTML which are not
|
97
|
+
# publicly accessible with a FQDN. This might include images, CSS, and
|
98
|
+
# JavaScript when running in development mode, or assets which are referenced
|
99
|
+
# with relative URL's. If you're able to turn this off, performance will be increased
|
100
|
+
# Default is true.
|
101
|
+
#
|
102
|
+
# Only applicable when `config.treat_urls_as_private == true`
|
103
|
+
#
|
104
|
+
# config.upload_assets = true
|
105
|
+
#
|
106
|
+
# or, if your assets are only publicly available on production
|
107
|
+
# config.upload_assets = Rails.env.development?
|
108
|
+
|
109
|
+
|
110
|
+
# Asset Selectors
|
111
|
+
#
|
112
|
+
# Configure what types of assets should be evaluated to be uploaded. Expects an
|
113
|
+
# array of string CSS selectors. Default is `[img script link[rel="stylesheet"]]`.
|
114
|
+
#
|
115
|
+
# Only applicable when `config.treat_urls_as_private == true`
|
116
|
+
# Only applicable when `config.upload_assets == true`
|
117
|
+
#
|
118
|
+
# config.asset_selectors = %w(img script link[rel="stylesheet"])
|
119
|
+
|
120
|
+
|
121
|
+
# Asset path matchers
|
122
|
+
#
|
123
|
+
# Determine which attribute path's to replace with an uploaded version of the asset.
|
124
|
+
# Expects a hash of attr: Regexp values. Default is `{ href: /^\/\w+/, src: /^\/\w+/}`
|
125
|
+
# which matches all relative paths.
|
126
|
+
#
|
127
|
+
# Only applicable when `config.treat_urls_as_private == true`
|
128
|
+
# Only applicable when `config.upload_assets == true`
|
129
|
+
#
|
130
|
+
# config.asset_path_matchers = {
|
131
|
+
# href: %r{^\/\w+},
|
132
|
+
# src: %r{^\/\w+}
|
133
|
+
# }
|
134
|
+
|
135
|
+
|
136
|
+
# Extract Metadata
|
137
|
+
#
|
138
|
+
# BreezyPDF supports specifying how a page should be rendered through meta tags within
|
139
|
+
# the HTML to be rendered. Contact support@breezypdf.com for more details. Default is
|
140
|
+
# true.
|
141
|
+
#
|
142
|
+
# Only applicable when `treat_urls_as_private == true`
|
143
|
+
# config.extract_metadata = true
|
144
|
+
|
145
|
+
|
146
|
+
# Threads
|
147
|
+
#
|
148
|
+
# Specify the maximum number of Threads to use when uploading assets. This speeds up the
|
149
|
+
# uploading of assets by doing them concurrently. Default is 1.
|
150
|
+
#
|
151
|
+
# Only applicable when `config.treat_urls_as_private == true`
|
152
|
+
# Only applicable when `config.upload_assets == true`
|
153
|
+
#
|
154
|
+
# config.threads = 1
|
155
|
+
|
156
|
+
|
157
|
+
# Filter Elements
|
158
|
+
#
|
159
|
+
# Remove certain elements from the HTML which shouldn't be included in the PDF, such as
|
160
|
+
# a navigation or footer elements. Default is false.
|
161
|
+
#
|
162
|
+
# Only applicable when `config.treat_urls_as_private == true`
|
163
|
+
#
|
164
|
+
# config.fitler_elements = false
|
165
|
+
|
166
|
+
|
167
|
+
# Filter Elements Selectors
|
168
|
+
#
|
169
|
+
# CSS selectors to configure which element you'd like to remove. Expects an array of of
|
170
|
+
# CSS selectors. Default is `[.breezy-pdf-remove]`.
|
171
|
+
#
|
172
|
+
# Only applicable when `config.treat_urls_as_private == true`
|
173
|
+
#
|
174
|
+
# config.filtered_element_selectors = %w[.breezy-pdf-remove]
|
175
|
+
|
176
|
+
# Logger
|
177
|
+
#
|
178
|
+
# Configure the logger, if you're into that sort of thing.
|
179
|
+
#
|
180
|
+
# config.logger = Logger.new(STDOUT).tap { |logger| logger.level = Logger::FATAL }
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
184
|
+
## Where's my loading animation?
|
185
|
+
|
186
|
+
By default, the requested PDF will eventually returned by the request after a series of redirects. The PDF will be sent with a Content-Disposition of `attachment`, so the browser will attempt to download it instead of showing it inline. All the while, and after the PDF has been downloaded, the current page's HTML will continue to be displayed.
|
187
|
+
|
188
|
+
If you want to show a loading animation on the current page, you can simply load the PDF with an AJAX request, eventually redirecting to the final URL.
|
189
|
+
|
190
|
+
Here is a contrived example:
|
191
|
+
|
192
|
+
```html
|
193
|
+
<a href="/this/path.pdf" class="breezy-pdf-download">Download as PDF</a>
|
194
|
+
|
195
|
+
<script type="text/javascript">
|
196
|
+
var downloadLinkEls = document.querySelectorAll('.breezy-pdf-download');
|
197
|
+
var loadingEl = document.createElement('div');
|
198
|
+
loadingEl.innerHTML = "<h1>Loading!</h1><p>Loading icon here, maybe?</p><p id='breezy-progress'></p>";
|
199
|
+
loadingEl.style = "position: absolute; width: 100%; height: 100%; text-align: center; background: #fff; top: 0; left: 0; z-index: 10000; display: none;"
|
200
|
+
|
201
|
+
document.body.appendChild(loadingEl);
|
202
|
+
var progressEl = document.getElementById('breezy-progress');
|
203
|
+
|
204
|
+
for (var i = downloadLinkEls.length - 1; i >= 0; i--) {
|
205
|
+
var linkEl = downloadLinkEls[i];
|
206
|
+
var pdfUrl = linkEl.getAttribute('href');
|
207
|
+
|
208
|
+
// Listen for a click on the link, then start handling the change of state
|
209
|
+
linkEl.addEventListener('click', function(ev) {
|
210
|
+
loadingEl.style.display = "block"; // Display ad-hoc loading element
|
211
|
+
ev.preventDefault();
|
212
|
+
|
213
|
+
var i = 1;
|
214
|
+
var interval = setInterval(function() {
|
215
|
+
progressEl.innerText = i / 10.0 + ' waiting seconds so far...';
|
216
|
+
i++;
|
217
|
+
}, 100);
|
218
|
+
|
219
|
+
var ajaxRequest = new XMLHttpRequest();
|
220
|
+
|
221
|
+
ajaxRequest.addEventListener('load', function(ev) {
|
222
|
+
clearInterval(interval);
|
223
|
+
console.log("Done waiting. We'd close modals or remove loading animations here before setting the location.")
|
224
|
+
loadingEl.style.display = "none";
|
225
|
+
|
226
|
+
// Redirect the eventual URL of the PDF
|
227
|
+
// If the browser downloads the file, the current page's HTML will still be shown
|
228
|
+
window.location = ev.currentTarget.responseURL;
|
229
|
+
})
|
230
|
+
|
231
|
+
ajaxRequest.open('GET', pdfUrl);
|
232
|
+
ajaxRequest.send();
|
233
|
+
})
|
234
|
+
}
|
235
|
+
</script>
|
236
|
+
```
|
237
|
+
|
238
|
+
## Development
|
239
|
+
|
240
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
241
|
+
|
242
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
243
|
+
|
244
|
+
## Contributing
|
245
|
+
|
246
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/danielwestendorf/breezy_pdf.
|
247
|
+
|
248
|
+
## License
|
249
|
+
|
250
|
+
Copyright (c) Daniel Westendorf
|
251
|
+
|
252
|
+
BreezyPDF is an Open Source project licensed under the terms of
|
253
|
+
the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html>
|
254
|
+
for license text.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "breezy_pdf"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/breezy_pdf.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path("../lib", __FILE__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require "breezy_pdf/version"
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = "breezy_pdf"
|
10
|
+
spec.version = BreezyPDF::VERSION
|
11
|
+
spec.authors = ["Daniel Westendorf"]
|
12
|
+
spec.email = ["daniel@prowestech.com"]
|
13
|
+
|
14
|
+
spec.summary = "Ruby client for BreezyPDF.com"
|
15
|
+
spec.description = "Client and Rack Middlware which submits URL's and HTML fragments to " \
|
16
|
+
"be rendered as a PDF"
|
17
|
+
spec.homepage = "https://www.breezypdf.com"
|
18
|
+
spec.license = "LGPL-3.0"
|
19
|
+
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
21
|
+
f.match(%r{^(test|spec|features)/})
|
22
|
+
end
|
23
|
+
spec.bindir = "exe"
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_dependency "nokogiri"
|
28
|
+
spec.add_dependency "concurrent-ruby"
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
31
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
32
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
33
|
+
spec.add_development_dependency "minitest-stub-const"
|
34
|
+
spec.add_development_dependency "rack-test"
|
35
|
+
spec.add_development_dependency "rubocop", "0.49"
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BreezyPDF
|
4
|
+
# HTTP Client for BreezyPDF API
|
5
|
+
class Client
|
6
|
+
def post(path, body)
|
7
|
+
uri = URI.parse(BreezyPDF.base_url + path)
|
8
|
+
http = Net::HTTP.new(uri.host, uri.port).tap { |h| h.use_ssl = true }
|
9
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
10
|
+
|
11
|
+
request.body = body.to_json
|
12
|
+
|
13
|
+
Response.new http.request(request)
|
14
|
+
end
|
15
|
+
|
16
|
+
def put(path, body)
|
17
|
+
uri = URI.parse(BreezyPDF.base_url + path)
|
18
|
+
http = Net::HTTP.new(uri.host, uri.port).tap { |h| h.use_ssl = true }
|
19
|
+
request = Net::HTTP::Put.new(uri.request_uri, headers)
|
20
|
+
|
21
|
+
request.body = body.to_json
|
22
|
+
|
23
|
+
Response.new http.request(request)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def headers
|
29
|
+
{
|
30
|
+
"Content-Type": "application/json",
|
31
|
+
"Authorization": "Bearer #{BreezyPDF.secret_api_key}"
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def success?(code)
|
36
|
+
code >= 200 && code < 300
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BreezyPDF
|
4
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/gzip.rb
|
5
|
+
module Gzip
|
6
|
+
# :nodoc
|
7
|
+
class Stream < StringIO
|
8
|
+
def initialize(*)
|
9
|
+
super
|
10
|
+
set_encoding "BINARY"
|
11
|
+
end
|
12
|
+
|
13
|
+
def close
|
14
|
+
rewind
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Compresses a string using gzip.
|
19
|
+
def self.compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY)
|
20
|
+
output = Stream.new
|
21
|
+
gz = Zlib::GzipWriter.new(output, level, strategy)
|
22
|
+
gz.write(source)
|
23
|
+
gz.close
|
24
|
+
output.string
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BreezyPDF::HTML
|
4
|
+
# Replace assets with uploaded URL's
|
5
|
+
class Publicize
|
6
|
+
def initialize(base_url, html_fragment)
|
7
|
+
@base_url = base_url
|
8
|
+
@html_fragment = html_fragment
|
9
|
+
@log_queue = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def public_fragment
|
13
|
+
@public_fragment ||= parsed_document.tap do
|
14
|
+
publicize!
|
15
|
+
end.to_html
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def publicize!
|
21
|
+
BreezyPDF.asset_selectors.each do |selector|
|
22
|
+
parsed_document.css(selector).each do |asset_element|
|
23
|
+
replace_asset_elements_matched_paths(asset_element)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@log_queue.each { |msg| BreezyPDF.logger.info(msg) }
|
28
|
+
|
29
|
+
thread_pool.shutdown
|
30
|
+
thread_pool.wait_for_termination
|
31
|
+
end
|
32
|
+
|
33
|
+
def parsed_document
|
34
|
+
@parsed_document ||= Nokogiri::HTML(@html_fragment)
|
35
|
+
end
|
36
|
+
|
37
|
+
def replace_asset_elements_matched_paths(asset_element)
|
38
|
+
BreezyPDF.asset_path_matchers.each do |attr, matcher|
|
39
|
+
attr_value = asset_element[attr.to_s]
|
40
|
+
|
41
|
+
next unless attr_value && attr_value.match?(matcher)
|
42
|
+
|
43
|
+
@log_queue << %([BreezyPDF] Replacing element #{asset_element.name}[#{attr}="#{asset_element[attr]}"])
|
44
|
+
replace_asset_element_attr(asset_element, attr.to_s)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def replace_asset_element_attr(asset_element, attr)
|
49
|
+
thread_pool.post do
|
50
|
+
asset = BreezyPDF::PrivateAssets::Asset.new(@base_url, asset_element[attr])
|
51
|
+
|
52
|
+
asset_element[attr] = BreezyPDF::Uploads::Base.new(
|
53
|
+
asset.filename, asset.content_type, asset.file_path
|
54
|
+
).public_url
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def thread_pool
|
59
|
+
@thread_pool ||= Concurrent::FixedThreadPool.new(BreezyPDF.threads.to_i)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BreezyPDF::HTML
|
4
|
+
# Replace assets with uploaded URL's
|
5
|
+
class Strip
|
6
|
+
def initialize(html_fragment)
|
7
|
+
@html_fragment = html_fragment
|
8
|
+
end
|
9
|
+
|
10
|
+
def stripped_fragment
|
11
|
+
@stripped_fragment ||= parsed_document.tap do
|
12
|
+
strip!
|
13
|
+
end.to_html
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def strip!
|
19
|
+
BreezyPDF.filter_elements_selectors.each do |selector|
|
20
|
+
BreezyPDF.logger.info("[BreezyPDF] Stripping out elements matching selector `#{selector}`")
|
21
|
+
parsed_document.css(selector).each(&:remove)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def parsed_document
|
26
|
+
@parsed_document ||= Nokogiri::HTML(@html_fragment)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|