Display flake details
This commit is contained in:
		| @@ -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, | ||||||
|  |     })?) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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)) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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
									
								
							
							
						
						
									
										14
									
								
								templates/flake-info.html
									
									
									
									
									
										Normal 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 %} | ||||||
|  |  | ||||||
| @@ -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> | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user