postdoc 0.2.4 → 0.3.5

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: 4fd07fd7a356f5e41dd00199937c8824010562d255d6539e59398e3fb55c0f79
4
- data.tar.gz: e89f06d78b8bd657ccfd52a2b079eea7035e1b77fda5380e6bc6f7a1f315e254
3
+ metadata.gz: 374246c4708c1c0492a3c8117f6a891723ae66b3c57476d6370b63f414876eb9
4
+ data.tar.gz: 30cac5f1aeee47ea6fc52e8985edafbd72ad2b81082aa3e7887f21e787b198ee
5
5
  SHA512:
6
- metadata.gz: '088597cc28cad883de3f539aa2e6e373285fa55b17cad6a17e619febce77d747c9174e0f2c6b1cca1d3583140b42f32e8b87c86bfdd3ae15361a9e36c6d3d945'
7
- data.tar.gz: 84d58a0ea2eeacbef730c0ac47d356125f934fe1e5cfe013cffcf87b5224e5af517b229e60f305f3dbb42e9d5ce753978ff615995a871de91cceebf2d056af4f
6
+ metadata.gz: 67093df126d95b92849611db7f08d1a6cbd065647398dfcdc8b31aaa68ab9f382b86de6edafb44cbca82a6ed95255e2817ce2bd842d3f9627380eed72d78f48a
7
+ data.tar.gz: 5b0ace904a20107d6d436c086bd20b183fe702c31b38e8bd4adab00c4f08bf34d28e07571129181fec6c28c98ea3f2cddf0312b841b75319692dd92db02831b4
data/lib/postdoc.rb CHANGED
@@ -1,62 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'chrome_remote'
3
+ require 'action_controller'
4
+ require 'postdoc/chrome_process'
5
+ require 'postdoc/client'
6
+ require 'postdoc/html_document'
4
7
 
5
8
  module Postdoc
6
9
  ActionController::Renderers.add :pdf do |_filename, options|
7
10
  Postdoc.render_from_string render_to_string(options), options
8
11
  end
9
12
 
10
- def self.render_from_string(string, options)
11
- htmlfile = Tempfile.new ['input', '.html']
12
-
13
- htmlfile.write string
14
- htmlfile.flush
15
-
16
- if options[:client].nil?
17
- # random port at 1025 or higher
18
- random_port = 1024 + Random.rand(65_535 - 1024)
19
- pid = Process.spawn "chrome --remote-debugging-port=#{random_port} --headless"
20
- end
21
-
22
- # FIXME
23
- sleep 1
24
-
25
- begin
26
- chrome = options[:client].nil? ? ChromeRemote.client(port: random_port) : options[:client]
27
-
28
- chrome.send_cmd 'Page.enable'
29
- chrome.send_cmd 'Page.navigate', url: "file://#{htmlfile.path}"
30
- chrome.wait_for 'Page.loadEventFired'
31
-
32
- if options[:header_template].present? || options[:footer_template].present?
33
- displayHeaderFooter = true
34
- else
35
- displayHeaderFooter = false
36
- end
37
-
38
- response = chrome.send_cmd 'Page.printToPDF', {
39
- landscape: options[:landscape] || false,
40
- printBackground: true,
41
- marginTop: options[:margin_top] || 1,
42
- marginBottom: options[:margin_bottom] || 1,
43
- displayHeaderFooter: displayHeaderFooter,
44
- headerTemplate: options[:header_template] || '',
45
- footerTemplate: options[:footer_template] || ''
46
- }
47
- result = Base64.decode64 response['data']
48
- ensure
49
- if options[:client].nil?
50
- Process.kill 'KILL', pid
51
- Process.wait pid
52
- else
53
- chrome.send_cmd 'Page.close'
54
- end
55
-
56
- htmlfile.close
57
- htmlfile.unlink
58
- end
59
-
60
- result
13
+ def self.render_from_string(content, **options)
14
+ server = ChromeProcess.new(**options)
15
+ html_file = HTMLDocument.new(content, **options)
16
+ server.client
17
+ .print_pdf_from_html(html_file.path, **options)
18
+ ensure
19
+ server.kill
20
+ html_file.cleanup
61
21
  end
