server: WIP tantivy integration
This commit is contained in:
@@ -10,35 +10,33 @@ use tokio::sync::Mutex;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
compute_offset_limit,
|
||||
clean_title, compute_offset_limit,
|
||||
config::Config,
|
||||
error::ServerError,
|
||||
graphql::{NewsPost, Tag, Thread, ThreadSummary},
|
||||
AddOutlink, EscapeHtml, FrameImages, InlineStyle, Query, SanitizeHtml, SlurpContents,
|
||||
StripHtml, Transformer,
|
||||
thread_summary_from_row, AddOutlink, EscapeHtml, FrameImages, InlineStyle, Query, SanitizeHtml,
|
||||
SlurpContents, StripHtml, ThreadSummaryRecord, Transformer, NEWSREADER_TAG_PREFIX,
|
||||
NEWSREADER_THREAD_PREFIX,
|
||||
};
|
||||
|
||||
const TAG_PREFIX: &'static str = "News/";
|
||||
const THREAD_PREFIX: &'static str = "news:";
|
||||
|
||||
pub fn is_newsreader_search(query: &str) -> bool {
|
||||
query.contains(TAG_PREFIX)
|
||||
query.contains(NEWSREADER_TAG_PREFIX)
|
||||
}
|
||||
|
||||
pub fn is_newsreader_thread(query: &str) -> bool {
|
||||
query.starts_with(THREAD_PREFIX)
|
||||
query.starts_with(NEWSREADER_THREAD_PREFIX)
|
||||
}
|
||||
|
||||
pub fn extract_thread_id(query: &str) -> &str {
|
||||
&query[THREAD_PREFIX.len()..]
|
||||
&query[NEWSREADER_THREAD_PREFIX.len()..]
|
||||
}
|
||||
|
||||
pub fn extract_site(tag: &str) -> &str {
|
||||
&tag[TAG_PREFIX.len()..]
|
||||
&tag[NEWSREADER_TAG_PREFIX.len()..]
|
||||
}
|
||||
|
||||
pub fn make_news_tag(tag: &str) -> String {
|
||||
format!("tag:{TAG_PREFIX}{tag}")
|
||||
format!("tag:{NEWSREADER_TAG_PREFIX}{tag}")
|
||||
}
|
||||
|
||||
pub async fn count(pool: &PgPool, query: &Query) -> Result<usize, ServerError> {
|
||||
@@ -93,37 +91,23 @@ pub async fn search(
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let mut res = Vec::new();
|
||||
for (i, r) in rows.into_iter().enumerate() {
|
||||
let site = r.site.unwrap_or("UNKOWN TAG".to_string());
|
||||
let mut tags = vec![format!("{TAG_PREFIX}{site}")];
|
||||
if !r.is_read.unwrap_or(true) {
|
||||
tags.push("unread".to_string());
|
||||
};
|
||||
let mut title = r.title.unwrap_or("NO TITLE".to_string());
|
||||
title = clean_title(&title).await.expect("failed to clean title");
|
||||
res.push((
|
||||
i as i32 + offset,
|
||||
ThreadSummary {
|
||||
thread: format!("{THREAD_PREFIX}{}", r.uid),
|
||||
timestamp: r
|
||||
.date
|
||||
.expect("post missing date")
|
||||
.assume_utc()
|
||||
.unix_timestamp() as isize,
|
||||
date_relative: "TODO date_relative".to_string(),
|
||||
matched: 0,
|
||||
total: 1,
|
||||
authors: r.name.unwrap_or_else(|| site.clone()),
|
||||
subject: title,
|
||||
tags,
|
||||
},
|
||||
thread_summary_from_row(ThreadSummaryRecord {
|
||||
site: r.site,
|
||||
date: r.date,
|
||||
is_read: r.is_read,
|
||||
title: r.title,
|
||||
uid: r.uid,
|
||||
name: r.name,
|
||||
})
|
||||
.await,
|
||||
));
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub async fn tags(pool: &PgPool, _needs_unread: bool) -> Result<Vec<Tag>, ServerError> {
|
||||
// TODO: optimize query by using needs_unread
|
||||
let tags = sqlx::query_file!("sql/tags.sql").fetch_all(pool).await?;
|
||||
@@ -131,7 +115,10 @@ pub async fn tags(pool: &PgPool, _needs_unread: bool) -> Result<Vec<Tag>, Server
|
||||
.into_iter()
|
||||
.map(|tag| {
|
||||
let unread = tag.unread.unwrap_or(0).try_into().unwrap_or(0);
|
||||
let name = format!("{TAG_PREFIX}{}", tag.site.expect("tag must have site"));
|
||||
let name = format!(
|
||||
"{NEWSREADER_TAG_PREFIX}{}",
|
||||
tag.site.expect("tag must have site")
|
||||
);
|
||||
let hex = compute_color(&name);
|
||||
Tag {
|
||||
name,
|
||||
@@ -150,8 +137,8 @@ pub async fn thread(
|
||||
thread_id: String,
|
||||
) -> Result<Thread, ServerError> {
|
||||
let id = thread_id
|
||||
.strip_prefix(THREAD_PREFIX)
|
||||
.expect("news thread doesn't start with '{THREAD_PREFIX}'")
|
||||
.strip_prefix(NEWSREADER_THREAD_PREFIX)
|
||||
.expect("news thread doesn't start with '{NEWSREADER_THREAD_PREFIX}'")
|
||||
.to_string();
|
||||
|
||||
let r = sqlx::query_file!("sql/thread.sql", id)
|
||||
@@ -265,17 +252,3 @@ pub async fn set_read_status<'ctx>(
|
||||
.await?;
|
||||
Ok(true)
|
||||
}
|
||||
async fn clean_title(title: &str) -> Result<String, ServerError> {
|
||||
// Make title HTML so html parsers work
|
||||
let mut title = format!("<html>{title}</html>");
|
||||
let title_tranformers: Vec<Box<dyn Transformer>> =
|
||||
vec![Box::new(EscapeHtml), Box::new(StripHtml)];
|
||||
// Make title HTML so html parsers work
|
||||
title = format!("<html>{title}</html>");
|
||||
for t in title_tranformers.iter() {
|
||||
if t.should_run(&None, &title) {
|
||||
title = t.transform(&None, &title).await?;
|
||||
}
|
||||
}
|
||||
Ok(title)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user