diff options
author | Tuomas Siipola | 2020-01-03 17:58:55 +0200 |
---|---|---|
committer | Tuomas Siipola | 2020-01-03 17:58:55 +0200 |
commit | f686ac3502e2d79d02931a50e29fac9a56196628 (patch) | |
tree | b869e7cbf17b4ae3413032dc880a8db3168c32c2 | |
parent | 3cbd74ad6161112fbd41723b48dcfa66e9caa603 (diff) |
Add log page
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 56 | ||||
-rw-r--r-- | templates/log.html | 42 | ||||
-rw-r--r-- | templates/repo.html | 1 |
5 files changed, 97 insertions, 4 deletions
@@ -280,6 +280,7 @@ dependencies = [ "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,3 +13,4 @@ tokio = { version = "0.2.6", features = ["macros"] } askama = "0.8.0" git2 = { version = "0.11.0", default-features = false } pulldown-cmark = { version = "0.6.1", default-features = false } +url = "2.1.0" diff --git a/src/main.rs b/src/main.rs index 23c5a6f..6ff3cae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ use git2::Repository; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Method, Request, Response, Server, StatusCode}; use pulldown_cmark::{html, Parser}; +use url::form_urlencoded; struct Repo { name: String, @@ -73,7 +74,7 @@ async fn index() -> Result<Response<Body>, Infallible> { enum Tab { Summary, Tree, - Commit, + Log, } struct Commit<'a> { @@ -125,7 +126,7 @@ fn read_readme(repo: &Repository, head: git2::Reference) -> Result<Option<String Ok(None) } -async fn repo(name: &str) -> Result<Response<Body>, Infallible> { +async fn summary(name: &str) -> Result<Response<Body>, Infallible> { let repo = Repository::open(Path::new("..").join(name)).unwrap(); let readme = read_readme(&repo, repo.head().unwrap()).unwrap(); let mut revwalk = repo.revwalk().unwrap(); @@ -338,7 +339,7 @@ async fn commit(name: &str, id: &str) -> Result<Response<Body>, Infallible> { .unwrap(); let tmpl = CommitTemplate { - tab: Tab::Commit, + tab: Tab::Log, repo: &read_repo(name).unwrap(), commit, diff: &diff_output, @@ -349,6 +350,47 @@ async fn commit(name: &str, id: &str) -> Result<Response<Body>, Infallible> { .unwrap()) } +#[derive(Template)] +#[template(path = "log.html")] +struct LogTemplate<'a> { + tab: Tab, + repo: &'a Repo, + commits: &'a [Commit<'a>], + next_id: Option<&'a str>, +} + +async fn log(name: &str, after: Option<&str>) -> Result<Response<Body>, Infallible> { + let repo = Repository::open(Path::new("..").join(name)).unwrap(); + + let mut revwalk = repo.revwalk().unwrap(); + match after { + Some(id) => revwalk.push(git2::Oid::from_str(id).unwrap()).unwrap(), + None => revwalk.push_head().unwrap(), + } + + let mut next_id = None; + let mut commits = Vec::new(); + while let Some(id) = revwalk.next() { + let id = id.unwrap(); + commits.push(Commit::new(repo.find_commit(id).unwrap())); + if commits.len() == 10 { + next_id = Some(format!("{}", id)); + break; + } + } + + let tmpl = LogTemplate { + tab: Tab::Log, + repo: &read_repo(name).unwrap(), + commits: commits.as_slice(), + next_id: next_id.as_ref().map(|x| x.as_ref()), + }; + Ok(Response::builder() + .header("Content-Type", "text/html") + .body(Body::from(tmpl.render().unwrap())) + .unwrap()) +} + async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> { if req.method() != Method::GET { return Ok(Response::builder() @@ -388,7 +430,13 @@ async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> { fs::read_to_string("public/folder-solid.svg").unwrap(), )) .unwrap()), - [name] => repo(name).await, + [name] => summary(name).await, + [name, "log"] => { + let after = form_urlencoded::parse(req.uri().query().unwrap_or("").as_bytes()) + .find(|(key, _)| key == "after") + .map(|(_, value)| value); + log(name, after.as_ref().map(|x| x.as_ref())).await + } [name, "commit", id] => commit(name, id).await, _ => Ok(Response::builder() .status(StatusCode::NOT_FOUND) diff --git a/templates/log.html b/templates/log.html new file mode 100644 index 0000000..1d39fbb --- /dev/null +++ b/templates/log.html @@ -0,0 +1,42 @@ +{# + # SPDX-FileCopyrightText: 2020 Tuomas Siipola + # SPDX-License-Identifier: EUPL-1.2 + #} + +{% extends "repo.html" %} + +{% block tab %} + <ul class="commits"> + {% for commit in commits %} + <li> + <a href="/{{ repo.name }}/commit/{{ commit.id }}"> + <code> + {{- commit.id[..8] -}} + </code> + <span class="message"> + {% match commit.summary() %} + {% when Some with (summary) %} + {{ summary }} + {% when None %} + no message + {% endmatch %} + </span> + <span class="author"> + by + {% match commit.author().name() %} + {% when Some with (author) %} + {{ author }} + {% when None %} + unknown + {% endmatch %} + </span> + </a> + </li> + {% endfor %} + </ul> + {% match next_id %} + {% when Some with (id) %} + <a href="/{{ repo.name }}/log?after={{ id }}">Next</a> + {% when None %} + {% endmatch %} +{% endblock %} diff --git a/templates/repo.html b/templates/repo.html index 8cfdc65..eac949c 100644 --- a/templates/repo.html +++ b/templates/repo.html @@ -22,6 +22,7 @@ <ul class="tabs"> <li><a href="/{{ repo.name }}"{% match tab %}{% when Tab::Summary %} class="current"{% else %}{% endmatch %}>summary</a></li> <li><a href="/{{ repo.name }}/tree"{% match tab %}{% when Tab::Tree %} class="current"{% else %}{% endmatch %}>tree</a></li> + <li><a href="/{{ repo.name }}/log"{% match tab %}{% when Tab::Log %} class="current"{% else %}{% endmatch %}>log</a></li> </ul> {% block tab %}{% endblock %} {% endblock %} |