146 lines
4.0 KiB
Rust
146 lines
4.0 KiB
Rust
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)
|
|
}
|