Display some server process information (memory, cpu usage, uptime)
[valheim_web.git] / backend / src / main.rs
1
2 extern crate listenfd;
3 extern crate askama;
4
5 // use futures::sink::With;
6 use listenfd::ListenFd;
7 use actix_files as fs;
8 use actix_web::{ get, Responder, middleware, App, HttpServer, web::Query };
9 use askama::Template;
10
11 use std::{ /*sync::Mutex, */fs::File, env::args, io::prelude::* };
12 use ron::{ de::from_reader, ser::{ to_string_pretty, PrettyConfig } };
13 use serde::{ Deserialize, Serialize };
14
15 mod consts;
16 mod tests;
17 mod valheim_controller;
18
19 #[derive(Template)]
20 #[template(path = "main.html")]
21 struct MainTemplate {
22 text_status: String,
23 memory: String,
24 cpu: String,
25 uptime: String
26 }
27
28 #[derive(Deserialize)]
29 pub struct Request {
30 m: Option<String>
31 }
32
33 const VALUE_UNKNOWN: &str = "-";
34
35 #[get("/")]
36 async fn main_page(/*key_shared: web::Data<Mutex<String>>,*/ query: Query<Request>) -> impl Responder {
37 //let key = key_shared.lock().unwrap();
38
39 match valheim_controller::get_valheim_executable_information() {
40 Some(info) =>
41 MainTemplate {
42 text_status: String::from("Valheim server is up and running :)"),
43 memory: info.format_memory(),
44 cpu: info.format_cpu_usage(),
45 uptime: info.format_uptime()
46 },
47 None => {
48 let value_unknown = String::from(VALUE_UNKNOWN);
49 MainTemplate { text_status: String::from("Valheim server is down :("), memory: value_unknown.clone(), cpu: value_unknown.clone(), uptime: value_unknown.clone() }
50 }
51 }
52
53 /*
54
55 let m =
56 if valheim_controller::is_valheim_running() { String::from("Valheim server is up and running") } else { String::from("Valheim server is down :(") };
57
58 MainTemplate { sentence: m }
59 */
60 }
61
62 #[derive(Debug, Deserialize, Serialize)]
63 struct Config {
64 port: u16
65 }
66
67 const DEFAULT_CONFIG: Config = Config { port: 8082 };
68
69 fn get_exe_name() -> String {
70 let first_arg = std::env::args().next().unwrap();
71 let sep: &[_] = &['\\', '/'];
72 first_arg[first_arg.rfind(sep).unwrap()+1..].to_string()
73 }
74
75 fn load_config() -> Config {
76 // unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF));
77 match File::open(consts::FILE_CONF) {
78 Ok(file) => from_reader(file).unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF)),
79 Err(_) => {
80 let mut file = File::create(consts::FILE_CONF) .unwrap();
81 file.write_all(to_string_pretty(&DEFAULT_CONFIG, PrettyConfig::new()).unwrap().as_bytes()).unwrap(); // We do not use 'to_writer' because it can't pretty format the output.
82 DEFAULT_CONFIG
83 }
84 }
85 }
86
87 #[actix_rt::main]
88 async fn main() -> std::io::Result<()> {
89
90 if process_args() { return Ok(()) }
91
92 println!("Starting Valheim Admin as web server...");
93
94 let config = load_config();
95
96 println!("Configuration: {:?}", config);
97
98 let mut listenfd = ListenFd::from_env();
99 let mut server =
100 HttpServer::new(
101 move || {
102 App::new()
103 // .app_data(key_shared.clone())
104 .wrap(middleware::Compress::default())
105 .wrap(middleware::Logger::default())
106 .service(main_page)
107 .service(fs::Files::new("/static", "static").show_files_listing())
108 }
109 );
110
111 server =
112 if let Some(l) = listenfd.take_tcp_listener(0).unwrap() {
113 server.listen(l).unwrap()
114 } else {
115 server.bind(&format!("0.0.0.0:{}", config.port)).unwrap()
116 };
117
118 server.run().await
119 }
120
121 fn process_args() -> bool {
122 fn print_usage() {
123 println!("Usage:");
124 println!(" {} [--help] [--status]", get_exe_name());
125 }
126
127 let args: Vec<String> = args().collect();
128
129 if args.iter().any(|arg| arg == "--help") {
130 print_usage();
131 return true
132 } else if args.iter().any(|arg| arg == "--status") {
133 println!("{:?}", valheim_controller::get_valheim_executable_information());
134 return true
135 }
136
137 false
138 }