From fde413d6f6c7e9549c7ea932b9e06b37d5dc19f1 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sat, 6 Jul 2024 22:06:09 +0200 Subject: [PATCH] feat: use pretty package filenames parsed using regex --- Cargo.lock | 5 ++-- server/Cargo.toml | 1 + server/src/db/query/package.rs | 10 ++++---- server/src/main.rs | 3 +++ server/src/repo/archive.rs | 6 ++++- server/src/repo/package.rs | 7 ------ server/src/web/repo.rs | 46 ++++++++++++++++++++++------------ 7 files changed, 47 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8520e63..bd0c194 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1670,9 +1670,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1732,6 +1732,7 @@ dependencies = [ "futures", "http-body-util", "libarchive", + "regex", "sea-orm", "sea-orm-migration", "sea-query", diff --git a/server/Cargo.toml b/server/Cargo.toml index b1fc688..5c26303 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -14,6 +14,7 @@ figment = { version = "0.10.19", features = ["env", "toml"] } futures = "0.3.28" http-body-util = "0.1.1" libarchive = { path = "../libarchive" } +regex = "1.10.5" sea-orm-migration = "0.12.1" sea-query = { version = "0.30.7", features = ["backend-postgres", "backend-sqlite"] } serde = { version = "1.0.178", features = ["derive"] } diff --git a/server/src/db/query/package.rs b/server/src/db/query/package.rs index 9a8be5f..8a4f054 100644 --- a/server/src/db/query/package.rs +++ b/server/src/db/query/package.rs @@ -60,17 +60,17 @@ pub async fn by_id(conn: &DbConn, id: i32) -> Result> { pub async fn by_fields( conn: &DbConn, repo_id: i32, - arch: &str, name: &str, - version: Option<&str>, - compression: Option<&str>, + version: &str, + arch: &str, + compression: &str, ) -> Result> { let cond = Condition::all() .add(package::Column::RepoId.eq(repo_id)) .add(package::Column::Name.eq(name)) .add(package::Column::Arch.eq(arch)) - .add_option(version.map(|version| package::Column::Version.eq(version))) - .add_option(compression.map(|compression| package::Column::Compression.eq(compression))); + .add(package::Column::Version.eq(version)) + .add(package::Column::Compression.eq(compression)); Package::find().filter(cond).one(conn).await } diff --git a/server/src/main.rs b/server/src/main.rs index cb66668..c641666 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -17,12 +17,14 @@ use tokio::runtime; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; pub const ANY_ARCH: &'static str = "any"; +pub const PKG_FILENAME_REGEX: &'static str = "^([a-z0-9@._+-]+)-((?:[0-9]+:)?[a-zA-Z0-9@._+]+-[0-9]+)-([a-zA-z0-9_]+).pkg.tar.([a-zA-Z0-9]+)$"; #[derive(Clone)] pub struct Global { config: crate::config::Config, repo: repo::Handle, db: sea_orm::DbConn, + pkg_filename_re: regex::Regex, } fn main() -> crate::Result<()> { @@ -79,6 +81,7 @@ fn setup(rt: &runtime::Handle, config_file: PathBuf) -> crate::Result { config: config.clone(), repo, db, + pkg_filename_re: regex::Regex::new(PKG_FILENAME_REGEX).unwrap(), }) } diff --git a/server/src/repo/archive.rs b/server/src/repo/archive.rs index ad08a67..2844b90 100644 --- a/server/src/repo/archive.rs +++ b/server/src/repo/archive.rs @@ -124,7 +124,11 @@ impl RepoArchivesWriter { fn write_desc(&self, path: impl AsRef, pkg: &db::package::Model) -> crate::Result<()> { let mut f = std::io::BufWriter::new(std::fs::File::create(path)?); - writeln!(f, "%FILENAME%\n{}", pkg.id)?; + let filename = format!( + "{}-{}-{}.pkg.tar.{}", + pkg.name, pkg.version, pkg.arch, pkg.compression + ); + writeln!(f, "%FILENAME%\n{}", filename)?; let mut write_attr = |k: &str, v: &str| { if !v.is_empty() { diff --git a/server/src/repo/package.rs b/server/src/repo/package.rs index 996f933..e8bb076 100644 --- a/server/src/repo/package.rs +++ b/server/src/repo/package.rs @@ -222,10 +222,3 @@ impl From for package::ActiveModel { } } } - -pub fn filename(pkg: &package::Model) -> String { - format!( - "{}-{}-{}.pkg.tar.{}", - pkg.name, pkg.version, pkg.arch, pkg.compression - ) -} diff --git a/server/src/web/repo.rs b/server/src/web/repo.rs index d690895..c3bfe6b 100644 --- a/server/src/web/repo.rs +++ b/server/src/web/repo.rs @@ -1,4 +1,4 @@ -use crate::FsConfig; +use crate::{db, FsConfig}; use axum::{ body::Body, @@ -44,23 +44,37 @@ async fn get_file( req: Request, ) -> crate::Result { if let Some(repo_id) = global.repo.get_repo(&distro, &repo).await? { + let file_name = + if file_name == format!("{}.db", repo) || file_name == format!("{}.db.tar.gz", repo) { + format!("{}.db.tar.gz", arch) + } else if file_name == format!("{}.files", repo) + || file_name == format!("{}.files.tar.gz", repo) + { + format!("{}.files.tar.gz", arch) + } else if let Some(m) = global.pkg_filename_re.captures(&file_name) { + // SAFETY: these unwraps cannot fail if the RegEx matched successfully + db::query::package::by_fields( + &global.db, + repo_id, + m.get(1).unwrap().as_str(), + m.get(2).unwrap().as_str(), + m.get(3).unwrap().as_str(), + m.get(4).unwrap().as_str(), + ) + .await? + .ok_or(StatusCode::NOT_FOUND)? + .id + .to_string() + } else { + return Err(StatusCode::NOT_FOUND.into()); + }; + match global.config.fs { FsConfig::Local { data_dir } => { - let repo_dir = data_dir.join("repos").join(repo_id.to_string()); - - let file_name = if file_name == format!("{}.db", repo) - || file_name == format!("{}.db.tar.gz", repo) - { - format!("{}.db.tar.gz", arch) - } else if file_name == format!("{}.files", repo) - || file_name == format!("{}.files.tar.gz", repo) - { - format!("{}.files.tar.gz", arch) - } else { - file_name - }; - - let path = repo_dir.join(file_name); + let path = data_dir + .join("repos") + .join(repo_id.to_string()) + .join(file_name); Ok(ServeFile::new(path).oneshot(req).await) } }