feat: use pretty package filenames parsed using regex
parent
86ab143271
commit
fde413d6f6
|
@ -1670,9 +1670,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.4"
|
version = "1.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -1732,6 +1732,7 @@ dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"libarchive",
|
"libarchive",
|
||||||
|
"regex",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
"sea-orm-migration",
|
"sea-orm-migration",
|
||||||
"sea-query",
|
"sea-query",
|
||||||
|
|
|
@ -14,6 +14,7 @@ figment = { version = "0.10.19", features = ["env", "toml"] }
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
http-body-util = "0.1.1"
|
http-body-util = "0.1.1"
|
||||||
libarchive = { path = "../libarchive" }
|
libarchive = { path = "../libarchive" }
|
||||||
|
regex = "1.10.5"
|
||||||
sea-orm-migration = "0.12.1"
|
sea-orm-migration = "0.12.1"
|
||||||
sea-query = { version = "0.30.7", features = ["backend-postgres", "backend-sqlite"] }
|
sea-query = { version = "0.30.7", features = ["backend-postgres", "backend-sqlite"] }
|
||||||
serde = { version = "1.0.178", features = ["derive"] }
|
serde = { version = "1.0.178", features = ["derive"] }
|
||||||
|
|
|
@ -60,17 +60,17 @@ pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<package::Model>> {
|
||||||
pub async fn by_fields(
|
pub async fn by_fields(
|
||||||
conn: &DbConn,
|
conn: &DbConn,
|
||||||
repo_id: i32,
|
repo_id: i32,
|
||||||
arch: &str,
|
|
||||||
name: &str,
|
name: &str,
|
||||||
version: Option<&str>,
|
version: &str,
|
||||||
compression: Option<&str>,
|
arch: &str,
|
||||||
|
compression: &str,
|
||||||
) -> Result<Option<package::Model>> {
|
) -> Result<Option<package::Model>> {
|
||||||
let cond = Condition::all()
|
let cond = Condition::all()
|
||||||
.add(package::Column::RepoId.eq(repo_id))
|
.add(package::Column::RepoId.eq(repo_id))
|
||||||
.add(package::Column::Name.eq(name))
|
.add(package::Column::Name.eq(name))
|
||||||
.add(package::Column::Arch.eq(arch))
|
.add(package::Column::Arch.eq(arch))
|
||||||
.add_option(version.map(|version| package::Column::Version.eq(version)))
|
.add(package::Column::Version.eq(version))
|
||||||
.add_option(compression.map(|compression| package::Column::Compression.eq(compression)));
|
.add(package::Column::Compression.eq(compression));
|
||||||
|
|
||||||
Package::find().filter(cond).one(conn).await
|
Package::find().filter(cond).one(conn).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,14 @@ use tokio::runtime;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
pub const ANY_ARCH: &'static str = "any";
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct Global {
|
pub struct Global {
|
||||||
config: crate::config::Config,
|
config: crate::config::Config,
|
||||||
repo: repo::Handle,
|
repo: repo::Handle,
|
||||||
db: sea_orm::DbConn,
|
db: sea_orm::DbConn,
|
||||||
|
pkg_filename_re: regex::Regex,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> crate::Result<()> {
|
fn main() -> crate::Result<()> {
|
||||||
|
@ -79,6 +81,7 @@ fn setup(rt: &runtime::Handle, config_file: PathBuf) -> crate::Result<Global> {
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
repo,
|
repo,
|
||||||
db,
|
db,
|
||||||
|
pkg_filename_re: regex::Regex::new(PKG_FILENAME_REGEX).unwrap(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,11 @@ impl RepoArchivesWriter {
|
||||||
fn write_desc(&self, path: impl AsRef<Path>, pkg: &db::package::Model) -> crate::Result<()> {
|
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)?);
|
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| {
|
let mut write_attr = |k: &str, v: &str| {
|
||||||
if !v.is_empty() {
|
if !v.is_empty() {
|
||||||
|
|
|
@ -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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::FsConfig;
|
use crate::{db, FsConfig};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body,
|
body::Body,
|
||||||
|
@ -44,23 +44,37 @@ async fn get_file(
|
||||||
req: Request<Body>,
|
req: Request<Body>,
|
||||||
) -> crate::Result<impl IntoResponse> {
|
) -> crate::Result<impl IntoResponse> {
|
||||||
if let Some(repo_id) = global.repo.get_repo(&distro, &repo).await? {
|
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 {
|
match global.config.fs {
|
||||||
FsConfig::Local { data_dir } => {
|
FsConfig::Local { data_dir } => {
|
||||||
let repo_dir = data_dir.join("repos").join(repo_id.to_string());
|
let path = data_dir
|
||||||
|
.join("repos")
|
||||||
let file_name = if file_name == format!("{}.db", repo)
|
.join(repo_id.to_string())
|
||||||
|| file_name == format!("{}.db.tar.gz", repo)
|
.join(file_name);
|
||||||
{
|
|
||||||
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);
|
|
||||||
Ok(ServeFile::new(path).oneshot(req).await)
|
Ok(ServeFile::new(path).oneshot(req).await)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue