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