dsx/dsx_server repo system first implementation

This commit is contained in:
2026-02-25 14:52:04 +00:00
parent ba4ced6433
commit 0d54b319f1
28 changed files with 1196 additions and 378 deletions
+145
View File
@@ -0,0 +1,145 @@
use std::{fs, path::Path};
use dsx_common::config::DsxConfig;
use rocket_dyn_templates::{Template, context};
use serde::Serialize;
use crate::{
error::ApiError,
model::{DATA_DIR, PackageHandle},
};
// Search for a package
#[get("/?<q>")]
pub fn search_packages(q: Option<String>) -> Result<Template, ApiError> {
#[derive(Serialize)]
struct Package {
name: String,
description: String,
updated_at: String,
}
let mut packages = Vec::new();
let dir = match fs::read_dir(DATA_DIR.join("repos")) {
Ok(dir) => dir,
Err(e) => {
warn!("failed to read repos directory: {}", e);
return Err(ApiError::InternalServerError(()));
}
};
for entry in dir {
let entry = entry.map_err(|e| {
warn!("failed to read entry: {}", e);
ApiError::InternalServerError(())
})?;
let config_path = entry.path().join("repo").join("Dsx.toml");
if config_path.exists() {
let text = fs::read_to_string(&config_path).map_err(|e| {
warn!("failed to read config file: {}", e);
ApiError::InternalServerError(())
})?;
let config: DsxConfig = toml::from_str(&text).map_err(|e| {
warn!("failed to parse config file: {}", e);
ApiError::InternalServerError(())
})?;
error!("{}", config.description.clone().unwrap_or_default());
// skip repo if it doesnt match query params
if let Some(query) = &q
&& !(config.name.contains(query)
|| config
.description
.clone()
.unwrap_or_default()
.contains(query))
{
continue;
}
packages.push(Package {
name: config.name,
description: config.description.unwrap_or_default(),
updated_at: String::from("0:00"),
})
}
}
Ok(Template::render(
"packages",
context! {
packages,
query: q.clone().unwrap_or_default()
},
))
}
// Main page for a repository, shows status, files, name etc.
#[get("/<id>")]
pub fn package_main(id: &str) -> Result<Template, ApiError> {
// get package info
let mut handle = PackageHandle::new(id);
let meta = handle.get_meta()?;
let config = handle.get_config()?;
let files = handle.file_tree("")?;
let parent_path: Option<String> = None;
let current_path: Option<String> = None;
Ok(Template::render(
"package_home",
context! {
parent_path,
current_path,
meta: meta,
config: config,
files: files,
},
))
}
// Path for a file within a repo
#[get("/<id>/~repo/<path..>", rank = 1)]
pub fn repo_file(id: &str, path: std::path::PathBuf) -> Result<Template, ApiError> {
// get package info
let mut handle = PackageHandle::new(id);
let meta = handle.get_meta()?;
let config = handle.get_config()?;
let files = handle.file_tree(&path)?;
let parent_path = path.parent().unwrap_or(Path::new(""));
let current_path = &path;
Ok(Template::render(
"package_home",
context! {
parent_path,
current_path,
meta: meta,
config: config,
files: files,
},
))
}
// Search within a package's files
#[get("/<name>/~repo?<q>", rank = 2)]
pub fn search_repo_files(name: &str, q: Option<String>) -> String {
format!("Search within {} for {:?}", name, q)
}
// Page listing repo artifacts by date
#[get("/<name>/artifacts")]
pub fn list_artifacts(name: &str) -> String {
format!("Artifacts for package {}", name)
}
// Page for a specific artifact and status/logs
#[get("/<name>/artifacts/<id>")]
pub fn artifact_detail(name: &str, id: u64) -> String {
format!("Artifact {} details for package {}", id, name)
}