Compare commits

...

1 commit

Author SHA1 Message Date
1c52be1fe6 config: static settings reference in appstate 2025-02-04 04:32:06 -08:00
6 changed files with 25 additions and 44 deletions

View file

@ -11,26 +11,4 @@ pub use router::*;
pub use state::*;
pub use views::*;
use std::{path::PathBuf, sync::LazyLock};
pub static CARGO_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION"));
pub static CACHE_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
std::env::var("NZ_CACHE_DIR")
.ok()
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("/var/lib/nyazoom/cache"))
});
pub static DIST_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
std::env::var("NZ_DIST_DIR")
.ok()
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("./dist"))
});
// This could utilize and env var like the others, but for now i have chosen to ignore it
//
// pros: would match dev environment and sqlx-cli better
// cons: don't feel like it right now
//
// FIXME: better errors here
pub static DB_URL: LazyLock<String> =
LazyLock::new(|| format!("sqlite://{}", CACHE_DIR.join("data").to_str().unwrap()));

View file

@ -9,21 +9,26 @@ use axum_extra::TypedHeader;
use tower_http::{services::ServeDir, trace::TraceLayer};
use views::templates::WelcomeTemplate;
use std::net::SocketAddr;
use std::{net::SocketAddr, sync::OnceLock};
use nyazoom::*;
use nyazoom::{config::Settings, *};
use util::{headers::ForwardedFor, logging, sweeper};
#[tokio::main]
async fn main() -> color_eyre::Result<()> {
async fn main() -> eyre::Result<()> {
color_eyre::install()?;
logging::init_tracing();
// uses create_dir_all to create both .cache and serve inside it in one go
util::make_dir(&*CACHE_DIR).await?;
let config = Settings::try_new()?;
tracing::info!(?config, "config generated");
let state = AppState::new();
// uses create_dir_all to create both .cache and serve inside it in one go
util::make_dir(&config.cache.dir).await?;
let fallback_service = ServeDir::new(&config.dist.dir);
let state = AppState::new_with_settings(config);
sweeper::spawn(state.clone());
@ -35,7 +40,7 @@ async fn main() -> color_eyre::Result<()> {
.nest("/records", get_records_router())
.nest("/link", get_link_router())
.with_state(state)
.fallback_service(ServeDir::new(&*DIST_DIR))
.fallback_service(fallback_service)
.layer(TraceLayer::new_for_http())
.layer(middleware::from_fn(log_source));

View file

@ -8,7 +8,7 @@ use axum::{
use reqwest::StatusCode;
use tokio_util::io::ReaderStream;
use crate::{AppState, CACHE_DIR};
use crate::AppState;
pub fn get_download_router() -> Router<AppState> {
Router::new().route("/:id", get(download))
@ -29,7 +29,7 @@ async fn download(
drop(conn);
if rows_affected > 0 {
let file = tokio::fs::File::open(CACHE_DIR.join(id))
let file = tokio::fs::File::open(state.settings.cache.dir.join(id))
.await
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))?;

View file

@ -30,7 +30,7 @@ async fn upload_to_zip(
) -> Result<Response, (StatusCode, String)> {
let cache_name = util::get_random_name(10);
let archive_path = crate::CACHE_DIR.join(&cache_name);
let archive_path = state.settings.cache.dir.join(&cache_name);
tracing::debug!("Zipping: {:?}", &archive_path);

View file

@ -2,25 +2,23 @@ use std::str::FromStr;
use sqlx::{sqlite::SqliteConnectOptions, SqlitePool};
use crate::DB_URL;
use crate::config::Settings;
#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct AppState {
pub settings: &'static Settings,
pub pool: SqlitePool,
}
impl AppState {
pub fn new() -> Self {
pub fn new_with_settings(settings: Settings) -> Self {
let settings = Box::leak(Box::new(settings));
Self {
pool: SqlitePool::connect_lazy_with(
SqliteConnectOptions::from_str(&DB_URL).expect("Invalid Database String"),
SqliteConnectOptions::from_str(&settings.database.url)
.expect("Invalid Database String"),
),
settings,
}
}
}
impl Default for AppState {
fn default() -> Self {
Self::new()
}
}

View file

@ -3,7 +3,7 @@ use std::time::Duration;
use sqlx::{sqlite::SqliteQueryResult, SqliteConnection};
use tracing::{info_span, Instrument};
use crate::{db::ExpiredRecord, state::AppState, CACHE_DIR};
use crate::{db::ExpiredRecord, state::AppState};
/// Spawn a repeating task that will clean files periodically
pub fn spawn(state: AppState) {
@ -34,7 +34,7 @@ pub fn spawn(state: AppState) {
let mut too_old = 0;
let mut out_of_downloads = 0;
for record in expired_records.iter() {
let cache_path = CACHE_DIR.join(&record.cache_name);
let cache_path = state.settings.cache.dir.join(&record.cache_name);
if let Err(error) = std::fs::remove_file(&cache_path) {
if error.kind() == std::io::ErrorKind::NotFound {