62
22
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Postdoc
4
+ class ChromeProcess
5
+ attr_reader :pid, :port
6
+
7
+ def initialize(port: Random.rand(65_535 - 1024), **_options)
8
+ @port = port
9
+ @pid = Process.spawn "chrome --remote-debugging-port=#{port} --headless",
10
+ out: File::NULL, err: File::NULL
11
+ end
12
+
13
+ def alive?
14
+ @alive ||= test_socket!
15
+ rescue Errno::ECONNREFUSED
16
+ false
17
+ end
18
+
19
+ def kill
20
+ Process.kill 'KILL', pid
21
+ Process.wait pid
22
+ end
23
+
24
+ def client
25
+ Client.new port
26
+ end
27
+
28
+ private
29
+
30
+ def test_socket!
31
+ TCPSocket.new('localhost', port)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'chrome_remote'
4
+
5
+ module Postdoc
6
+ class Client
7
+ attr_accessor :client
8
+
9
+ def initialize(port)
10
+ @port = port
11
+ 100.times { setup_connection_or_wait && break }
12
+ raise 'ChromeClient couldn\'t launch' if @client.blank?
13
+ end
14
+
15
+ def print_pdf_from_html(file_path,
16
+ header_template: false,
17
+ footer_template: false,
18
+ **options)
19
+
20
+ client.send_cmd 'Page.enable'
21
+ client.send_cmd 'Page.navigate', url: "file://#{file_path}"
22
+ client.wait_for 'Page.loadEventFired'
23
+
24
+ response = client.send_cmd 'Page.printToPDF', {
25
+ landscape: options[:landscape] || false,
26
+ printBackground: true,
27
+ marginTop: options[:margin_top] || 1,
28
+ marginBottom: options[:margin_bottom] || 1,
29
+ marginLeft: options[:margin_left] || 1,
30
+ marginRight: options[:margin_right] || 1,
31
+ displayHeaderFooter: !!(header_template || footer_template),
32
+ headerTemplate: header_template || '',
33
+ footerTemplate: footer_template || ''
34
+ }
35
+
36
+ Base64.decode64 response['data']
37
+ end
38
+
39
+ private
40
+
41
+ def setup_connection_or_wait
42
+ @client = ChromeRemote.client(port: @port)
43
+ true
44
+ rescue Errno::EHOSTUNREACH, Errno::ECONNREFUSED
45
+ sleep(0.1)
46
+ false
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ module Postdoc
6
+ class HTMLDocument
7
+ attr_accessor :file
8
+
9
+ delegate :path, to: :file
10
+
11
+ def initialize(content, path: nil, **_options)
12
+ path ||= Rails.root&.join('tmp') || '/tmp'
13
+ @file = Tempfile.new ['input', '.html'], path
14
+
15
+ file.write content
16
+ file.flush
17
+ end
18
+
19
+ def cleanup
20
+ file.close
21
+ file.unlink
22
+ end
23
+ end
24
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postdoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Groeneveld
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-21 00:00:00.000000000 Z
11
+ date: 2021-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chrome_remote
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rails
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -31,19 +45,19 @@ dependencies:
31
45
  - !ruby/object:Gem::Version
32
46
  version: '6.1'
33
47
  - !ruby/object:Gem::Dependency
34
- name: chrome_remote
48
+ name: mocha
35
49
  requirement: !ruby/object:Gem::Requirement
36
50
  requirements:
37
51
  - - ">="
38
52
  - !ruby/object:Gem::Version
39
- version: 0.2.0
40
- type: :runtime
53
+ version: '0'
54
+ type: :development
41
55
  prerelease: false
42
56
  version_requirements: !ruby/object:Gem::Requirement
43
57
  requirements:
44
58
  - - ">="
45
59
  - !ruby/object:Gem::Version
46
- version: 0.2.0
60
+ version: '0'
47
61
  description: Description of Postdoc.
48
62
  email:
49
63
  - frank@ivaldi.nl
@@ -54,6 +68,9 @@ files:
54
68
  - LICENSE
55
69
  - Rakefile
56
70
  - lib/postdoc.rb
71
+ - lib/postdoc/chrome_process.rb
72
+ - lib/postdoc/client.rb
73
+ - lib/postdoc/html_document.rb
57
74
  homepage: https://github.com/ivaldi/postdoc
58
75
  licenses:
59
76
  - BSD-2-Clause