Initial model + some various changes
[recipes.git] / backend / src / main.rs
1 use std::io::prelude::*;
2 use std::{fs::File, env::args};
3
4 use actix_files as fs;
5 use actix_web::{get, web, Responder, middleware, App, HttpServer, HttpResponse, HttpRequest, web::Query};
6
7 use askama_actix::Template;
8 use ron::de::from_reader;
9 use serde::Deserialize;
10
11 use itertools::Itertools;
12
13 mod consts;
14 mod model;
15 mod db;
16
17 #[derive(Template)]
18 #[template(path = "home.html")]
19 struct HomeTemplate {
20 recipes: Vec<db::Recipe>
21 }
22
23 #[derive(Template)]
24 #[template(path = "view_recipe.html")]
25 struct ViewRecipeTemplate {
26 recipes: Vec<db::Recipe>,
27 current_recipe: db::Recipe
28 }
29
30 #[derive(Deserialize)]
31 pub struct Request {
32 m: Option<String>
33 }
34
35 #[get("/")]
36 async fn home_page(req: HttpRequest) -> impl Responder {
37 HomeTemplate { recipes: vec![ db::Recipe { title: String::from("Saumon en croûte feuilletée"), id: 1 }, db::Recipe { title: String::from("Croissant au jambon"), id: 2 } ] }
38 }
39
40 #[get("/recipe/view/{id}")]
41 async fn view_page(req: HttpRequest, path: web::Path<(i32,)>) -> impl Responder {
42 ViewRecipeTemplate { recipes: vec![ db::Recipe { title: String::from("Saumon en croûte feuilletée"), id: 1 }, db::Recipe { title: String::from("Croissant au jambon"), id: 2 } ], current_recipe: db::Recipe { title: String::from("Saumon en croûte feuilletée"), id: 1 } }
43 }
44
45 #[derive(Debug, Deserialize)]
46 struct Config {
47 port: u16
48 }
49
50 fn get_exe_name() -> String {
51 let first_arg = std::env::args().nth(0).unwrap();
52 let sep: &[_] = &['\\', '/'];
53 first_arg[first_arg.rfind(sep).unwrap()+1..].to_string()
54 }
55
56 #[actix_web::main]
57 async fn main() -> std::io::Result<()> {
58 if process_args() { return Ok(()) }
59
60 std::env::set_var("RUST_LOG", "actix_web=debug");
61 env_logger::init();
62
63 println!("Starting Recipes as web server...");
64
65 let config: Config = {
66 let f = File::open(consts::FILE_CONF).unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF));
67 match from_reader(f) {
68 Ok(c) => c,
69 Err(e) => panic!("Failed to load config: {}", e)
70 }
71 };
72
73 println!("Configuration: {:?}", config);
74
75 // let database_connection = db::create_or_update();
76
77 std::env::set_var("RUST_LOG", "actix_web=info");
78
79 let mut server =
80 HttpServer::new(
81 || {
82 App::new()
83 .wrap(middleware::Logger::default())
84 .wrap(middleware::Compress::default())
85 .service(home_page)
86 .service(view_page)
87 .service(fs::Files::new("/static", "static").show_files_listing())
88 }
89 );
90
91 server = server.bind(&format!("0.0.0.0:{}", config.port)).unwrap();
92
93 server.run().await
94 }
95
96 fn process_args() -> bool {
97 fn print_usage() {
98 println!("Usage:");
99 println!(" {} [--help] [--test]", get_exe_name());
100 }
101
102 let args: Vec<String> = args().collect();
103
104 if args.iter().any(|arg| arg == "--help") {
105 print_usage();
106 return true
107 } else if args.iter().any(|arg| arg == "--test") {
108 match db::Connection::new() {
109 Ok(_) => (),
110 Err(error) => println!("Error: {:?}", error)
111 }
112 return true
113 }
114
115 false
116 }