Display flake details

This commit is contained in:
clerie 2025-02-01 19:00:51 +01:00
parent 055a9c9d57
commit 97ea3d3802
5 changed files with 69 additions and 3 deletions

View File

@ -4,6 +4,7 @@ use anyhow::{
use askama::Template; use askama::Template;
use axum::{ use axum::{
extract::{ extract::{
Path,
State, State,
}, },
http::{ http::{
@ -20,9 +21,11 @@ use axum::{
}; };
use flake_tracker::{ use flake_tracker::{
storage::{ storage::{
FlakeRevision,
FlakeUri, FlakeUri,
}, },
templates::{ templates::{
FlakeInfoTemplate,
FlakesTemplate, FlakesTemplate,
IndexTemplate, IndexTemplate,
}, },
@ -93,6 +96,7 @@ async fn main() -> anyhow::Result<()> {
let mut app = Router::new() let mut app = Router::new()
.route("/", get(route_index)) .route("/", get(route_index))
.route("/flakes", get(route_flakes)) .route("/flakes", get(route_flakes))
.route("/f/{uri}", get(route_flake_info))
.with_state(state); .with_state(state);
let listener = tokio::net::TcpListener::bind("[::]:3000") let listener = tokio::net::TcpListener::bind("[::]:3000")
@ -130,3 +134,27 @@ async fn route_flakes(
flakes: flake_revisions, flakes: flake_revisions,
})?) })?)
} }
async fn route_flake_info(
State(state): State<AppState>,
Path(uri): Path<String>,
) -> Result<impl IntoResponse, AppError> {
let flake_revisions: Vec<FlakeRevision> = sqlx::query_as("
SELECT
revision_uri,
revision,
last_modified
FROM flake_revisions
WHERE uri = ?
ORDER BY last_modified
")
.bind(&uri)
.fetch_all(&state.db)
.await
.context("Failed to fetch data from database")?;
Ok(render_template(&FlakeInfoTemplate {
uri: uri,
flake_revisions: flake_revisions,
})?)
}

View File

@ -1,3 +1,6 @@
use crate::utils::{
urlencode,
};
use sqlx::{ use sqlx::{
FromRow, FromRow,
}; };
@ -12,13 +15,26 @@ pub struct FlakeRevisionRow {
pub last_modified: Option<i64>, pub last_modified: Option<i64>,
} }
#[derive(FromRow)]
pub struct FlakeRevision {
pub revision_uri: String,
pub revision: String,
pub last_modified: i64,
}
impl FlakeRevision {
pub fn link(&self ) -> String {
format!("/r/{}", urlencode(&self.revision_uri))
}
}
#[derive(FromRow)] #[derive(FromRow)]
pub struct FlakeUri { pub struct FlakeUri {
pub uri: String, pub uri: String,
} }
impl FlakeUri { impl FlakeUri {
pub fn uri_encoded(&self ) -> String { pub fn link(&self ) -> String {
crate::utils::urlencode(&self.uri) format!("/f/{}", urlencode(&self.uri))
} }
} }

View File

@ -3,6 +3,7 @@ use askama::{
}; };
use crate::{ use crate::{
storage::{ storage::{
FlakeRevision,
FlakeUri, FlakeUri,
}, },
}; };
@ -17,3 +18,10 @@ pub struct IndexTemplate {
pub struct FlakesTemplate { pub struct FlakesTemplate {
pub flakes: Vec<FlakeUri>, pub flakes: Vec<FlakeUri>,
} }
#[derive(Template)]
#[template(path = "flake-info.html")]
pub struct FlakeInfoTemplate {
pub uri: String,
pub flake_revisions: Vec<FlakeRevision>,
}

14
templates/flake-info.html Normal file
View File

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block content %}
<h1>{{ uri }}</h1>
<h2>Revisions</h2>
<ul>
{% for flake_revision in flake_revisions %}
<li><a href="{{ flake_revision.link() }}">{{ flake_revision.revision }}</a> ({{ flake_revision.last_modified }})</li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -5,7 +5,7 @@
<ul> <ul>
{% for flake in flakes %} {% for flake in flakes %}
<li><a href="/f/{{ flake.uri_encoded() }}">{{ flake.uri }}</a></li> <li><a href="{{ flake.link() }}">{{ flake.uri }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>