grover 0.2.2 → 0.3.0

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: 26c7ccbc8a629084f409b83b07f3aa3f59018b93
4
- data.tar.gz: 7b2bbb83563b7b142f99115a36cb061eeea54e29
3
+ metadata.gz: 0f700a9f110114c8de7c64f68ada3c60b183e002
4
+ data.tar.gz: 10038b11d2dc0e3a7deb9c8be59c17ce9fe75f5a
5
5
  SHA512:
6
- metadata.gz: 7274a0c0591d9b8bd03fdf583686a6fc52bca590dc76989ad732462e0424b2516ed9575bf136615b7ca6959625f9ea06ada6898435a8f90ff717044ce2f140dc
7
- data.tar.gz: 75213b2235ff0ede9fc0a17421fc28badbf546615806055d2a650eac3616c3af68f644d21a63e51f51a620a18d2953fe9605d9de03344a4318ccb9f860f2b99c
6
+ metadata.gz: '08d9ea6100709712c0ac3a3adaf6c00c80ae45fca0fe38176d808e4f4c89efe8b900128d750056ca9b4a7db73dae1f099cec4d5f97851501459728480d181ab4'
7
+ data.tar.gz: df95c29b666dd3eb53bbb5c23acfd328f3750cdd2931dd08a9432805ec4089a9f13f17303b7f3a1cffe7655179f1ea97fb16d270f51287736692dc38fc085227
@@ -0,0 +1,12 @@
1
+ class Grover
2
+ #
3
+ # Configuration of the options for Grover HTML to PDF conversion
4
+ #
5
+ class Configuration
6
+ attr_accessor :options
7
+
8
+ def initialize
9
+ @options = {}
10
+ end
11
+ end
12
+ end
@@ -29,12 +29,14 @@ class Grover
29
29
 
30
30
  private
31
31
 
32
+ PDF_REGEX = /\.pdf$/i
33
+
32
34
  def rendering_pdf?
33
35
  @render_pdf
34
36
  end
35
37
 
36
38
  def render_as_pdf?
37
- @request.path.end_with?('.pdf')
39
+ !@request.path.match(PDF_REGEX).nil?
38
40
  end
39
41
 
40
42
  def html_content?(headers)
@@ -61,7 +63,7 @@ class Grover
61
63
  def configure_env_for_pdf_request(env)
62
64
  @render_pdf = true
63
65
 
64
- path = @request.path.sub(/\.pdf$/, '')
66
+ path = @request.path.sub(PDF_REGEX, '')
65
67
  path = path.sub(@request.script_name, '')
66
68
 
67
69
  %w[PATH_INFO REQUEST_URI].each { |e| env[e] = path }
data/lib/grover/utils.rb CHANGED
@@ -3,11 +3,46 @@ class Grover
3
3
  # Utility class for Grover helper methods
4
4
  #
5
5
  class Utils
6
+ ACRONYMS = {
7
+ 'css' => 'CSS'
8
+ }.freeze
9
+ private_constant :ACRONYMS
10
+
11
+ #
12
+ # Removes leading/trailing whitespaces and squishes inner whitespace with a single space
13
+ #
14
+ # N.B. whitespace includes all 'blank' characters as well as newlines/carriage returns etc.
15
+ #
6
16
  def self.squish(string)
7
17
  string.
8
18
  gsub(/\A[[:space:]]+/, '').
9
19
  gsub(/[[:space:]]+\z/, '').
10
20
  gsub(/[[:space:]]+/, ' ')
11
21
  end
22
+
23
+ #
24
+ # Recursively normalizes hash objects with camelized string keys
25
+ #
26
+ def self.normalize_object(object)
27
+ if object.is_a? Hash
28
+ object.each_with_object({}) do |(k, v), acc|
29
+ acc[normalize_key(k)] = normalize_object(v)
30
+ end
31
+ else
32
+ object
33
+ end
34
+ end
35
+
36
+ #
37
+ # Normalizes hash keys into camelized strings, including up-casing known acronyms
38
+ #
39
+ # Regex sourced from ActiveSupport camelize
40
+ #
41
+ def self.normalize_key(key)
42
+ key.to_s.downcase.gsub(%r{(?:_|(/))([a-z\d]*)}) do
43
+ "#{Regexp.last_match(1)}#{ACRONYMS[Regexp.last_match(2)] || Regexp.last_match(2).capitalize}"
44
+ end
45
+ end
46
+ private_class_method :normalize_key
12
47
  end
13
48
  end
@@ -1,3 +1,3 @@
1
1
  class Grover
2
- VERSION = '0.2.2'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/grover.rb CHANGED
@@ -1,14 +1,48 @@
1
1
  require 'grover/version'
2
2
 
3
3
  require 'grover/utils'
4
- require 'grover/processor'
5
4
  require 'grover/html_preprocessor'
6
5
  require 'grover/middleware'
6
+ require 'grover/configuration'
7
+
8
+ require 'schmooze'
7
9
 
8
10
  #
9
11
  # Grover interface for converting HTML to PDF
10
12
  #
11
13
  class Grover
