#![doc = include_str!("../README.md")]
#![doc(html_root_url = "https://puffer.stellular.net/api/docs/puffer/")]
#![doc(html_favicon_url = "https://stellular.net/static/favicon.svg")]
#![doc(
html_logo_url = "https://code.stellular.org/repo-avatars/cc8d0efab0759fa6310b75fd5759c33169ee0ab354a958172ed4425a66d2593b"
)]
#![doc(issue_tracker_base_url = "https://code.stellular.org/stellular/puffer/issues/")]
use actix_files as fs;
use actix_web::{web, App, HttpServer};
use dotenv;
pub mod config;
pub mod db;
pub mod utility;
pub mod api;
pub mod pages;
pub mod markup;
use crate::db::{AppData, Database};
use dorsal::DatabaseOpts;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
dotenv::dotenv().ok();
env_logger::init();
let args: Vec<String> = config::collect_arguments();
let port_search: Option<String> = config::get_named_argument(&args, "port");
let mut port: u16 = 8080;
if port_search.is_some() {
port = port_search.unwrap().parse::<u16>().unwrap();
}
let static_dir_flag: Option<String> = config::get_named_argument(&args, "static-dir");
let db_type: Option<String> = config::get_named_argument(&args, "db-type");
let db_host: Option<String> = config::get_var("DB_HOST");
let db_user: Option<String> = config::get_var("DB_USER");
let db_pass: Option<String> = config::get_var("DB_PASS");
let db_name: Option<String> = config::get_var("DB_NAME");
let db_is_other: bool = db_type
.clone()
.is_some_and(|x| (x == String::from("postgres")) | (x == String::from("mysql")));
if db_is_other && (db_user.is_none() | db_pass.is_none() | db_name.is_none()) {
panic!("Missing required database config settings!");
}
let db: Database = Database::new(DatabaseOpts {
_type: db_type,
host: db_host,
user: if db_is_other {
db_user.unwrap()
} else {
String::new()
},
pass: if db_is_other {
db_pass.unwrap()
} else {
String::new()
},
name: if db_is_other {
db_name.unwrap()
} else {
String::new()
},
})
.await;
db.init().await;
println!("Starting server at: http://localhost:{port}");
HttpServer::new(move || {
let client = awc::Client::default();
let data = web::Data::new(AppData {
db: db.clone(),
http_client: client,
});
let cors = actix_cors::Cors::default().send_wildcard();
App::new()
.app_data(web::Data::clone(&data))
.wrap(actix_web::middleware::Logger::default())
.wrap(cors)
.service(
fs::Files::new(
"/static",
if static_dir_flag.is_some() {
static_dir_flag.as_ref().unwrap()
} else {
"./static"
},
)
.show_files_listing(),
)
.service(fs::Files::new("/api/docs", "./target/doc").show_files_listing())
.service(crate::api::auth::callback_request)
.service(crate::api::auth::logout)
.service(crate::api::boards::get_posts_request)
.service(crate::api::boards::get_post_request)
.service(crate::api::boards::create_request)
.service(crate::api::boards::create_post_request)
.service(crate::api::boards::update_post_request)
.service(crate::api::boards::update_post_tags_request)
.service(crate::api::boards::metadata_request)
.service(crate::api::boards::pin_post_request)
.service(crate::api::boards::delete_post_request)
.service(crate::api::boards::delete_board_request)
.service(crate::pages::home::home_request)
.service(crate::pages::boards::dashboard_request)
.service(crate::pages::boards::new_request)
.service(crate::pages::boards::view_board_post_request)
.service(crate::pages::boards::board_settings_request)
.service(crate::pages::boards::create_board_post_request)
.service(crate::pages::boards::view_board_request)
})
.bind(("0.0.0.0", port))?
.run()
.await
}