Files
AstralRinth/src/main.rs
Aeledfyr 95339a8338 Create a mock file host for dev, Fix mod creation route (#38)
* fix(mod-creation): fix actix server data & mod creation route

* feat(file-host): implement mock file hosting

This implements a mock file hosting system backed by the system's
filesystem.  It mirrors the API of the backblaze integration, but
puts the files directly on disk in the path specified by the
MOCK_FILE_PATH environment variable (defaults to /tmp/modrinth).

The mock file hosting is enabled by default using cargo features
to allow people to work on modrinth without access to a valid
backblaze account and setup.  To enable backblaze, specify the
cargo feature "backblaze" when running, ex. `cargo run --features
backblaze`.

* feat(file-hosting): implement basic backblaze API error handling

* fix(mod-creation): fix extension parsing, use base62 ids for paths
fix(file-hosting): reduce unnecessary allocations

* fix: fix auth with docker mongodb

* fix: fix failing checks

* fix: remove testing files
2020-07-16 21:06:58 -07:00

104 lines
3.0 KiB
Rust

use crate::search::indexing::index_mods;
use actix_web::middleware::Logger;
use actix_web::{web, App, HttpServer};
use env_logger::Env;
use log::info;
use std::env;
use std::fs::File;
mod database;
mod file_hosting;
mod models;
mod routes;
mod search;
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
env_logger::from_env(Env::default().default_filter_or("info")).init();
dotenv::dotenv().ok();
check_env_vars();
//Database Connecter
let client = database::connect()
.await
.expect("Database connection failed");
let client_ref = client.clone();
//File Hosting Initializer
let authorization_data = file_hosting::authorize_account(
dotenv::var("BACKBLAZE_KEY_ID").unwrap(),
dotenv::var("BACKBLAZE_KEY").unwrap(),
)
.await
.unwrap();
let upload_url_data = file_hosting::get_upload_url(
authorization_data.clone(),
dotenv::var("BACKBLAZE_BUCKET_ID").unwrap(),
)
.await
.unwrap();
// Get executable path
let mut exe_path = env::current_exe()?.parent().unwrap().to_path_buf();
// Create the path to the index lock file
exe_path.push("index.v1.lock");
//Indexing mods if not already done
if env::args().any(|x| x == "regen") {
// User forced regen of indexing
info!("Forced regeneration of indexes!");
index_mods(client).await.expect("Mod indexing failed");
} else if !exe_path.exists() {
// The indexes were not created, or the version was upgraded
info!("Indexing of mods for first time...");
index_mods(client).await.expect("Mod indexing failed");
// Create the lock file
File::create(exe_path)?;
}
info!("Starting Actix HTTP server!");
//Init App
HttpServer::new(move || {
App::new()
.wrap(Logger::default())
.wrap(Logger::new("%a %{User-Agent}i"))
.data(client_ref.clone())
.data(authorization_data.clone())
.data(upload_url_data.clone())
.service(routes::index_get)
.service(routes::mod_search)
.service(routes::mod_create)
.default_service(web::get().to(routes::not_found))
})
.bind(dotenv::var("BIND_ADDR").unwrap())?
.run()
.await
}
// This is so that env vars not used immediately don't panic at runtime
fn check_env_vars() {
fn check_var<T: std::str::FromStr>(var: &str) {
if dotenv::var(var)
.ok()
.and_then(|s| s.parse::<T>().ok())
.is_none()
{
log::warn!(
"Variable `{}` missing in dotenv or not of type `{}`",
var,
std::any::type_name::<T>()
)
}
}
check_var::<bool>("INDEX_CURSEFORGE");
check_var::<String>("MONGODB_ADDR");
check_var::<String>("MEILISEARCH_ADDR");
check_var::<String>("BIND_ADDR");
check_var::<String>("BACKBLAZE_KEY_ID");
check_var::<String>("BACKBLAZE_KEY");
check_var::<String>("BACKBLAZE_BUCKET_ID");
}