diff --git a/src/cli.rs b/src/cli.rs index 4dfe224..63bf2e8 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -55,7 +55,10 @@ pub struct BuildCommand { /// output directory pub out: Option, - #[argh(option, default = r#"String::from("git.hydrar.de/navos/navos:latest")"#)] + #[argh( + option, + default = r#"String::from("git.hydrar.de/navos/navos:latest")"# + )] /// docker build image pub image: String, } diff --git a/src/main.rs b/src/main.rs index e33466f..bba0c79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,7 +70,9 @@ async fn launch(config: String) { routes::user::new_api_key, routes::user::end_session, routes::user::change_password, - routes::user::change_password_post + routes::user::change_password_post, + routes::ui::repo::repo_arch_json, + routes::ui::pkg::pkg_json ], ) .manage(config) diff --git a/src/pkg/arch.rs b/src/pkg/arch.rs index 1bd7f68..7accc83 100644 --- a/src/pkg/arch.rs +++ b/src/pkg/arch.rs @@ -1,4 +1,6 @@ #![allow(non_camel_case_types)] + +use serde::Serialize; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Architecture { x86_64, @@ -6,6 +8,15 @@ pub enum Architecture { any, } +impl Serialize for Architecture { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + impl Architecture { pub fn parse(val: &str) -> Option { match val { diff --git a/src/pkg/package.rs b/src/pkg/package.rs index 9f96912..f227908 100644 --- a/src/pkg/package.rs +++ b/src/pkg/package.rs @@ -5,6 +5,7 @@ use std::{ }; use based::get_pg; +use serde::Serialize; use sqlx::FromRow; use super::{Repository, arch::Architecture}; @@ -684,7 +685,7 @@ impl Compression { } } -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize)] pub struct PackageInfo { /// Architecture pub architectures: Vec, @@ -713,7 +714,7 @@ pub struct PackageInfo { /// Dependencies pub dependencies: Vec, /// Optional Dependencies - pub opt_depends: Vec, + pub optdepends: Vec, /// Provides pub provides: Vec, // Replaces @@ -721,14 +722,14 @@ pub struct PackageInfo { /// Backup pub backup: Vec, /// Conflicts - pub conflict: Vec, + pub conflicts: Vec, /// Check Dependencies - pub check_depends: Vec, + pub checkdepends: Vec, /// Groups pub groups: Vec, } -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize)] pub struct OptionalDependency { pub pkg: String, pub reason: Option, @@ -815,7 +816,7 @@ impl PackageInfo { (pkg, None) }; - info.opt_depends.push(OptionalDependency { + info.optdepends.push(OptionalDependency { pkg: pkg.to_string(), reason: reason, }); @@ -842,13 +843,13 @@ impl PackageInfo { "conflict" => { let conflicts: Vec<_> = val.split(';').collect(); for e in conflicts { - info.conflict.push(e.to_string()); + info.conflicts.push(e.to_string()); } } "checkdepend" => { let pkgs: Vec<_> = val.split(';').collect(); for pkg in pkgs { - info.check_depends.push(pkg.to_string()); + info.checkdepends.push(pkg.to_string()); } } "group" => { @@ -907,11 +908,11 @@ impl PackageInfo { PKGBUILD.push_str(&PackageInfo::gen_array("makedepends", &self.makedepends)); PKGBUILD.push_str(&PackageInfo::gen_array("depends", &self.dependencies)); - PKGBUILD.push_str(&PackageInfo::gen_array("checkdepends", &self.check_depends)); + PKGBUILD.push_str(&PackageInfo::gen_array("checkdepends", &self.checkdepends)); PKGBUILD.push_str(&PackageInfo::gen_array( "optdepends", &self - .opt_depends + .optdepends .iter() .map(|x| x.as_str()) .collect::>(), @@ -927,7 +928,7 @@ impl PackageInfo { PKGBUILD.push_str(&PackageInfo::gen_array("backup", &self.backup)); - PKGBUILD.push_str(&PackageInfo::gen_array("conflicts", &self.conflict)); + PKGBUILD.push_str(&PackageInfo::gen_array("conflicts", &self.conflicts)); PKGBUILD.push_str(&PackageInfo::gen_array("groups", &self.groups)); diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 9580aef..770adcc 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -18,6 +18,7 @@ pub mod push; pub mod ui; pub mod user; +/// Main Index Route : Overview of repositories #[get("/")] pub async fn index_page( ctx: RequestContext, @@ -64,6 +65,7 @@ pub async fn index_page( shell.render_page(content, "Repositories", ctx).await } +/// Download endpoint for package downloads and `pacman` #[get("/pkg///")] pub async fn pkg_route( repo: &str, diff --git a/src/routes/push.rs b/src/routes/push.rs index 08174da..180e119 100644 --- a/src/routes/push.rs +++ b/src/routes/push.rs @@ -32,6 +32,7 @@ pub async fn tmp_file_to_vec<'r>(tmp: &TempFile<'r>) -> Vec { buf } +/// Upload route for pushing a package #[post("/pkg//upload", data = "")] pub async fn upload_pkg( repo: &str, diff --git a/src/routes/ui/pkg.rs b/src/routes/ui/pkg.rs index f2f597c..9b200f3 100644 --- a/src/routes/ui/pkg.rs +++ b/src/routes/ui/pkg.rs @@ -9,9 +9,32 @@ use pacco::pkg::package::PackageMetaInfo; use rocket::{State, get}; use pacco::pkg::{Package, Repository, arch::Architecture, find_package_by_name}; +use serde_json::json; use super::take_out; +/// Package API Endpoint +#[get("///json")] +pub async fn pkg_json(repo: &str, pkg_name: &str) -> serde_json::Value { + let repository = Repository::new(repo).unwrap(); + let pkg = repository.get_pkg_by_name(pkg_name).unwrap(); + + let versions = pkg.versions(); + let version = pkg.version.clone(); + let arch = pkg.arch(); + let pkginfo = pkg.pkginfo(); + + json!({ + "repo": repo, + "pkg": pkg_name, + "versions": versions, + "version": version, + "arch": arch.iter().map(|x| x.to_string()).collect::>(), + "info": pkginfo + }) +} + +/// Package overview UI #[get("//?")] pub async fn pkg_ui( repo: &str, diff --git a/src/routes/ui/repo.rs b/src/routes/ui/repo.rs index 5e1a344..d73190d 100644 --- a/src/routes/ui/repo.rs +++ b/src/routes/ui/repo.rs @@ -6,10 +6,33 @@ use pacco::pkg::package::PackageMetaInfo; use rocket::{State, get}; use pacco::pkg::{Repository, arch::Architecture}; +use serde_json::json; use crate::routes::ui::arch_card; use pacco::config::Config; +/// Repository API Endpoint +#[get("///json")] +pub async fn repo_arch_json( + repo: &str, + ctx: RequestContext, + arch: &str, + config: &State, +) -> serde_json::Value { + let arch = Architecture::parse(arch).unwrap_or(Architecture::any); + let repo_name = repo; + + let repo = Repository::new(repo_name).unwrap(); + let packages = repo.list_pkg_arch(arch.clone()); + + json!({ + "repo": repo_name, + "arch": arch.to_string(), + "packages": packages + }) +} + +/// Repository Overview UI #[get("/?&")] pub async fn repo_ui( repo: &str,