diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/src/main.rs b/src/main.rs index d17984f..00fc6ce 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,21 +1,30 @@ | |||
1 | use crate::config::Config; | 1 | use crate::{ |
2 | use crate::db::init_db_pool; | 2 | config::Config, |
3 | use crate::routes::device; | 3 | db::init_db_pool, |
4 | use crate::routes::start::start; | 4 | routes::{device, start, status}, |
5 | use crate::routes::status::status; | 5 | services::ping::{BroadcastCommand, StatusMap}, |
6 | use crate::services::ping::StatusMap; | 6 | }; |
7 | use axum::middleware::from_fn_with_state; | 7 | use axum::{ |
8 | use axum::routing::{get, put}; | 8 | middleware::from_fn_with_state, |
9 | use axum::{routing::post, Router}; | 9 | routing::{get, post}, |
10 | Router, | ||
11 | }; | ||
10 | use dashmap::DashMap; | 12 | use dashmap::DashMap; |
11 | use services::ping::BroadcastCommand; | ||
12 | use sqlx::PgPool; | 13 | use sqlx::PgPool; |
13 | use std::env; | 14 | use time::UtcOffset; |
14 | use std::sync::Arc; | 15 | use std::{env, sync::Arc}; |
15 | use tokio::sync::broadcast::{channel, Sender}; | 16 | use tokio::sync::broadcast::{channel, Sender}; |
16 | use tracing::{info, level_filters::LevelFilter}; | 17 | use tracing::{info, level_filters::LevelFilter}; |
17 | use tracing_subscriber::fmt::time::UtcTime; | 18 | use tracing_subscriber::{ |
18 | use tracing_subscriber::{fmt, prelude::*, EnvFilter}; | 19 | fmt::{self, time::OffsetTime}, |
20 | prelude::*, | ||
21 | EnvFilter, | ||
22 | }; | ||
23 | use utoipa::{ | ||
24 | openapi::security::{ApiKey, ApiKeyValue, SecurityScheme}, | ||
25 | Modify, OpenApi, | ||
26 | }; | ||
27 | use utoipa_swagger_ui::SwaggerUi; | ||
19 | 28 | ||
20 | mod config; | 29 | mod config; |
21 | mod db; | 30 | mod db; |
@@ -25,20 +34,62 @@ mod routes; | |||
25 | mod services; | 34 | mod services; |
26 | mod wol; | 35 | mod wol; |
27 | 36 | ||
37 | #[derive(OpenApi)] | ||
38 | #[openapi( | ||
39 | paths( | ||
40 | start::start, | ||
41 | device::get, | ||
42 | device::get_path, | ||
43 | device::post, | ||
44 | device::put, | ||
45 | ), | ||
46 | components( | ||
47 | schemas( | ||
48 | start::Payload, | ||
49 | start::Response, | ||
50 | device::PutDevicePayload, | ||
51 | device::GetDevicePayload, | ||
52 | device::PostDevicePayload, | ||
53 | db::DeviceSchema, | ||
54 | ) | ||
55 | ), | ||
56 | modifiers(&SecurityAddon), | ||
57 | tags( | ||
58 | (name = "Webol", description = "Webol API") | ||
59 | ) | ||
60 | )] | ||
61 | struct ApiDoc; | ||
62 | |||
63 | struct SecurityAddon; | ||
64 | |||
65 | impl Modify for SecurityAddon { | ||
66 | fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { | ||
67 | if let Some(components) = openapi.components.as_mut() { | ||
68 | components.add_security_scheme( | ||
69 | "api_key", | ||
70 | SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("Authorization"))), | ||
71 | ); | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
28 | #[tokio::main] | 76 | #[tokio::main] |
77 | #[allow(deprecated)] | ||
29 | async fn main() -> color_eyre::eyre::Result<()> { | 78 | async fn main() -> color_eyre::eyre::Result<()> { |
30 | color_eyre::install()?; | 79 | color_eyre::install()?; |
31 | 80 | ||
81 | let config = Config::load()?; | ||
82 | |||
32 | let time_format = | 83 | let time_format = |
33 | time::macros::format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); | 84 | time::macros::format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); |
34 | let loc = UtcTime::new(time_format); | 85 | let time = OffsetTime::new(UtcOffset::from_hms(config.timeoffset, 0, 0)?, time_format); |
35 | 86 | ||
36 | let file_appender = tracing_appender::rolling::daily("logs", "webol.log"); | 87 | let file_appender = tracing_appender::rolling::daily("logs", "webol.log"); |
37 | let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); | 88 | let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); |
38 | 89 | ||
39 | tracing_subscriber::registry() | 90 | tracing_subscriber::registry() |
40 | .with(fmt::layer().with_writer(non_blocking).with_ansi(false)) | 91 | .with(fmt::layer().with_writer(non_blocking).with_ansi(false)) |
41 | .with(fmt::layer().with_timer(loc)) | 92 | .with(fmt::layer().with_timer(time)) |
42 | .with( | 93 | .with( |
43 | EnvFilter::builder() | 94 | EnvFilter::builder() |
44 | .with_default_directive(LevelFilter::INFO.into()) | 95 | .with_default_directive(LevelFilter::INFO.into()) |
@@ -48,8 +99,6 @@ async fn main() -> color_eyre::eyre::Result<()> { | |||
48 | 99 | ||
49 | let version = env!("CARGO_PKG_VERSION"); | 100 | let version = env!("CARGO_PKG_VERSION"); |
50 | 101 | ||
51 | let config = Config::load()?; | ||
52 | |||
53 | info!("start webol v{}", version); | 102 | info!("start webol v{}", version); |
54 | 103 | ||
55 | let db = init_db_pool(&config.database_url).await; | 104 | let db = init_db_pool(&config.database_url).await; |
@@ -67,12 +116,15 @@ async fn main() -> color_eyre::eyre::Result<()> { | |||
67 | }; | 116 | }; |
68 | 117 | ||
69 | let app = Router::new() | 118 | let app = Router::new() |
70 | .route("/start", post(start)) | 119 | .route("/start", post(start::start)) |
71 | .route("/device", get(device::get)) | 120 | .route( |
72 | .route("/device", put(device::put)) | 121 | "/device", |
73 | .route("/device", post(device::post)) | 122 | post(device::post).get(device::get).put(device::put), |
74 | .route("/status", get(status)) | 123 | ) |
124 | .route("/device/:id", get(device::get_path)) | ||
125 | .route("/status", get(status::status)) | ||
75 | .route_layer(from_fn_with_state(shared_state.clone(), extractors::auth)) | 126 | .route_layer(from_fn_with_state(shared_state.clone(), extractors::auth)) |
127 | .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi())) | ||
76 | .with_state(Arc::new(shared_state)); | 128 | .with_state(Arc::new(shared_state)); |
77 | 129 | ||
78 | let addr = config.serveraddr; | 130 | let addr = config.serveraddr; |