From 7620dd41ca41cf4fb445d6a6e9afe2607ed77a95 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Thu, 22 Apr 2021 06:44:04 -0600 Subject: actually handle subfolders --- src/main.rs | 64 ++++++++++++++++++++++++++++++++-------------- src/templates.rs | 17 +++++++----- templates/about.html | 13 ---------- templates/repo_folder.html | 33 ++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 38 deletions(-) delete mode 100644 templates/about.html create mode 100644 templates/repo_folder.html diff --git a/src/main.rs b/src/main.rs index 0710d40..333a4bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,8 +34,8 @@ async fn main() -> Result<()> { app.at("/").get(index); { let mut repo = app.at("/*repo/"); - repo.get(about); - repo.at("tree/").get(|_| async { Ok("bruh tree") }); + repo.get(repo_index); + repo.at("tree/*path").get(repo_tree_path); } app.listen(("127.0.0.1", port)).await?; Ok(()) @@ -49,9 +49,22 @@ async fn index(req: Request) -> tide::Result { Ok(templates::Index { state: state.deref() }.into()) } -async fn about(req: Request) -> tide::Result { +async fn repo_index(req: Request) -> tide::Result { + let state = req.state(); let repo_rel_path = req.param("repo").expect("no repo in repo-based URL?"); + + view_tree_path(state, repo_rel_path, "").await +} + +async fn repo_tree_path(req: Request) -> tide::Result { let state = req.state(); + let repo_rel_path = req.param("repo").expect("no repo in repo-based URL?"); + let tree_rel_path = req.param("path").expect("no path in path-based URL?"); + + view_tree_path(state, repo_rel_path, tree_rel_path).await +} + +async fn view_tree_path(state: &Arc>, repo_rel_path: &str, tree_rel_path: &str) -> tide::Result { let state = state.lock_arc().await; let repo = state.data.iter() .find(|repo| state.relative_path(repo.path()) == Path::new(repo_rel_path)); @@ -72,24 +85,37 @@ async fn about(req: Request) -> tide::Result { Err(err) => return Ok(format!("bruh that repo's HEAD has no tree: {}", err).into()), }; - let tree_readme = head_tree.get_path(Path::new("README.md")); - let tree_readme = match tree_readme { - Ok(x) => x, - Err(err) => return Ok(format!("that repo's HEAD tree has no README.md: {}", err).into()), - }; + let selected_object = if tree_rel_path.is_empty() { + head_tree.into_object() + } else { + let selected_tree_entry = head_tree.get_path(Path::new(&tree_rel_path)); + let selected_tree_entry = match selected_tree_entry { + Ok(x) => x, + Err(err) => return Ok(format!("bruh that path doesn't exist: {}", err).into()), + }; - let tree_readme_object = tree_readme.to_object(repo); - let tree_readme_object = match tree_readme_object { - Ok(x) => x, - Err(err) => return Ok(format!("that repo's HEAD tree has no README.md: {}", err).into()), + let selected_object = selected_tree_entry.to_object(repo); + let selected_object = match selected_object { + Ok(x) => x, + Err(err) => return Ok(format!("bruh that path doesn't exist: {}", err).into()), + }; + selected_object }; - let head_readme_blob = tree_readme_object.into_blob(); - let head_readme_blob = match head_readme_blob { - Ok(x) => x, - Err(_) => return Ok("somehow that README wasn't a file".into()), - }; + let tree_rel_path = format!("/{}", tree_rel_path); - let readme = String::from_utf8_lossy(head_readme_blob.content()); - Ok(templates::About { path: repo_rel_path, readme }.into()) + if let Some(selected_tree) = selected_object.as_tree() { + let template = templates::RepoFolder { + repo, + repo_path: repo_rel_path, + title: repo_rel_path, + rel_path: &tree_rel_path, + tree: selected_tree.clone(), + }; + Ok(template.into()) + } else if let Some(selected_blob) = selected_object.as_blob() { + todo!() + } else { + panic!() + } } diff --git a/src/templates.rs b/src/templates.rs index bb285fa..257c41e 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use askama::Template; use crate::state::State; @@ -11,13 +9,20 @@ pub struct Index<'a> { } #[derive(Template)] -#[template(path = "about.html")] -pub struct About<'a> { - pub path: &'a str, - pub readme: Cow<'a, str>, +#[template(path = "repo_folder.html")] +pub struct RepoFolder<'a> { + pub repo: &'a git2::Repository, + pub repo_path: &'a str, + pub title: &'a str, + pub rel_path: &'a str, + pub tree: git2::Tree<'a>, } mod filters { + pub fn from_utf8_lossy(utf8: &[u8]) -> ::askama::Result { + Ok(String::from_utf8_lossy(utf8).into_owned()) + } + pub fn markdown(s: &str) -> ::askama::Result { use pulldown_cmark::{Parser, Options, html}; diff --git a/templates/about.html b/templates/about.html deleted file mode 100644 index 977d916..0000000 --- a/templates/about.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - {{ path }} - - -{{ readme|markdown|safe }} - - diff --git a/templates/repo_folder.html b/templates/repo_folder.html new file mode 100644 index 0000000..6f6b3a9 --- /dev/null +++ b/templates/repo_folder.html @@ -0,0 +1,33 @@ + + + + + + + {{ title }} + + +

gityeet

+

{{ rel_path }}

+{%- macro effective_name(entry) -%} + {{- entry.name().unwrap() -}} + {%- match entry.kind() -%} + {%- when Some with (x) %}{% match x %}{% when git2::ObjectType::Tree %}/{% else %}{% endmatch %} + {%- else -%} + {%- endmatch -%} +{%- endmacro -%} + +{% for entry in tree -%} +{% if entry.name().unwrap() == "README.md" -%} +{{ entry.to_object(repo).unwrap().into_blob().unwrap().content()|from_utf8_lossy|markdown|safe }} +{%- endif %} +{%- endfor %} + + -- cgit v1.2.3