Add asynchronous call to database.
[recipes.git] / backend / src / main.rs
index 299f5c5..03517f8 100644 (file)
-use std::io::prelude::*;
-use std::{fs::File, env::args};
-
 use actix_files as fs;
-use actix_web::{get, web, Responder, middleware, App, HttpServer, HttpResponse, web::Query, middleware::Logger};
-
-use askama::Template;
-use listenfd::ListenFd;
-use ron::de::from_reader;
-use serde::Deserialize;
-use env_logger;
+use actix_web::{web, middleware, App, HttpServer};
+use chrono::prelude::*;
+use clap::Parser;
+use log::error;
 
-use itertools::Itertools;
+use data::db;
 
 mod consts;
-mod db;
-
-#[derive(Template)]
-#[template(path = "main.html")]
-struct MainTemplate<'a> {
-    test: &'a str,
-}
-
-#[derive(Deserialize)]
-pub struct Request {
-   m: Option<String>
-}
-
-fn main_page(query: Query<Request>) -> HttpResponse {
-
-    let main_template = MainTemplate { test: &"*** test ***" };
-
-    let s = main_template.render().unwrap();
-    HttpResponse::Ok().content_type("text/html").body(s)
-}
-
-#[derive(Debug, Deserialize)]
-struct Config {
-    port: u16
-}
-
-fn get_exe_name() -> String {
-    let first_arg = std::env::args().nth(0).unwrap();
-    let sep: &[_] = &['\\', '/'];
-    first_arg[first_arg.rfind(sep).unwrap()+1..].to_string()
-}
-
-#[actix_rt::main]
+mod utils;
+mod data;
+mod hash;
+mod model;
+mod user;
+mod email;
+mod config;
+mod services;
+
+#[actix_web::main]
 async fn main() -> std::io::Result<()> {
     if process_args() { return Ok(()) }
 
-    println!("Starting RUP as web server...");
-
-    let config: Config = {
-        let f = File::open(consts::FILE_CONF).unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF));
-        match from_reader(f) {
-            Ok(c) => c,
-            Err(e) => panic!("Failed to load config: {}", e)
-        }
-    };
+    std::env::set_var("RUST_LOG", "info,actix_web=info");
+    env_logger::init();
 
-    println!("Configuration: {:?}", config);
+    println!("Starting Recipes as web server...");
 
-    // let database_connection = db::create_or_update();
+    let config = web::Data::new(config::load());
+    let port = config.as_ref().port;
 
-    std::env::set_var("RUST_LOG", "actix_web=info");
-    env_logger::init();
-
-    let mut listenfd = ListenFd::from_env();
-    let mut server =
-        HttpServer::new(
-            || {
-                App::new()
-                    .wrap(middleware::Compress::default())
-                    .wrap(Logger::default())
-                    .wrap(Logger::new("%a %{User-Agent}i"))
-                    .service(web::resource("/").to(main_page))
-                    .service(fs::Files::new("/static", "static").show_files_listing())
-            }
-        );
+    println!("Configuration: {:?}", config);
 
-    server =
-        if let Some(l) = listenfd.take_tcp_listener(0).unwrap() {
-            server.listen(l).unwrap()
-        } else {
-            server.bind(&format!("0.0.0.0:{}", config.port)).unwrap()
-        };
+    let db_connection = web::Data::new(db::Connection::new().unwrap());
+
+    let server =
+        HttpServer::new(move || {
+            App::new()
+                .wrap(middleware::Logger::default())
+                .wrap(middleware::Compress::default())
+                .app_data(db_connection.clone())
+                .app_data(config.clone())
+                .service(services::home_page)
+                .service(services::sign_up_get)
+                .service(services::sign_up_post)
+                .service(services::sign_up_check_email)
+                .service(services::sign_up_validation)
+                .service(services::sign_in_get)
+                .service(services::sign_in_post)
+                .service(services::sign_out)
+                .service(services::view_recipe)
+                .service(fs::Files::new("/static", "static"))
+                .default_service(web::to(services::not_found))
+        });
+        //.workers(1);
+
+    server.bind(&format!("0.0.0.0:{}", port))?.run().await
+}
 
-    server.run().await
+#[derive(Parser, Debug)]
+struct Args {
+    #[arg(long)]
+    dbtest: bool
 }
 
 fn process_args() -> bool {
-    fn print_usage() {
-        println!("Usage:");
-        println!(" {} [--help] [--test]", get_exe_name());
-    }
-
-    let args: Vec<String> = args().collect();
+    let args = Args::parse();
+
+    if args.dbtest {
+        match db::Connection::new() {
+            Ok(con) => {
+                if let Err(error) = con.execute_file("sql/data_test.sql") {
+                    eprintln!("{}", error);
+                }
+                // Set the creation datetime to 'now'.
+                con.execute_sql("UPDATE [User] SET [creation_datetime] = ?1 WHERE [email] = 'paul@test.org'", [Utc::now()]).unwrap();
+            },
+            Err(error) => {
+                eprintln!("{}", error);
+            },
+        }
 
-    if args.iter().any(|arg| arg == "--help") {
-        print_usage();
-        return true
-    } else if args.iter().any(|arg| arg == "--test") {
-        let db_connection = db::Connection::new();
-        db_connection.create_or_update();
-        return true
+        return true;
     }
 
     false