Adding recent articles back to blog. Cleaning up appstate
This commit is contained in:
parent
ae530431d7
commit
a13ca49fa8
7 changed files with 32 additions and 194 deletions
|
|
@ -1,86 +0,0 @@
|
|||
use super::blog::get_articles_as_links_list;
|
||||
use crate::{
|
||||
database::{link::{Link, LinkType}, PsqlData},
|
||||
html::AppState,
|
||||
};
|
||||
use axum::{response::IntoResponse, routing::get, Extension, Router};
|
||||
use sqlx::PgPool;
|
||||
use std::error::Error;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new()
|
||||
.route("/articles", get(blogs))
|
||||
.route("/recentarticles", get(recent_blogs))
|
||||
.route("/blogrolllinks", get(blogroll_links))
|
||||
.route("/articlelinks", get(article_links))
|
||||
}
|
||||
|
||||
async fn blogs(state: Extension<AppState>) -> impl IntoResponse {
|
||||
let db_pool = &state.db;
|
||||
let article_list: Vec<String> = get_articles_as_links_list(db_pool)
|
||||
.await
|
||||
.expect("couldn't get articles");
|
||||
|
||||
article_list.join("\n")
|
||||
}
|
||||
|
||||
async fn recent_blogs(state: Extension<AppState>) -> impl IntoResponse {
|
||||
let db_pool = &state.db;
|
||||
let article_list: Vec<String> = get_articles_as_links_list(db_pool)
|
||||
.await
|
||||
.expect("couldn't get articles");
|
||||
|
||||
let (article_head, _) = article_list.split_at(5);
|
||||
|
||||
article_head.join("\n")
|
||||
}
|
||||
|
||||
async fn blogroll_links(state: Extension<AppState>) -> impl IntoResponse {
|
||||
let db_pool = &state.db;
|
||||
let blogroll_list: Vec<String> = get_links_as_list(db_pool, LinkType::BLOG)
|
||||
.await
|
||||
.expect("couldn't get blogroll links");
|
||||
|
||||
blogroll_list.join("\n<hr>\n")
|
||||
}
|
||||
|
||||
async fn article_links(state: Extension<AppState>) -> impl IntoResponse {
|
||||
let db_pool = &state.db;
|
||||
let blogroll_list: Vec<String> = get_links_as_list(db_pool, LinkType::ARTICLE)
|
||||
.await
|
||||
.expect("couldn't get blogroll links");
|
||||
|
||||
blogroll_list.join("\n<hr>\n")
|
||||
}
|
||||
|
||||
pub async fn get_links_as_list(pool: &PgPool, link_type: LinkType) -> Result<Vec<String>, Box<dyn Error>> {
|
||||
let mut links: Vec<Link> = match Link::read_all(pool).await {
|
||||
Ok(a) => a.iter().map(|x| *x.clone()).collect(),
|
||||
Err(_) => Vec::new(),
|
||||
};
|
||||
|
||||
let mut rng = thread_rng();
|
||||
links.shuffle(&mut rng);
|
||||
|
||||
let list: Vec<String> = links
|
||||
.iter()
|
||||
.filter(|link| link.link_type == link_type)
|
||||
.map(|link| {
|
||||
let title: String = match &link.title {
|
||||
Some(t) => t.to_string(),
|
||||
None => link.url.clone(),
|
||||
};
|
||||
format!(
|
||||
"<li><a href=\"{}\">{}</a>:<br>{}</li>",
|
||||
link.url,
|
||||
title,
|
||||
match &link.description {
|
||||
Some(d) => d,
|
||||
None => "",
|
||||
}
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
Ok(list)
|
||||
}
|
||||
|
|
@ -8,10 +8,7 @@ use axum::{
|
|||
use sqlx::PgPool;
|
||||
use std::{collections::HashMap, error::Error};
|
||||
|
||||
use super::{
|
||||
templates::{ArticleTemplate, BlogFooterTemplate, BlogTemplate, HtmlTemplate},
|
||||
AppState,
|
||||
};
|
||||
use super::templates::{ArticleTemplate, BlogFooterTemplate, BlogTemplate, HtmlTemplate};
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new()
|
||||
|
|
@ -19,23 +16,22 @@ pub fn get_router() -> Router {
|
|||
.route("/:article", get(article))
|
||||
}
|
||||
|
||||
async fn blog(state: Extension<AppState>) -> impl IntoResponse {
|
||||
async fn blog(Extension(pool): Extension<PgPool>) -> impl IntoResponse {
|
||||
let blog_page = BlogTemplate {
|
||||
articles: match get_articles_date_sorted(&state.db).await {
|
||||
articles: match get_articles_date_sorted(&pool).await {
|
||||
Ok(list) => list,
|
||||
Err(_) => Vec::new(),
|
||||
}
|
||||
},
|
||||
};
|
||||
HtmlTemplate(blog_page)
|
||||
}
|
||||
|
||||
async fn article(
|
||||
state: Extension<AppState>,
|
||||
Extension(pool): Extension<PgPool>,
|
||||
Path(params): Path<HashMap<String, String>>,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
let db_pool = &state.db;
|
||||
let article_id: &String = params.get("article").unwrap();
|
||||
let article: Article = match Article::read_by_reference(db_pool, article_id).await {
|
||||
let article: Article = match Article::read_by_reference(&pool, article_id).await {
|
||||
Ok(a) => *a,
|
||||
Err(_) => return Err(StatusCode::NOT_FOUND),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
use sqlx::PgPool;
|
||||
|
||||
pub mod blog;
|
||||
pub mod garden;
|
||||
pub mod root;
|
||||
pub mod templates;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub db: PgPool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
use achubb_database::data::{project::Project, PsqlData};
|
||||
use askama::Template;
|
||||
use axum::extract::{Extension, Path};
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::{routing::get, Router};
|
||||
use sqlx::PgPool;
|
||||
use std::{collections::HashMap, error::Error};
|
||||
|
||||
use super::{root::AppState, ArticleTemplate, HtmlTemplate};
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new()
|
||||
.route("/", get(projects))
|
||||
.route("/:project", get(project))
|
||||
}
|
||||
|
||||
pub async fn projects(state: Extension<AppState>) -> impl IntoResponse {
|
||||
let db_pool = &state.db;
|
||||
let list: Vec<String> = get_projects_as_links_list(db_pool)
|
||||
.await
|
||||
.expect("couldn't get projects");
|
||||
let template = ProjectsTemplate {
|
||||
project_list: list.join("\n"),
|
||||
};
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "projects.html")]
|
||||
struct ProjectsTemplate {
|
||||
project_list: String,
|
||||
}
|
||||
|
||||
async fn project(
|
||||
state: Extension<AppState>,
|
||||
Path(params): Path<HashMap<String, String>>,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
let db_pool = &state.db;
|
||||
let project_id: &String = params.get("project").unwrap();
|
||||
let project: Project = match Project::read_by_reference(db_pool, project_id).await {
|
||||
Ok(a) => *a,
|
||||
Err(_) => return Err(StatusCode::NOT_FOUND),
|
||||
};
|
||||
let footer: &str = "<a href=\"/projects\">Back to Projects</a>";
|
||||
let template = ArticleTemplate {
|
||||
content: project
|
||||
.content
|
||||
.expect("Should have had content if it got this far"),
|
||||
footer: footer.to_string(),
|
||||
};
|
||||
Ok(HtmlTemplate(template))
|
||||
}
|
||||
|
||||
pub async fn get_projects_as_links_list(pool: &PgPool) -> Result<Vec<String>, Box<dyn Error>> {
|
||||
let mut projects: Vec<Project> = match Project::read_all(pool).await {
|
||||
Ok(a) => a.iter().map(|x| *x.clone()).collect(),
|
||||
Err(_) => Vec::new(),
|
||||
};
|
||||
|
||||
projects.sort_by(|a, b| b.date.cmp(&a.date));
|
||||
|
||||
let list: Vec<String> = projects
|
||||
.iter()
|
||||
.map(|project| {
|
||||
if project.blog {
|
||||
format!(
|
||||
"<li><a href=\"/blog/{}\">{}</a></li>",
|
||||
project.reference, project.title
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"<li><a href=\"/projects/{}\">{}</a></li>",
|
||||
project.reference, project.title
|
||||
)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Ok(list)
|
||||
}
|
||||
|
|
@ -14,16 +14,16 @@ use crate::database::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
blog, garden,
|
||||
blog::{self, get_articles_date_sorted},
|
||||
garden,
|
||||
templates::{
|
||||
AboutTemplate, AiTemplate, BlogrollTemplate, ContactTemplate, GiftsTemplate, HomeTemplate, HtmlTemplate, InterestsTemplate, LinksPageTemplate, NowTemplate, UsesTemplate
|
||||
AboutTemplate, AiTemplate, BlogrollTemplate, ContactTemplate, GiftsTemplate, HomeTemplate,
|
||||
HtmlTemplate, InterestsTemplate, LinksPageTemplate, NowTemplate, UsesTemplate,
|
||||
},
|
||||
AppState,
|
||||
};
|
||||
|
||||
pub fn get_router(pool: PgPool) -> Router {
|
||||
let assets_path = std::env::current_dir().unwrap();
|
||||
let state = AppState { db: pool };
|
||||
Router::new()
|
||||
.nest("/blog", blog::get_router())
|
||||
.nest("/garden", garden::get_router())
|
||||
|
|
@ -45,11 +45,15 @@ pub fn get_router(pool: PgPool) -> Router {
|
|||
"/robots.txt",
|
||||
get(|| async { Redirect::permanent("/assets/robots.txt") }),
|
||||
)
|
||||
.layer(Extension(state))
|
||||
.layer(Extension(pool))
|
||||
}
|
||||
|
||||
async fn home() -> impl IntoResponse {
|
||||
HtmlTemplate(HomeTemplate {})
|
||||
async fn home(Extension(pool): Extension<PgPool>) -> impl IntoResponse {
|
||||
let mut articles = get_articles_date_sorted(&pool).await.unwrap();
|
||||
articles.truncate(5);
|
||||
HtmlTemplate(HomeTemplate {
|
||||
recent_articles: articles,
|
||||
})
|
||||
}
|
||||
|
||||
async fn now() -> impl IntoResponse {
|
||||
|
|
@ -80,9 +84,9 @@ async fn gifts() -> impl IntoResponse {
|
|||
HtmlTemplate(GiftsTemplate {})
|
||||
}
|
||||
|
||||
async fn blogroll(state: Extension<AppState>) -> impl IntoResponse {
|
||||
async fn blogroll(Extension(pool): Extension<PgPool>) -> impl IntoResponse {
|
||||
let blogroll_page = BlogrollTemplate {
|
||||
blogs: match get_links_as_list(&state.db, LinkType::BLOG).await {
|
||||
blogs: match get_links_as_list(&pool, LinkType::BLOG).await {
|
||||
Ok(list) => list,
|
||||
Err(_) => Vec::new(),
|
||||
},
|
||||
|
|
@ -90,9 +94,9 @@ async fn blogroll(state: Extension<AppState>) -> impl IntoResponse {
|
|||
HtmlTemplate(blogroll_page)
|
||||
}
|
||||
|
||||
async fn links(state: Extension<AppState>) -> impl IntoResponse {
|
||||
async fn links(Extension(pool): Extension<PgPool>) -> impl IntoResponse {
|
||||
let links_page = LinksPageTemplate {
|
||||
articles: match get_links_as_list(&state.db, LinkType::ARTICLE).await {
|
||||
articles: match get_links_as_list(&pool, LinkType::ARTICLE).await {
|
||||
Ok(list) => list,
|
||||
Err(_) => Vec::new(),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -110,7 +110,9 @@ pub struct InterestsTemplate {}
|
|||
|
||||
#[derive(Template)]
|
||||
#[template(path = "home.html")]
|
||||
pub struct HomeTemplate {}
|
||||
pub struct HomeTemplate {
|
||||
pub recent_articles: Vec<Article>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "about.html")]
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@
|
|||
Chronological <a href="blog">stuff</a> that I have written.
|
||||
Not adding to this as much with the focus more on the garden but if something is timely then will still be added as a blog post.
|
||||
</p>
|
||||
<h3>Most Recent Posts</h3>
|
||||
|
||||
<ul class="no-bul">
|
||||
{% for article in recent_articles %}
|
||||
<li><a href="/blog/{{article.reference}}">{{article.title}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</section><br>
|
||||
|
||||
<section id="interests">
|
||||
|
|
@ -81,6 +88,7 @@
|
|||
How <a href="/ai">AI</a> is (or more accurately is not) used in this site and my work in general,
|
||||
and why.
|
||||
</p>
|
||||
</section><br>
|
||||
|
||||
<section id="contact">
|
||||
<h2>Contact Me</h2>
|
||||
|
|
|
|||
Loading…
Reference in a new issue