ovlach_pdf/src/routes/pdf.rs

66 lines
2.4 KiB
Rust
Raw Normal View History

2023-11-27 19:38:32 +00:00
use headless_chrome::Browser;
2023-11-28 17:17:11 +00:00
use headless_chrome::types::PrintToPdfOptions;
use nanobyte_opentelemetry::rocket::TracingSpan;
2023-11-29 13:04:36 +00:00
use rocket::{get, response::stream::ByteStream, fairing::Fairing, fs::NamedFile, futures::TryFutureExt};
use tempfile::NamedTempFile;
use tera::Context;
use tracing::{info_span, error, debug};
use crate::{chromium::rocket::BrowserHolder, tools::{tera::NanoTera, pdf::PdfStream}};
use urlencoding::encode;
2023-11-27 21:56:10 +00:00
2023-11-29 13:04:36 +00:00
// TODO: request-id
fn generate_pdf(browser: Browser, file: &NamedTempFile) -> Vec<u8> {
2023-11-27 19:38:32 +00:00
let tab = browser.new_tab().unwrap();
2023-11-29 13:04:36 +00:00
let path = format!("file://{}", file.path().to_str().unwrap());
2023-11-28 16:09:50 +00:00
info_span!("open_pdf").in_scope(|| {
2023-11-29 13:04:36 +00:00
debug!("Render pdf from {}", &path);
tab.navigate_to(&path).unwrap().wait_until_navigated().unwrap();
2023-11-28 16:09:50 +00:00
});
2023-11-27 19:38:32 +00:00
let options = PrintToPdfOptions{
margin_bottom: Some(0.0),
margin_left: Some(0.0),
margin_right: Some(0.0),
margin_top: Some(0.0),
print_background: Some(true),
//paper_width: Some(29.7),
//paper_height: Some(21.0),
..PrintToPdfOptions::default()
};
//thread::sleep(Duration::from_secs(10));
2023-11-28 16:09:50 +00:00
let bytes = info_span!("print_pdf").in_scope(|| {
tab.print_to_pdf(Some(options)).unwrap()
});
2023-11-29 13:04:36 +00:00
return bytes;
}
#[tracing::instrument]
fn render_template(template_name: &str, file: &NamedTempFile, tera: NanoTera) {
// TODO: handle errors
tera.0.render_to("two_column.html.tera", &Context::new(), file);
2023-11-27 19:38:32 +00:00
}
2023-11-29 13:04:36 +00:00
#[get("/cv/<username>/output.pdf")]
pub async fn render_pdf_cv(username: &str, browser: BrowserHolder, tera: NanoTera, tracing: TracingSpan) -> PdfStream {
2023-11-28 08:45:03 +00:00
let entered_span = tracing.0.enter();
2023-11-29 13:04:36 +00:00
let file = tempfile::Builder::new().suffix(".html").tempfile().unwrap();
render_template("two_column", &file, tera);
2023-11-28 08:45:03 +00:00
let span = info_span!("render_pdf", username = username);
2023-11-29 13:04:36 +00:00
let pdf = span.in_scope(||{
generate_pdf(browser.browser, &file)
2023-11-28 16:09:50 +00:00
});
2023-11-28 08:45:03 +00:00
drop(entered_span);
2023-11-29 13:04:36 +00:00
PdfStream::new(pdf)
}
/// Route only for debuging
#[get("/cv/<username>/output.html")]
pub async fn render_html_cv(username: &str, tera: NanoTera, tracing: TracingSpan) -> NamedFile {
let entered_span = tracing.0.enter();
let file = tempfile::Builder::new().suffix(".html").tempfile().unwrap();
render_template("two_column", &file, tera);
NamedFile::open(file.path()).await.unwrap()
2023-11-27 19:38:32 +00:00
}