Created
January 11, 2021 18:31
-
-
Save eduardonunesp/a9d783e1d86b85cccccd4cfbc6e8d530 to your computer and use it in GitHub Desktop.
pdf-exporter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::fs::File; | |
use std::io::{prelude::*, BufReader, Write}; | |
use std::process::Command; | |
use actix_multipart::Multipart; | |
use actix_web::{ | |
get, http::StatusCode, post, web, App, Error, HttpResponse, HttpServer, Responder, | |
}; | |
use futures::{StreamExt, TryStreamExt}; | |
use tempdir::TempDir; | |
#[get("/")] | |
async fn ping() -> impl Responder { | |
"Pong".with_status(StatusCode::OK) | |
} | |
#[post("/")] | |
async fn upload(mut payload: Multipart) -> Result<HttpResponse, Error> { | |
let dir = TempDir::new("temp")?; | |
let mut vec: Vec<u8> = vec![]; | |
while let Ok(Some(mut field)) = payload.try_next().await { | |
let content_type = field.content_disposition().unwrap(); | |
let filename = content_type.get_filename().unwrap(); | |
let tmp_filepath = dir.path().join(sanitize_filename::sanitize(&filename)); | |
let mut filepath = tmp_filepath.clone(); | |
let mut f = web::block(move || std::fs::File::create(&tmp_filepath)).await?; | |
// Field in turn is stream of *Bytes* object | |
while let Some(chunk) = field.next().await { | |
let data = chunk?; | |
// filesystem operations are blocking, we have to use threadpool | |
f = web::block(move || f.write_all(&data).map(|_| f)).await?; | |
} | |
println!("{:?}", &filepath); | |
let mut soffice = Command::new("soffice"); | |
let result = soffice | |
.arg("--headless") | |
.arg("--convert-to") | |
.arg("pdf") | |
.arg(&filepath) | |
.arg("--outdir") | |
.arg(std::path::Path::new(&filepath).parent().unwrap()) | |
.output()?; | |
println!("{}", String::from_utf8_lossy(&result.stdout)); | |
filepath.set_extension("pdf"); | |
vec = web::block(move || { | |
let file = File::open(filepath)?; | |
let mut buf_reader = BufReader::new(file); | |
let mut tmp_vec: Vec<u8> = vec![]; | |
buf_reader.read_to_end(&mut tmp_vec)?; | |
std::io::Result::Ok(tmp_vec) | |
}) | |
.await?; | |
} | |
Ok(HttpResponse::Ok() | |
.content_type("application/pdf") | |
.body(vec) | |
.into()) | |
} | |
#[actix_rt::main] | |
async fn main() -> std::io::Result<()> { | |
let port = std::env::var("PORT").unwrap_or("3000".to_string()); | |
let server_address = format!("0.0.0.0:{}", port); | |
println!("Serving on port {}", server_address); | |
HttpServer::new(|| App::new().service(upload).service(ping)) | |
.bind(server_address)? | |
.run() | |
.await | |
} |
Author
eduardonunesp
commented
Jul 14, 2021
[package]
name = "exporter"
version = "0.1.0"
authors = ["Eduardo Pereira <[email protected]>"]
edition = "2018"
[dependencies]
actix-rt = "1.0.0"
actix-web = "2.0.0"
actix-http = "1.0.1"
actix-service = "1.0.5"
actix-multipart = "0.2.0"
futures = "0.3.1"
sanitize-filename = "0.2"
tempdir = "0.3"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment