-use std::fs::File;
-use std::sync::Mutex;
-
use actix_files as fs;
-use actix_web::{get, web, Responder, middleware, App, HttpServer, HttpRequest};
-use askama_actix::Template;
+use actix_web::{web, middleware, App, HttpServer};
+use chrono::prelude::*;
use clap::Parser;
-use ron::de::from_reader;
-use serde::Deserialize;
+use log::error;
+
+use data::db;
mod consts;
+mod utils;
+mod data;
+mod hash;
mod model;
-mod db;
-
-#[derive(Template)]
-#[template(path = "home.html")]
-struct HomeTemplate {
- recipes: Vec<(i32, String)>,
-}
-
-#[derive(Template)]
-#[template(path = "view_recipe.html")]
-struct ViewRecipeTemplate {
- recipes: Vec<(i32, String)>,
- current_recipe: model::Recipe,
-}
-
-#[derive(Deserialize)]
-pub struct Request {
- m: Option<String>
-}
-
-#[get("/")]
-async fn home_page(req: HttpRequest, connection: web::Data<db::Connection>) -> impl Responder {
- HomeTemplate { recipes: connection.get_all_recipe_titles().unwrap() } // TODO: unwrap.
-}
-
-#[get("/recipe/view/{id}")]
-async fn view_recipe(req: HttpRequest, path: web::Path<(i32,)>, connection: web::Data<db::Connection>) -> impl Responder {
- ViewRecipeTemplate {
- recipes: connection.get_all_recipe_titles().unwrap(),
- current_recipe: connection.get_recipe(path.0).unwrap(),
- }
-}
-
-#[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()
-}
+mod user;
+mod email;
+mod config;
+mod services;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
if process_args() { return Ok(()) }
- std::env::set_var("RUST_LOG", "actix_web=debug");
+ std::env::set_var("RUST_LOG", "info,actix_web=info");
env_logger::init();
println!("Starting Recipes 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)
- }
- };
+ let config = web::Data::new(config::load());
+ let port = config.as_ref().port;
println!("Configuration: {:?}", config);
- let db_connection = web::Data::new(db::Connection::new().unwrap()); // TODO: remove unwrap.
-
- std::env::set_var("RUST_LOG", "actix_web=info");
-
- let mut server =
- HttpServer::new(
- move || {
- App::new()
- .wrap(middleware::Logger::default())
- .wrap(middleware::Compress::default())
- .app_data(db_connection.clone())
- .service(home_page)
- .service(view_recipe)
- .service(fs::Files::new("/static", "static").show_files_listing())
- }
- );
-
- server = server.bind(&format!("0.0.0.0:{}", config.port)).unwrap();
-
- server.run().await
+ 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
}
#[derive(Parser, Debug)]
struct Args {
#[arg(long)]
- test: bool
+ dbtest: bool
}
fn process_args() -> bool {
let args = Args::parse();
- if args.test {
- if let Err(error) = db::Connection::new() {
- println!("Error: {:?}", error)
+ 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);
+ },
}
- return true;
- }
- false
-
- /*
-
-
- fn print_usage() {
- println!("Usage:");
- println!(" {} [--help] [--test]", get_exe_name());
+ return true;
}
- let args: Vec<String> = args().collect();
-
- if args.iter().any(|arg| arg == "--help") {
- print_usage();
- return true
- } else if args.iter().any(|arg| arg == "--test") {
- match db::Connection::new() {
- Ok(_) => (),
- Err(error) => println!("Error: {:?}", error)
- }
- return true
- }
false
- */
}