pinakes: import in parallel; various UI improvements

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I1eb47cd79cd4145c56af966f6756fe1d6a6a6964
This commit is contained in:
raf 2026-02-03 10:31:20 +03:00
commit 116fe7b059
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
42 changed files with 4316 additions and 316 deletions

View file

@ -2,6 +2,9 @@ use std::path::PathBuf;
use std::sync::Arc;
use anyhow::Result;
use axum::Router;
use axum::response::Redirect;
use axum::routing::any;
use clap::Parser;
use tokio::sync::RwLock;
use tracing::info;
@ -202,6 +205,7 @@ async fn main() -> Result<()> {
scanning: false,
files_found: total_found,
files_processed: total_processed,
files_skipped: 0,
errors: all_errors,
}
})
@ -459,7 +463,7 @@ async fn main() -> Result<()> {
let state = AppState {
storage: storage.clone(),
config: config_arc,
config: config_arc.clone(),
config_path: Some(config_path),
scan_progress: pinakes_core::scan::ScanProgress::new(),
sessions: Arc::new(RwLock::new(std::collections::HashMap::new())),
@ -489,23 +493,124 @@ async fn main() -> Result<()> {
});
}
let router = app::create_router(state);
let config_read = config_arc.read().await;
let tls_config = config_read.server.tls.clone();
drop(config_read);
info!(addr = %addr, "server listening");
let listener = tokio::net::TcpListener::bind(&addr).await?;
// Create router with TLS config for HSTS headers
let router = if tls_config.enabled {
app::create_router_with_tls(state, Some(&tls_config))
} else {
app::create_router(state)
};
axum::serve(
listener,
router.into_make_service_with_connect_info::<std::net::SocketAddr>(),
)
.with_graceful_shutdown(shutdown_signal())
.await?;
if tls_config.enabled {
// TLS/HTTPS mode
let cert_path = tls_config
.cert_path
.as_ref()
.ok_or_else(|| anyhow::anyhow!("TLS enabled but cert_path not specified"))?;
let key_path = tls_config
.key_path
.as_ref()
.ok_or_else(|| anyhow::anyhow!("TLS enabled but key_path not specified"))?;
info!(addr = %addr, cert = %cert_path.display(), "server listening with TLS");
// Configure TLS
let tls_config_builder =
axum_server::tls_rustls::RustlsConfig::from_pem_file(cert_path, key_path).await?;
// Start HTTP redirect server if configured
if tls_config.redirect_http {
let http_addr = format!(
"{}:{}",
config_arc.read().await.server.host,
tls_config.http_port
);
let https_port = config_arc.read().await.server.port;
let https_host = config_arc.read().await.server.host.clone();
let redirect_router = create_https_redirect_router(https_host, https_port);
let shutdown = shutdown_token.clone();
tokio::spawn(async move {
let listener = match tokio::net::TcpListener::bind(&http_addr).await {
Ok(l) => l,
Err(e) => {
tracing::warn!(error = %e, addr = %http_addr, "failed to bind HTTP redirect listener");
return;
}
};
info!(addr = %http_addr, "HTTP redirect server listening");
let server = axum::serve(
listener,
redirect_router.into_make_service_with_connect_info::<std::net::SocketAddr>(),
);
tokio::select! {
result = server => {
if let Err(e) = result {
tracing::warn!(error = %e, "HTTP redirect server error");
}
}
_ = shutdown.cancelled() => {
info!("HTTP redirect server shutting down");
}
}
});
}
// Start HTTPS server with graceful shutdown via Handle
let addr_parsed: std::net::SocketAddr = addr.parse()?;
let handle = axum_server::Handle::new();
let shutdown_handle = handle.clone();
// Spawn a task to trigger graceful shutdown
tokio::spawn(async move {
shutdown_signal().await;
shutdown_handle.graceful_shutdown(Some(std::time::Duration::from_secs(30)));
});
axum_server::bind_rustls(addr_parsed, tls_config_builder)
.handle(handle)
.serve(router.into_make_service_with_connect_info::<std::net::SocketAddr>())
.await?;
} else {
// Plain HTTP mode
info!(addr = %addr, "server listening");
let listener = tokio::net::TcpListener::bind(&addr).await?;
axum::serve(
listener,
router.into_make_service_with_connect_info::<std::net::SocketAddr>(),
)
.with_graceful_shutdown(shutdown_signal())
.await?;
}
shutdown_token.cancel();
info!("server shut down");
Ok(())
}
/// Create a router that redirects all HTTP requests to HTTPS
fn create_https_redirect_router(https_host: String, https_port: u16) -> Router {
Router::new().fallback(any(move |uri: axum::http::Uri| {
let https_host = https_host.clone();
async move {
let path_and_query = uri.path_and_query().map(|pq| pq.as_str()).unwrap_or("/");
let https_url = if https_port == 443 {
format!("https://{}{}", https_host, path_and_query)
} else {
format!("https://{}:{}{}", https_host, https_port, path_and_query)
};
Redirect::permanent(&https_url)
}
}))
}
async fn shutdown_signal() {
let ctrl_c = async {
match tokio::signal::ctrl_c().await {