Skip to content

Commit

Permalink
Merge pull request #73 from dandi/gh-14
Browse files Browse the repository at this point in the history
Add breadcrumbs to web view
  • Loading branch information
jwodder authored Feb 14, 2024
2 parents 19da772 + 6651775 commit 4998bd8
Show file tree
Hide file tree
Showing 9 changed files with 491 additions and 228 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ In Development
- Disable log coloration when stderr is not a terminal
- Suppress noisy & irrelevant log messages from various dependencies
- Log errors that cause 404 and 500 responses
- Added breadcrumbs to HTML views of collections
- `FAST_NOT_EXIST` components are now checked for case-insensitively

v0.2.0 (2024-02-07)
-------------------
Expand Down
5 changes: 3 additions & 2 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ pub(crate) static HTML_TIMESTAMP_FORMAT: &[FormatItem<'_>] = format_description!
);

/// If a client makes a request for a resource with one of these names as a
/// component, assume it doesn't exist without checking the Archive.
/// component (case insensitive), assume it doesn't exist without bothering to
/// check the backend.
///
/// This list must be kept in sorted order; this is enforced by a test below.
pub(crate) static FAST_NOT_EXIST: &[&str] = &[".bzr", ".git", ".nols", ".svn"];
Expand All @@ -51,7 +52,7 @@ mod tests {
#[test]
fn test_fast_not_exist_is_sorted() {
assert!(FAST_NOT_EXIST.windows(2).all(|ab| {
assert!(ab.len() >= 2);
assert!(ab.len() == 2);
ab[0] < ab[1]
}));
}
Expand Down
26 changes: 26 additions & 0 deletions src/dav/html.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::util::Href;
use super::{DavCollection, DavItem, DavResource, ResourceKind};
use crate::consts::HTML_TIMESTAMP_FORMAT;
use crate::paths::Component;
use serde::{ser::Serializer, Serialize};
use tera::{Context, Error, Tera};
use thiserror::Error;
Expand Down Expand Up @@ -43,12 +44,19 @@ impl Templater {
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub(super) struct CollectionContext {
pub(super) title: String,
pub(super) breadcrumbs: Vec<Link>,
pub(super) rows: Vec<ColRow>,
pub(super) package_url: &'static str,
pub(super) package_version: &'static str,
pub(super) package_commit: Option<&'static str>,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub(super) struct Link {
name: String,
href: Href,
}

#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub(super) struct ColRow {
name: String,
Expand Down Expand Up @@ -144,3 +152,21 @@ fn maybe_timestamp<S: Serializer>(
None => serializer.serialize_none(),
}
}

pub(super) fn make_breadcrumbs(pathparts: Vec<Component>) -> Vec<Link> {
let mut links = Vec::with_capacity(pathparts.len().saturating_add(1));
let mut cumpath = String::from("/");
links.push(Link {
name: String::from("dandidav"),
href: Href::from_path(&cumpath),
});
for p in pathparts {
cumpath.push_str(&p);
cumpath.push('/');
links.push(Link {
name: p.into(),
href: Href::from_path(&cumpath),
});
}
links
}
24 changes: 19 additions & 5 deletions src/dav/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use self::util::*;
use self::xml::*;
use crate::consts::{DAV_XML_CONTENT_TYPE, HTML_CONTENT_TYPE};
use crate::dandi::*;
use crate::paths::Component;
use crate::zarrman::*;
use axum::{
body::Body,
Expand Down Expand Up @@ -64,14 +65,17 @@ impl DandiDav {
let m = req.method();
match m {
&Method::GET => {
let Some(path) = DavPath::parse_uri_path(uri_path) else {
let Some(parts) = split_uri_path(uri_path) else {
return Ok(not_found());
};
self.get(&path, uri_path).await
let Some(path) = DavPath::from_components(parts.clone()) else {
return Ok(not_found());
};
self.get(&path, parts).await
}
&Method::OPTIONS => Ok(StatusCode::NO_CONTENT.into_response()),
m if m.as_str().eq_ignore_ascii_case("PROPFIND") => {
let Some(path) = DavPath::parse_uri_path(uri_path) else {
let Some(path) = split_uri_path(uri_path).and_then(DavPath::from_components) else {
return Ok(not_found());
};
match req.extract::<(FiniteDepth, PropFind), _>().await {
Expand All @@ -83,16 +87,26 @@ impl DandiDav {
}
}

async fn get(&self, path: &DavPath, uri_path: &str) -> Result<Response<Body>, DavError> {
async fn get(
&self,
path: &DavPath,
pathparts: Vec<Component>,
) -> Result<Response<Body>, DavError> {
match self.resolve_with_children(path).await? {
DavResourceWithChildren::Collection { col, children } => {
let mut rows = children.into_iter().map(ColRow::from).collect::<Vec<_>>();
rows.sort_unstable();
if path != &DavPath::Root {
rows.insert(0, ColRow::parentdir(col.parent_web_link()));
}
let mut title = format!("{} \u{2014} /", self.title);
for p in &pathparts {
title.push_str(p);
title.push('/');
}
let context = CollectionContext {
title: format!("{} — {}", self.title, uri_path),
title,
breadcrumbs: make_breadcrumbs(pathparts),
rows,
package_url: env!("CARGO_PKG_REPOSITORY"),
package_version: env!("CARGO_PKG_VERSION"),
Expand Down
Loading

0 comments on commit 4998bd8

Please sign in to comment.