Lot of thing
[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::Template;
8 use listenfd::ListenFd;
9 use ron::de::from_reader;
10 use serde::Deserialize;
11
12 use itertools::Itertools;
13
14 mod consts;
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 panic!("ERROR");
43 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 } }
44 }
45
46 #[derive(Debug, Deserialize)]
47 struct Config {
48 port: u16
49 }
50
51 fn get_exe_name() -> String {
52 let first_arg = std::env::args().nth(0).unwrap();
53 let sep: &[_] = &['\\', '/'];
54 first_arg[first_arg.rfind(sep).unwrap()+1..].to_string()
55 }
56
57 #[actix_rt::main]
58 async fn main() -> std::io::Result<()> {
59 if process_args() { return Ok(()) }
60
61 println!("Starting Recipes as web server...");
62
63 let config: Config = {
64 let f = File::open(consts::FILE_CONF).unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF));
65 match from_reader(f) {
66 Ok(c) => c,
67 Err(e) => panic!("Failed to load config: {}", e)
68 }
69 };
70
71 println!("Configuration: {:?}", config);
72
73 // let database_connection = db::create_or_update();
74
75 std::env::set_var("RUST_LOG", "actix_web=info");
76
77 let mut listenfd = ListenFd::from_env();
78 let mut server =
79 HttpServer::new(
80 || {
81 App::new()
82 .wrap(middleware::Compress::default())
83 .service(home_page)
84 .service(view_page)
85 .service(fs::Files::new("/static", "static").show_files_listing())
86 }
87 );
88
89 server =
90 if let Some(l) = listenfd.take_tcp_listener(0).unwrap() {
91 server.listen(l).unwrap()
92 } else {
93 server.bind(&format!("0.0.0.0:{}", config.port)).unwrap()
94 };
95
96 server.run().await
97 }
98
99 fn process_args() -> bool {
100 fn print_usage() {
101 println!("Usage:");
102 println!(" {} [--help] [--test]", get_exe_name());
103 }
104
105 let args: Vec<String> = args().collect();
106
107 if args.iter().any(|arg| arg == "--help") {
108 print_usage();
109 return true
110 } else if args.iter().any(|arg| arg == "--test") {
111 let db_connection = db::Connection::new();
112 return true
113 }
114
115 false
116 }