14
+ #
15
+ # Processor helper class for calling out to Puppeteer NodeJS library
16
+ #
17
+ class Processor < Schmooze::Base
18
+ dependencies puppeteer: 'puppeteer'
19
+
20
+ def self.launch_params
21
+ ENV['CI'] == 'true' ? "{args: ['--no-sandbox', '--disable-setuid-sandbox']}" : ''
22
+ end
23
+
24
+ method :convert_pdf, Utils.squish(<<-FUNCTION)
25
+ async (url, options) => {
26
+ let browser;
27
+ try {
28
+ browser = await puppeteer.launch(#{launch_params});
29
+ const page = await browser.newPage();
30
+ if (url.match(/^http/i)) {
31
+ await page.goto(url, { waitUntil: 'networkidle2' });
32
+ } else {
33
+ await page.goto(`data:text/html,${url}`, { waitUntil: 'networkidle0' });
34
+ }
35
+ return await page.pdf(options);
36
+ } finally {
37
+ if (browser) {
38
+ await browser.close();
39
+ }
40
+ }
41
+ }
42
+ FUNCTION
43
+ end
44
+ private_constant :Processor
45
+
12
46
  #
13
47
  # @param [String] url URL of the page to convert
14
48
  # @param [Hash] options Optional parameters to pass to PDF processor
@@ -16,32 +50,44 @@ class Grover
16
50
  #
17
51
  def initialize(url, options = {})
18
52
  @url = url
19
- @root_path = options.delete :root_path
20
- @options = options
53
+ @options = Grover.configuration.options.merge options
54
+ @root_path = @options.delete :root_path
21
55
  end
22
56
 
23
57
  #
24
58
  # Request URL with provided options and create PDF
25
59
  #
26
60
  # @param [String] path Optional path to write the PDF to
27
- # @return [Array<Integer>] Byte array of the resulting PDF
61
+ # @return [String] The resulting PDF data
28
62
  #
29
63
  def to_pdf(path = nil)
30
- options = @options.dup
31
- options[:path] = path if path
32
- result = processor.convert_pdf @url, options
64
+ result = processor.convert_pdf @url, normalized_options(path)
33
65
  result['data'].pack('c*')
34
66
  end
35
67
 
68
+ #
69
+ # Instance inspection
70
+ #
36
71
  def inspect
37
72
  format(
38
73
  '#<%<class_name>s:0x%<object_id>p @url="%<url>s">',
39
74
  class_name: self.class.name,
40
75
  object_id: object_id,
41
- url: url
76
+ url: @url
42
77
  )
43
78
  end
44
79
 
80
+ #
81
+ # Configuration for the conversion
82
+ #
83
+ def self.configuration
84
+ @configuration ||= Configuration.new
85
+ end
86
+
87
+ def self.configure
88
+ yield(configuration)
89
+ end
90
+
45
91
  private
46
92
 
47
93
  def root_path
@@ -49,6 +95,12 @@ class Grover
49
95
  end
50
96
 
51
97
  def processor
52
- Grover::Processor.new(root_path)
98
+ Processor.new(root_path)
99
+ end
100
+
101
+ def normalized_options(path)
102
+ options = Utils.normalize_object @options
103
+ options['path'] = path if path
104
+ options
53
105
  end
54
106
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Bromwich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-23 00:00:00.000000000 Z
11
+ date: 2018-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: schmooze
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rake
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +108,20 @@ dependencies:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
110
  version: '0.53'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.28'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.28'
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: simplecov
85
127
  requirement: !ruby/object:Gem::Requirement
@@ -102,9 +144,9 @@ extensions: []
102
144
  extra_rdoc_files: []
103
145
  files:
104
146
  - lib/grover.rb
147
+ - lib/grover/configuration.rb
105
148
  - lib/grover/html_preprocessor.rb
106
149
  - lib/grover/middleware.rb
107
- - lib/grover/processor.rb
108
150
  - lib/grover/utils.rb
109
151
  - lib/grover/version.rb
110
152
  homepage: http://github.com/Studiosity/grover
@@ -1,35 +0,0 @@
1
- require 'schmooze'
2
-
3
- class Grover
4
- #
5
- # Processor helper class for calling out to Puppeteer NodeJS library
6
- #
7
- class Processor < Schmooze::Base
8
- dependencies puppeteer: 'puppeteer'
9
-
10
- def self.launch_params
11
- ENV['CI'] == 'true' ? "{args: ['--no-sandbox', '--disable-setuid-sandbox']}" : ''
12
- end
13
- private_class_method :launch_params
14
-
15
- method :convert_pdf, Utils.squish(<<-FUNCTION)
16
- async (url, options) => {
17
- let browser;
18
- try {
19
- browser = await puppeteer.launch(#{launch_params});
20
- const page = await browser.newPage();
21
- if (url.match(/^http/i)) {
22
- await page.goto(url, { waitUntil: 'networkidle2' });
23
- } else {
24
- await page.goto(`data:text/html,${url}`, { waitUntil: 'networkidle0' });
25
- }
26
- return await page.pdf(options);
27
- } finally {
28
- if (browser) {
29
- await browser.close();
30
- }
31
- }
32
- }
33
- FUNCTION
34
- end
35
- end