Remove generated file 'frontend.js'
[recipes.git] / backend / src / main.rs
1 use std::path::Path;
2
3 use actix_files as fs;
4 use actix_web::{middleware, web, App, HttpServer};
5 use chrono::prelude::*;
6 use clap::Parser;
7
8 use data::db;
9
10 mod config;
11 mod consts;
12 mod data;
13 mod email;
14 mod hash;
15 mod model;
16 mod services;
17 mod utils;
18
19 #[actix_web::main]
20 async fn main() -> std::io::Result<()> {
21 if process_args() {
22 return Ok(());
23 }
24
25 std::env::set_var("RUST_LOG", "info,actix_web=info");
26 env_logger::init();
27
28 println!("Starting Recipes as web server...");
29
30 let config = web::Data::new(config::load());
31 let port = config.as_ref().port;
32
33 println!("Configuration: {:?}", config);
34
35 let db_connection = web::Data::new(db::Connection::new().unwrap());
36
37 let server = HttpServer::new(move || {
38 App::new()
39 .wrap(middleware::Logger::default())
40 .wrap(middleware::Compress::default())
41 .app_data(db_connection.clone())
42 .app_data(config.clone())
43 .service(services::home_page)
44 .service(services::sign_up_get)
45 .service(services::sign_up_post)
46 .service(services::sign_up_check_email)
47 .service(services::sign_up_validation)
48 .service(services::sign_in_get)
49 .service(services::sign_in_post)
50 .service(services::sign_out)
51 .service(services::view_recipe)
52 .service(services::edit_recipe)
53 .service(fs::Files::new("/static", "static"))
54 .default_service(web::to(services::not_found))
55 });
56 //.workers(1);
57
58 server.bind(&format!("0.0.0.0:{}", port))?.run().await
59 }
60
61 #[derive(Parser, Debug)]
62 struct Args {
63 /// Will clear the database and insert some test data. (A backup is made first).
64 #[arg(long)]
65 dbtest: bool,
66 }
67
68 fn process_args() -> bool {
69 let args = Args::parse();
70
71 if args.dbtest {
72 // Make a backup of the database.
73 let db_path = Path::new(consts::DB_DIRECTORY).join(consts::DB_FILENAME);
74 if db_path.exists() {
75 let db_path_bckup = (1..)
76 .find_map(|n| {
77 let p = db_path.with_extension(format!("sqlite.bckup{:03}", n));
78 if p.exists() {
79 None
80 } else {
81 Some(p)
82 }
83 })
84 .unwrap();
85 std::fs::copy(&db_path, &db_path_bckup).expect(&format!(
86 "Unable to make backup of {:?} to {:?}",
87 &db_path, &db_path_bckup
88 ));
89 std::fs::remove_file(&db_path)
90 .expect(&format!("Unable to remove db file: {:?}", &db_path));
91 }
92
93 match db::Connection::new() {
94 Ok(con) => {
95 if let Err(error) = con.execute_file("sql/data_test.sql") {
96 eprintln!("{}", error);
97 }
98 // Set the creation datetime to 'now'.
99 con.execute_sql(
100 "UPDATE [User] SET [creation_datetime] = ?1 WHERE [email] = 'paul@test.org'",
101 [Utc::now()],
102 )
103 .unwrap();
104 }
105 Err(error) => {
106 eprintln!("{}", error);
107 }
108 }
109
110 return true;
111 }
112
113 false
114 }