-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconverter.rs
More file actions
95 lines (89 loc) · 3.83 KB
/
converter.rs
File metadata and controls
95 lines (89 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! # HTML to PDF converter with screenshots
use crate::defs::{Files, ScreenshotFormat, Timeout, WindowSize};
use crate::errors::{err_headless_chrome, err_write_file, Result};
use crate::options::{PdfPrintingOptions, ScreenshotTakingOptions};
use crate::units::{inches_to_millimeters, inches_to_points, round1};
use clap::crate_name;
use headless_chrome::{Browser, LaunchOptionsBuilder, Tab};
use std::ffi::OsStr;
use std::fs;
use std::sync::Arc;
use std::time::Duration;
/// Converts `HTML` files into `PDF` files.
pub fn html_to_pdf(files: Files, pdf_printing_options: PdfPrintingOptions) -> Result<()> {
let verbose = pdf_printing_options.verbose;
let paper_size = pdf_printing_options.paper_size;
let browser = get_browser(pdf_printing_options.no_crash_reports, None)?;
let tab = get_tab(&browser, pdf_printing_options.page_load_timeout)?;
for (input_url, output_file_name) in &files {
if verbose {
println!("[{}] Printing file {}", crate_name!(), input_url);
if let Some((paper_width, paper_height)) = paper_size.0.zip(paper_size.1) {
println!(
"[{}] Page size: {} x {} mm, {} x {} in, {} x {} pts",
crate_name!(),
inches_to_millimeters(paper_width),
inches_to_millimeters(paper_height),
round1(paper_width),
round1(paper_height),
inches_to_points(paper_width),
inches_to_points(paper_height)
);
}
}
tab.navigate_to(input_url).map_err(|e| err_headless_chrome(e.to_string()))?;
tab.wait_until_navigated().map_err(|e| err_headless_chrome(e.to_string()))?;
let pdf = tab
.print_to_pdf(Some(pdf_printing_options.clone().into()))
.map_err(|e| err_headless_chrome(e.to_string()))?;
save_file(output_file_name, &pdf, verbose, "Printing")?;
}
Ok(())
}
/// Takes screenshot of `HTML` files.
pub fn html_to_screenshot(files: Files, screenshot_taking_options: ScreenshotTakingOptions) -> Result<()> {
let output_format = screenshot_taking_options.screenshot_format.unwrap_or(ScreenshotFormat::Png);
let verbose = screenshot_taking_options.verbose;
let browser = get_browser(screenshot_taking_options.no_crash_reports, screenshot_taking_options.window_size)?;
let tab = get_tab(&browser, screenshot_taking_options.page_load_timeout)?;
for (input_url, output_file_name) in &files {
tab.navigate_to(input_url).map_err(|e| err_headless_chrome(e.to_string()))?;
tab.wait_until_navigated().map_err(|e| err_headless_chrome(e.to_string()))?;
let image = tab
.capture_screenshot(output_format.into(), None, None, true)
.map_err(|e| err_headless_chrome(e.to_string()))?;
save_file(output_file_name, &image, verbose, "Imaging")?;
}
Ok(())
}
/// Returns a new browser.
fn get_browser(no_crash_reports: bool, window_size: WindowSize) -> Result<Browser> {
let mut arguments = vec![OsStr::new("--disable-search-engine-choice-screen")];
if no_crash_reports {
arguments.push(OsStr::new("--disable-crash-reporter"))
}
let launch_options = LaunchOptionsBuilder::default()
.headless(true)
.devtools(false)
.args(arguments)
.window_size(window_size)
.build()
.map_err(|e| err_headless_chrome(e.to_string()))?;
Browser::new(launch_options).map_err(|e| err_headless_chrome(e.to_string()))
}
/// Returns a new browser tab.
fn get_tab(browser: &Browser, timeout: Timeout) -> Result<Arc<Tab>> {
let tab = browser.new_tab().map_err(|e| err_headless_chrome(e.to_string()))?;
if let Some(timeout) = timeout {
tab.set_default_timeout(Duration::from_millis(timeout));
}
Ok(tab)
}
/// Saves the content to file.
fn save_file(file_name: &str, content: &[u8], verbose: bool, action: &str) -> Result<()> {
fs::write(file_name, content).map_err(|e| err_write_file(file_name, e.to_string()))?;
if verbose {
println!("[{}] {action} completed: {file_name}\n", crate_name!());
}
Ok(())
}