WIP basic news thread rendering

This commit is contained in:
Bill Thiede 2024-07-21 12:50:21 -07:00
parent 65fcbd4b77
commit 6fae9cd018
3 changed files with 72 additions and 5 deletions

6
server/sql/thread.sql Normal file
View File

@ -0,0 +1,6 @@
SELECT
*
FROM
post
WHERE
uid = $1

View File

@ -243,14 +243,20 @@ impl QueryRoot {
}
async fn thread<'ctx>(&self, ctx: &Context<'ctx>, thread_id: String) -> Result<Thread, Error> {
let nm = ctx.data_unchecked::<Notmuch>();
let pool = ctx.data_unchecked::<PgPool>();
let debug_content_tree = ctx
.look_ahead()
.field("messages")
.field("body")
.field("contentTree")
.exists();
// TODO: look at thread_id and conditionally load newsreader
if newsreader::is_newsreader_thread(&thread_id) {
Ok(newsreader::thread(pool, thread_id).await?)
} else {
Ok(nm::thread(nm, thread_id, debug_content_tree).await?)
}
}
}
pub struct Mutation;

View File

@ -5,16 +5,21 @@ use log::info;
use sqlx::postgres::PgPool;
const TAG_PREFIX: &'static str = "News/";
const THREAD_PREFIX: &'static str = "news:";
use crate::{
error,
graphql::{Tag, ThreadSummary},
error::ServerError,
graphql::{Body, Email, Html, Message, Tag, Thread, ThreadSummary},
};
pub fn is_newsreader_search(query: &str) -> bool {
query.contains(TAG_PREFIX)
}
pub fn is_newsreader_thread(query: &str) -> bool {
query.starts_with(THREAD_PREFIX)
}
pub async fn search(
pool: &PgPool,
after: Option<String>,
@ -54,7 +59,7 @@ pub async fn search(
vec!["unread".to_string(), site.clone()]
};
ThreadSummary {
thread: format!("news:{}", r.uid),
thread: format!("{THREAD_PREFIX}{}", r.uid),
timestamp: r
.date
.expect("post missing date")
@ -84,7 +89,7 @@ pub async fn search(
.await
}
pub async fn tags(pool: &PgPool, needs_unread: bool) -> Result<Vec<Tag>, error::ServerError> {
pub async fn tags(pool: &PgPool, needs_unread: bool) -> Result<Vec<Tag>, ServerError> {
// TODO: write separate query for needs_unread.
let tags = sqlx::query_file!("sql/tags.sql").fetch_all(pool).await?;
let tags = tags
@ -105,3 +110,53 @@ pub async fn tags(pool: &PgPool, needs_unread: bool) -> Result<Vec<Tag>, error::
.collect();
Ok(tags)
}
pub async fn thread(pool: &PgPool, thread_id: String) -> Result<Thread, ServerError> {
let id = thread_id
.strip_prefix(THREAD_PREFIX)
.expect("news thread doesn't start with '{THREAD_PREFIX}'")
.to_string();
let r = sqlx::query_file!("sql/thread.sql", id)
.fetch_one(pool)
.await?;
let site = r.site.unwrap_or("NO SITE".to_string());
let tags = if r.is_read.unwrap_or(false) {
vec![site.clone()]
} else {
vec!["unread".to_string(), site.clone()]
};
let body = Body::Html(Html {
html: r.summary.unwrap_or("NO SUMMARY".to_string()),
content_tree: "".to_string(),
});
let title = r.title.unwrap_or("NO TITLE".to_string());
let from = Some(Email {
name: Some(site.clone()),
addr: r.link,
});
Ok(Thread {
thread_id,
subject: title.clone(),
messages: vec![Message {
id,
// TODO: join with feed for pretty site name
from,
to: Vec::new(),
cc: Vec::new(),
subject: Some(title),
timestamp: Some(
r.date
.expect("post missing date")
.assume_utc()
.unix_timestamp(),
),
headers: Vec::new(),
body,
path: "".to_string(),
attachments: Vec::new(),
tags,
}],
})
}