grover 0.2.2 → 0.3.0

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
  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