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