feat: use pretty package filenames parsed using regex

pull/11/head
Jef Roosens 2024-07-06 22:06:09 +02:00
parent 86ab143271
commit fde413d6f6
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
7 changed files with 47 additions and 31 deletions

5
Cargo.lock generated
View File

@ -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",

View File

@ -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"] }

View File

@ -60,17 +60,17 @@ pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<package::Model>> {
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<Option<package::Model>> {
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
}

View File

@ -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<Global> {
config: config.clone(),
repo,
db,
pkg_filename_re: regex::Regex::new(PKG_FILENAME_REGEX).unwrap(),
})
}

View File

@ -124,7 +124,11 @@ impl RepoArchivesWriter {
fn write_desc(&self, path: impl AsRef<Path>, 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() {

View File

@ -222,10 +222,3 @@ impl From<Package> for package::ActiveModel {
}
}
}
pub fn filename(pkg: &package::Model) -> String {
format!(
"{}-{}-{}.pkg.tar.{}",
pkg.name, pkg.version, pkg.arch, pkg.compression
)
}

View File

@ -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<Body>,
) -> crate::Result<impl IntoResponse> {
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)
}
}