1#![forbid(unsafe_code)]
2#![allow(proc_macro_derive_resolution_fallback)]
4
5#[macro_use]
6extern crate diesel;
7#[macro_use]
8extern crate log;
9#[macro_use]
10extern crate serde_derive;
11
12pub mod app;
13pub mod cli;
14pub mod errors;
15pub mod handlers;
16pub mod models;
17pub mod rpi;
18pub mod schema;
19pub mod settings;
20pub mod setup;
21pub mod utilities;
22pub mod validation;
23
24use crate::app::AppState;
25use crate::cli::get_cli_args;
26use crate::handlers::DbExecutor;
27use crate::setup::setup_rpi_and_db;
28use crate::utilities::reset_table_gpio_state;
29use crate::validation::validate_setup;
30use actix::SyncArbiter;
31use actix_web::server;
32use diesel::{r2d2::ConnectionManager, SqliteConnection};
33use dotenv::dotenv;
34
35pub fn setup_and_run() {
36 let cli_args = get_cli_args();
38
39 let config = settings::Settings::new(cli_args).expect("Could not read config file");
41 let database_url = &config.database.database_url;
42 let hostname = config.webserver.hostname;
43 let port = config.webserver.port;
44
45 dotenv().ok();
47
48 env_logger::init();
50
51 let manager = ConnectionManager::<SqliteConnection>::new(database_url.to_string());
53 let pool = r2d2::Pool::builder()
54 .build(manager)
55 .expect("Failed to create r2d2 pool.");
56 let connection = pool.get().expect("Failed to acquire connection");
57
58 reset_table_gpio_state(&connection).expect("Unable to update table 'gpio_state'");
60
61 validate_setup(&config.gpioconfig).expect("Provided setup variables are inconsistent");
63
64 let gpio_arc_mutex = rpi::create_gpio_arc_mutex().expect("Could not acquire GPIO");
66
67 setup_rpi_and_db(&config.gpioconfig, &connection, gpio_arc_mutex.clone())
69 .expect("Error when setting up Raspberry Pi and database");
70
71 let sys = actix::System::new("raspberry-web");
72 let addr = SyncArbiter::start(3, move || DbExecutor(pool.clone()));
75
76 let ip_port = format!("{}:{}", hostname, port);
77 let _server = server::new(move || {
78 app::create_app(AppState {
79 db: addr.clone(),
80 gpio_arc_mutex: gpio_arc_mutex.clone(),
81 })
82 })
83 .bind(&ip_port)
84 .expect(&format!("Can not bind to {}", &ip_port))
85 .start();
86
87 let _sys = sys.run();
88}