#![recursion_limit = "1024"]
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
#![warn(clippy::cargo)]
#![warn(
clippy::clone_on_ref_ptr,
clippy::empty_structs_with_brackets,
clippy::exit,
clippy::expect_used,
clippy::format_push_string,
clippy::get_unwrap,
clippy::if_then_some_else_none,
clippy::indexing_slicing,
clippy::integer_division,
clippy::large_include_file,
clippy::missing_docs_in_private_items,
clippy::mixed_read_write_in_expression,
clippy::multiple_inherent_impl,
clippy::mutex_atomic,
clippy::panic_in_result_fn,
clippy::partial_pub_fields,
clippy::print_stderr,
clippy::print_stdout,
clippy::rc_buffer,
clippy::rc_mutex,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_name_method,
clippy::shadow_unrelated,
clippy::str_to_string,
clippy::string_to_string,
clippy::suspicious_xor_used_as_pow,
clippy::todo,
clippy::try_err,
clippy::unimplemented,
clippy::unnecessary_self_imports,
clippy::unneeded_field_pattern,
clippy::unreachable,
clippy::unseparated_literal_suffix,
clippy::unwrap_in_result,
clippy::unwrap_used,
clippy::use_debug,
clippy::verbose_file_reads
)]
#![allow(clippy::multiple_crate_versions)]
use actix_cors::Cors;
use actix_web::{http, middleware::Logger, App, HttpServer};
use config::{api_doc, auth::Config, routes};
use db::{
connection::Pool,
cronjobs::{cleanup_layers, cleanup_maps},
};
use log::info;
pub mod config;
pub mod controller;
pub mod db;
pub mod error;
pub mod model;
#[allow(clippy::missing_docs_in_private_items)]
pub mod schema;
pub mod service;
pub mod sse;
#[cfg(test)]
pub mod test;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let config = match config::app::Config::from_env() {
Ok(config) => config,
Err(e) => panic!("Error reading configuration: {e}"),
};
env_logger::init();
Config::init(&config).await;
info!(
"Starting server on {}:{}",
config.bind_address.0, config.bind_address.1
);
let data = config::data::init(&config.database_url);
start_cronjobs(data.pool.clone());
HttpServer::new(move || {
App::new()
.wrap(cors_configuration())
.app_data(data.clone())
.configure(routes::config)
.configure(api_doc::config)
.wrap(Logger::default())
})
.shutdown_timeout(5)
.bind(config.bind_address)?
.run()
.await
}
fn cors_configuration() -> Cors {
Cors::default()
.allowed_origin("http://localhost:5173")
.allowed_origin("https://mr.permaplant.net")
.allowed_origin("https://dev.permaplant.net")
.allowed_origin("https://master.permaplant.net")
.allowed_origin("https://www.permaplant.net")
.allowed_origin("https://cloud.permaplant.net")
.allowed_methods(vec!["GET", "POST", "PUT", "PATCH", "DELETE"])
.allowed_headers(vec![
http::header::AUTHORIZATION,
http::header::ACCEPT,
http::header::CONTENT_TYPE,
])
.max_age(3600)
}
fn start_cronjobs(pool: Pool) {
tokio::spawn(cleanup_maps(pool.clone()));
tokio::spawn(cleanup_layers(pool));
}