From ad5da60b5abc76fa0c4efaf36b94e0d534b659f5 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 6 Aug 2023 20:31:11 +0200 Subject: [PATCH] Show queued tasks --- ...c9ed2758e21a6bf74026ba3e19cba1d274536.json | 44 +++++++++++++ src/util.rs | 37 +++++++---- src/web.rs | 2 + src/web/commit_hash.rs | 4 +- src/web/queue.rs | 65 +++++++++++++++++-- static/base.css | 29 +++++++++ templates/queue.html | 6 +- templates/queue_table.html | 18 +++++ 8 files changed, 180 insertions(+), 25 deletions(-) create mode 100644 .sqlx/query-02a0484f131cdd7420fb073dec5c9ed2758e21a6bf74026ba3e19cba1d274536.json create mode 100644 templates/queue_table.html diff --git a/.sqlx/query-02a0484f131cdd7420fb073dec5c9ed2758e21a6bf74026ba3e19cba1d274536.json b/.sqlx/query-02a0484f131cdd7420fb073dec5c9ed2758e21a6bf74026ba3e19cba1d274536.json new file mode 100644 index 0000000..51d4969 --- /dev/null +++ b/.sqlx/query-02a0484f131cdd7420fb073dec5c9ed2758e21a6bf74026ba3e19cba1d274536.json @@ -0,0 +1,44 @@ +{ + "db_name": "SQLite", + "query": "SELECT id, hash, message, date AS \"date: time::OffsetDateTime\", priority FROM queue JOIN commits USING (hash) ORDER BY priority DESC, unixepoch(date) DESC, hash ASC ", + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "hash", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "message", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "date: time::OffsetDateTime", + "ordinal": 3, + "type_info": "Text" + }, + { + "name": "priority", + "ordinal": 4, + "type_info": "Int64" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "02a0484f131cdd7420fb073dec5c9ed2758e21a6bf74026ba3e19cba1d274536" +} diff --git a/src/util.rs b/src/util.rs index 34728d9..2454657 100644 --- a/src/util.rs +++ b/src/util.rs @@ -22,20 +22,31 @@ pub fn time_to_offset_datetime(time: Time) -> somehow::Result { .to_offset(UtcOffset::from_whole_seconds(time.offset)?)) } -pub fn format_time(time: OffsetDateTime) -> somehow::Result { - let now = OffsetDateTime::now_utc(); - let delta = time - now; - - let formatted_time = time.format(format_description!( - "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour sign:mandatory][offset_minute]" - ))?; - let formatted_delta = - humantime::format_duration(Duration::from_secs(delta.unsigned_abs().as_secs())); - Ok(if delta.is_positive() { - format!("{formatted_time} (in {formatted_delta})") +pub fn format_delta(delta: time::Duration) -> String { + let seconds = delta.unsigned_abs().as_secs(); + let seconds = seconds + 30 - (seconds + 30) % 60; // To nearest minute + let formatted = humantime::format_duration(Duration::from_secs(seconds)); + if delta.is_positive() { + format!("in {formatted}") } else { - format!("{formatted_time} ({formatted_delta} ago)") - }) + format!("{formatted} ago") + } +} + +pub fn format_delta_from_now(time: OffsetDateTime) -> String { + let now = OffsetDateTime::now_utc(); + format_delta(time - now) +} + +pub fn format_time(time: OffsetDateTime) -> String { + let formatted_time = time + .format(format_description!( + "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour sign:mandatory][offset_minute]" + )) + .expect("invalid date format"); + + let formatted_delta = format_delta_from_now(time); + format!("{formatted_time} ({formatted_delta})") } pub fn format_actor(author: IdentityRef<'_>) -> somehow::Result { diff --git a/src/web.rs b/src/web.rs index 8f6f334..77e729d 100644 --- a/src/web.rs +++ b/src/web.rs @@ -14,6 +14,7 @@ pub enum Tab { Queue, } +#[derive(Clone)] pub struct Base { root: String, repo_name: String, @@ -43,6 +44,7 @@ pub async fn run(state: AppState) -> somehow::Result<()> { .route("/commit/", get(commit::get)) .route("/commit/:hash", get(commit_hash::get)) .route("/queue/", get(queue::get)) + .route("/queue/table", get(queue::get_table)) .fallback(get(r#static::static_handler)) .with_state(state.clone()); diff --git a/src/web/commit_hash.rs b/src/web/commit_hash.rs index 657c055..6102797 100644 --- a/src/web/commit_hash.rs +++ b/src/web/commit_hash.rs @@ -101,9 +101,9 @@ pub async fn get( base: Base::new(config, Tab::Commit), hash: commit.hash, author: commit.author, - author_date: util::format_time(commit.author_date)?, + author_date: util::format_time(commit.author_date), commit: commit.committer, - commit_date: util::format_time(commit.committer_date)?, + commit_date: util::format_time(commit.committer_date), parents, children, summary: util::format_commit_summary(&commit.message), diff --git a/src/web/queue.rs b/src/web/queue.rs index b7fb171..fc62984 100644 --- a/src/web/queue.rs +++ b/src/web/queue.rs @@ -1,18 +1,69 @@ use askama::Template; use axum::{extract::State, response::IntoResponse}; +use futures::TryStreamExt; +use sqlx::SqlitePool; -use crate::{config::Config, somehow}; +use crate::{config::Config, somehow, util}; use super::{Base, Tab}; -#[derive(Template)] -#[template(path = "queue.html")] -struct CommitTemplate { - base: Base, +struct Task { + id: String, + short: String, + since: String, + priority: i64, } -pub async fn get(State(config): State<&'static Config>) -> somehow::Result { - Ok(CommitTemplate { +async fn get_queue(db: &SqlitePool) -> somehow::Result> { + sqlx::query!( + "\ + SELECT \ + id, \ + hash, \ + message, \ + date AS \"date: time::OffsetDateTime\", \ + priority \ + FROM queue \ + JOIN commits USING (hash) \ + ORDER BY priority DESC, unixepoch(date) DESC, hash ASC \ + " + ) + .fetch(db) + .map_ok(|r| Task { + id: r.id, + short: util::format_commit_short(&r.hash, &r.message), + since: util::format_delta_from_now(r.date), + priority: r.priority, + }) + .err_into::() + .try_collect::>() + .await +} + +#[derive(Template)] +#[template(path = "queue_table.html")] +struct QueueTableTemplate { + tasks: Vec, +} + +pub async fn get_table(State(db): State) -> somehow::Result { + let tasks = get_queue(&db).await?; + Ok(QueueTableTemplate { tasks }) +} +#[derive(Template)] +#[template(path = "queue.html")] +struct QueueTemplate { + base: Base, + table: QueueTableTemplate, +} + +pub async fn get( + State(config): State<&'static Config>, + State(db): State, +) -> somehow::Result { + let tasks = get_queue(&db).await?; + Ok(QueueTemplate { base: Base::new(config, Tab::Queue), + table: QueueTableTemplate { tasks }, }) } diff --git a/static/base.css b/static/base.css index e64a37e..7c481ea 100644 --- a/static/base.css +++ b/static/base.css @@ -37,6 +37,21 @@ details>summary { margin-left: 0; } +table { + border-collapse: collapse; +} + +thead tr, +tbody tr:hover { + background-color: #ddd; +} + +th+th, +td+td { + padding-left: 2ch; +} + + /* Nav bar */ nav { @@ -117,3 +132,17 @@ nav img { .commit pre { white-space: pre-wrap; } + +/* Queue */ + +.queue td:nth-child(2) { + text-align: right; +} + +.queue td:nth-child(3) { + text-align: center; +} + +.queue .odd { + background-color: #eee; +} diff --git a/templates/queue.html b/templates/queue.html index 8270f7d..3fb2524 100644 --- a/templates/queue.html +++ b/templates/queue.html @@ -1,8 +1,8 @@ {% extends "base.html" %} -{% block title %}queue{% endblock %} +{% block title %}queue ({{ table.tasks.len() }}){% endblock %} {% block body %} -

Queue

-

Sorry, nothing here yet.

+

Queue ({{ table.tasks.len() }})

+{{ table|safe }} {% endblock %} diff --git a/templates/queue_table.html b/templates/queue_table.html new file mode 100644 index 0000000..21dba18 --- /dev/null +++ b/templates/queue_table.html @@ -0,0 +1,18 @@ + + + + + + + + + + {% for task in tasks %} + + + + + + {% endfor %} + +
commitsinceprio
{{ task.short }}{{ task.since }}{{ task.priority }}