List scanned flakes
This commit is contained in:
		| @@ -19,26 +19,19 @@ use axum::{ | |||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| use flake_tracker::{ | use flake_tracker::{ | ||||||
|  |     storage::{ | ||||||
|  |         FlakeUri, | ||||||
|  |     }, | ||||||
|     templates::{ |     templates::{ | ||||||
|  |         FlakesTemplate, | ||||||
|         IndexTemplate, |         IndexTemplate, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| use sqlx::{ | use sqlx::{ | ||||||
|     FromRow, |  | ||||||
|     SqlitePool, |     SqlitePool, | ||||||
|     sqlite::SqlitePoolOptions, |     sqlite::SqlitePoolOptions, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #[derive(FromRow)] |  | ||||||
| struct StorageFlakeRevision { |  | ||||||
|     revision_uri: String, |  | ||||||
|     uri: Option<String>, |  | ||||||
|     nix_store_path: Option<String>, |  | ||||||
|     revision: Option<String>, |  | ||||||
|     nar_hash: Option<String>, |  | ||||||
|     last_modified: Option<i64>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct AppError(anyhow::Error); | struct AppError(anyhow::Error); | ||||||
|  |  | ||||||
| impl std::fmt::Display for AppError { | impl std::fmt::Display for AppError { | ||||||
| @@ -121,15 +114,10 @@ async fn route_index( | |||||||
|  |  | ||||||
| async fn route_flakes( | async fn route_flakes( | ||||||
|     State(state): State<AppState>, |     State(state): State<AppState>, | ||||||
| ) -> Result<String, AppError> { | ) -> Result<impl IntoResponse, AppError> { | ||||||
|     let flake_revisions: Vec<StorageFlakeRevision> = sqlx::query_as(" |     let flake_revisions: Vec<FlakeUri> = sqlx::query_as(" | ||||||
|         SELECT |         SELECT | ||||||
|             revision_uri, |             uri | ||||||
|             uri, |  | ||||||
|             nix_store_path, |  | ||||||
|             revision, |  | ||||||
|             nar_hash, |  | ||||||
|             last_modified |  | ||||||
|         FROM flake_revisions |         FROM flake_revisions | ||||||
|         GROUP BY uri |         GROUP BY uri | ||||||
|         ORDER BY uri |         ORDER BY uri | ||||||
| @@ -138,15 +126,7 @@ async fn route_flakes( | |||||||
|         .await |         .await | ||||||
|         .context("Failed to fetch data from database")?; |         .context("Failed to fetch data from database")?; | ||||||
|  |  | ||||||
|     let mut out = String::new(); |     Ok(render_template(&FlakesTemplate { | ||||||
|  |         flakes: flake_revisions, | ||||||
|     for flake_revision in flake_revisions { |     })?) | ||||||
|         if let Some(uri) = &flake_revision.uri { |  | ||||||
|             out.push_str("- "); |  | ||||||
|             out.push_str(&uri); |  | ||||||
|             out.push_str("\n"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Ok(out) |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1 +1,3 @@ | |||||||
|  | pub mod storage; | ||||||
| pub mod templates; | pub mod templates; | ||||||
|  | pub mod utils; | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								src/storage.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/storage.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | use sqlx::{ | ||||||
|  |     FromRow, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #[derive(FromRow)] | ||||||
|  | pub struct FlakeRevisionRow { | ||||||
|  |     pub revision_uri: String, | ||||||
|  |     pub uri: Option<String>, | ||||||
|  |     pub nix_store_path: Option<String>, | ||||||
|  |     pub revision: Option<String>, | ||||||
|  |     pub nar_hash: Option<String>, | ||||||
|  |     pub last_modified: Option<i64>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(FromRow)] | ||||||
|  | pub struct FlakeUri { | ||||||
|  |     pub uri: String, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl FlakeUri { | ||||||
|  |     pub fn uri_encoded(&self ) -> String { | ||||||
|  |         crate::utils::urlencode(&self.uri) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,8 +1,19 @@ | |||||||
| use askama::{ | use askama::{ | ||||||
|     Template, |     Template, | ||||||
| }; | }; | ||||||
|  | use crate::{ | ||||||
|  |     storage::{ | ||||||
|  |         FlakeUri, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
|  |  | ||||||
| #[derive(Template)] | #[derive(Template)] | ||||||
| #[template(path = "index.html")] | #[template(path = "index.html")] | ||||||
| pub struct IndexTemplate { | pub struct IndexTemplate { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Template)] | ||||||
|  | #[template(path = "flakes.html")] | ||||||
|  | pub struct FlakesTemplate { | ||||||
|  |     pub flakes: Vec<FlakeUri>, | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								src/utils.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/utils.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | fn urlencode_char(c: &char) -> String { | ||||||
|  |     if c.is_ascii_alphanumeric() { | ||||||
|  |         return c.to_string(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if vec!['-', '.', '_', '~'].contains(&c) { | ||||||
|  |         return c.to_string(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     c.to_string().as_bytes().iter().map(|b| format!("%{:02X}", b)).collect::<Vec<String>>().join("") | ||||||
|  | } | ||||||
|  | pub fn urlencode(s: &str) -> String { | ||||||
|  |     s.chars().map(|c| urlencode_char(&c)).collect::<Vec<String>>().join("") | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								templates/base.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								templates/base.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="utf-8"> | ||||||
|  | 		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||||||
|  | 		<title>Flake Tracker</title> | ||||||
|  | 	</head> | ||||||
|  | 	<body> | ||||||
|  | 		<div id="content"> | ||||||
|  | 			{% block content %}{% endblock %} | ||||||
|  | 		</div> | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								templates/flakes.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/flakes.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | {% extends "base.html" %} | ||||||
|  |  | ||||||
|  | {% block content %} | ||||||
|  | <h1>All scanned flakes</h1> | ||||||
|  |  | ||||||
|  | <ul> | ||||||
|  | {% for flake in flakes %} | ||||||
|  | 	<li><a href="/f/{{ flake.uri_encoded() }}">{{ flake.uri }}</a></li> | ||||||
|  | {% endfor %} | ||||||
|  | </ul> | ||||||
|  |  | ||||||
|  | {% endblock %} | ||||||
| @@ -1 +1,10 @@ | |||||||
| Hello World! | {% extends "base.html" %} | ||||||
|  |  | ||||||
|  | {% block content %} | ||||||
|  | <h1>Flake Tracker</h1> | ||||||
|  |  | ||||||
|  | <ul> | ||||||
|  | 	<li><a href="/flakes">All scanned flakes</a></li> | ||||||
|  | </ul> | ||||||
|  | {% endblock %} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user