Skip to content

Commit 1f143a5

Browse files
committed
Merge branch 'receipt-bank-stream-pdf-to-file'
2 parents d4c744c + 761f217 commit 1f143a5

File tree

4 files changed

+59
-26
lines changed

4 files changed

+59
-26
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ browser.screenshot(path: "google.jpg") # => 30902
346346
browser.screenshot(full: true, quality: 60) # "iVBORw0KGgoAAAANSUhEUgAABAAAAAMACAYAAAC6uhUNAAAAAXNSR0IArs4c6Q...
347347
```
348348

349-
#### pdf(\*\*options) : `String` | `Integer`
349+
#### pdf(\*\*options) : `String` | `Boolean`
350350

351351
Saves PDF on a disk or returns it as base64.
352352

@@ -366,7 +366,7 @@ Saves PDF on a disk or returns it as base64.
366366
```ruby
367367
browser.go_to("https://google.com/")
368368
# Save to disk as a PDF
369-
browser.pdf(path: "google.pdf", paper_width: 1.0, paper_height: 1.0) # => 14983
369+
browser.pdf(path: "google.pdf", paper_width: 1.0, paper_height: 1.0) # => true
370370
```
371371

372372
#### mhtml(\*\*options) : `String` | `Integer`

lib/ferrum.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ class NoSuchTargetError < Error; end
1010
class NotImplementedError < Error; end
1111

1212
class StatusError < Error
13+
attr_reader :pendings
14+
1315
def initialize(url, pendings = [])
16+
@pendings = pendings
1417
message = if pendings.empty?
1518
"Request to #{url} failed to reach server, check DNS and/or server status"
1619
else

lib/ferrum/page/screenshot.rb

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ module Screenshot
2424
A6: { width: 4.13, height: 5.83 },
2525
}.freeze
2626

27+
STREAM_CHUNK = 128 * 1024
28+
2729
def screenshot(**opts)
2830
path, encoding = common_options(**opts)
2931
options = screenshot_options(path, **opts)
@@ -34,14 +36,16 @@ def screenshot(**opts)
3436
save_file(path, bin)
3537
end
3638

37-
def pdf(**opts)
39+
def pdf(**opts)
3840
path, encoding = common_options(**opts)
39-
options = pdf_options(**opts)
40-
data = command("Page.printToPDF", **options).fetch("data")
41-
return data if encoding == :base64
41+
options = pdf_options(**opts).merge(transferMode: "ReturnAsStream")
42+
handle = command("Page.printToPDF", **options).fetch("stream")
4243

43-
bin = Base64.decode64(data)
44-
save_file(path, bin)
44+
if path
45+
stream_to_file(handle, path: path)
46+
else
47+
stream_to_memory(handle, encoding: encoding)
48+
end
4549
end
4650

4751
def mhtml(path: nil)
@@ -70,6 +74,29 @@ def save_file(path, data)
7074
File.open(path.to_s, "wb") { |f| f.write(data) }
7175
end
7276

77+
def stream_to_file(handle, path:)
78+
File.open(path, "wb") { |f| stream_to(handle, f) }
79+
true
80+
end
81+
82+
def stream_to_memory(handle, encoding:)
83+
data = String.new("") # Mutable string has << and compatible to File
84+
stream_to(handle, data)
85+
encoding == :base64 ? Base64.encode64(data) : data
86+
end
87+
88+
def stream_to(handle, output)
89+
loop do
90+
result = command("IO.read", handle: handle, size: STREAM_CHUNK)
91+
92+
data_chunk = result["data"]
93+
data_chunk = Base64.decode64(data_chunk) if result["base64Encoded"]
94+
output << data_chunk
95+
96+
break if result["eof"]
97+
end
98+
end
99+
73100
def common_options(encoding: :base64, path: nil, **_)
74101
encoding = encoding.to_sym
75102
encoding = :binary if path

spec/screenshot_spec.rb

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def create_screenshot(path: file, **options)
295295
it "convert case correct" do
296296
browser.go_to("/ferrum/long_page")
297297

298-
allow(browser.page).to receive(:command).with("Page.printToPDF", {
298+
allow(browser.page).to receive(:command).with("Page.printToPDF", hash_including(
299299
displayHeaderFooter: false,
300300
ignoreInvalidPageRanges: false,
301301
landscape: false,
@@ -310,23 +310,26 @@ def create_screenshot(path: file, **options)
310310
preferCSSPageSize: false,
311311
printBackground: false,
312312
scale: 1,
313-
transferMode: "ReturnAsBase64"
314-
}) { { "data" => "" } }
315-
316-
browser.pdf(path: file, landscape: false,
317-
display_header_footer: false,
318-
print_background: false,
319-
scale: 1,
320-
paper_width: 8.5,
321-
paper_height: 11,
322-
margin_top: 0.4,
323-
margin_bottom: 0.4,
324-
margin_left: 0.4,
325-
margin_right: 0.4,
326-
page_ranges: "",
327-
ignore_invalid_page_ranges: false,
328-
prefer_css_page_size: false,
329-
transfer_mode: "ReturnAsBase64")
313+
)) { { "stream" => "1" } }
314+
315+
allow(browser.page).to receive(:command).with("IO.read", hash_including(handle: "1")) {
316+
{ "data" => "", "base64Encoded" => false, "eof" => true }
317+
}
318+
319+
browser.pdf(path: file,
320+
landscape: false,
321+
display_header_footer: false,
322+
print_background: false,
323+
scale: 1,
324+
paper_width: 8.5,
325+
paper_height: 11,
326+
margin_top: 0.4,
327+
margin_bottom: 0.4,
328+
margin_left: 0.4,
329+
margin_right: 0.4,
330+
page_ranges: "",
331+
ignore_invalid_page_ranges: false,
332+
prefer_css_page_size: false)
330333
end
331334
end
332335
end

0 commit comments

Comments
 (0)