mod config; mod db; mod deleter; mod download; mod file_kind; mod multipart; mod template; mod upload; use actix_files::Files; use actix_web::{ middleware::{self, Logger}, web::{self, Data}, App, Error, HttpResponse, HttpServer, }; use env_logger::Env; use sqlx::postgres::PgPool; use std::env; use tokio::{sync::mpsc::channel, task}; async fn not_found() -> Result { Ok(HttpResponse::NotFound() .content_type("text/plain") .body("not found")) } #[tokio::main] async fn main() -> std::io::Result<()> { env_logger::Builder::from_env(Env::default().default_filter_or("info,sqlx=warn")).init(); let pool: PgPool = db::setup_db().await; let config = config::get_config().await; let (sender, receiver) = channel(8); log::info!("omnomnom"); let db = web::Data::new(pool.clone()); let expiry_watch_sender = web::Data::new(sender); let bind_address = env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8000".to_owned()); task::spawn(deleter::delete_old_files( receiver, pool, config.files_dir.clone(), )); template::write_prefillable_templates(&config).await; let config = Data::new(config); HttpServer::new({ move || { App::new() .wrap(Logger::new(r#"%{r}a "%r" =%s %bbytes %Tsec"#)) .wrap(middleware::Compress::default()) .app_data(db.clone()) .app_data(expiry_watch_sender.clone()) .app_data(config.clone()) .service(web::resource("/").route(web::get().to(upload::index))) .service(web::resource("/upload").route(web::post().to(upload::upload))) .service( web::resource(["/upload/{id}", "/upload/{id}/{name}"]) .route(web::get().to(upload::uploaded)), ) .service(Files::new("/static", "static").disable_content_disposition()) .service( web::resource([ "/{id:[a-z0-9]{5}}", "/{id:[a-z0-9]{5}}/", "/{id:[a-z0-9]{5}}/{name}", ]) .route(web::get().to(download::download)), ) .default_service(web::route().to(not_found)) } }) .bind(bind_address)? .run() .await }