From e86b241ee6423743c1b5d6c70484d3f538386a85 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 10 Jan 2026 17:53:48 +0200 Subject: [PATCH] implement local image features --- crates/crawler/src/main.rs | 5 ++++- crates/http/config.toml | 4 ---- crates/http/src/main.rs | 32 +++++++++++++++++++++------ crates/http/templates/index.html.tera | 5 +---- crates/mysql/src/connection.rs | 14 +++++++----- crates/mysql/src/transaction.rs | 13 +++++++++++ 6 files changed, 52 insertions(+), 21 deletions(-) diff --git a/crates/crawler/src/main.rs b/crates/crawler/src/main.rs index 881b9b6..c766142 100644 --- a/crates/crawler/src/main.rs +++ b/crates/crawler/src/main.rs @@ -171,7 +171,10 @@ fn crawl(tx: &mut mysql::Transaction, channel_config: &config::Channel) -> Resul } }; let content_image_id = tx.insert_content_image(content_id, image_id)?; - debug!("Add content image relationship #{content_image_id}") + debug!("Add content image relationship #{content_image_id}"); + let uri = format!("/image/{image_id}"); + tx.replace_content_description(content_id, src, &uri)?; + debug!("Replace content image in description from `{src}` to `{uri}`") } } } diff --git a/crates/http/config.toml b/crates/http/config.toml index f4ade36..0e81ccb 100644 --- a/crates/http/config.toml +++ b/crates/http/config.toml @@ -1,10 +1,6 @@ title = "rssto" #description = "" -# Replace image sources with local -# * if crawled with the `persist_images_selector` selector -local_images = true - format_time = "%d/%m/%Y %H:%M" # Provider ID (`provider` table) diff --git a/crates/http/src/main.rs b/crates/http/src/main.rs index df8ecd4..568b95b 100644 --- a/crates/http/src/main.rs +++ b/crates/http/src/main.rs @@ -12,7 +12,12 @@ use feed::Feed; use global::Global; use meta::Meta; use mysql::{Database, table::Sort}; -use rocket::{State, http::Status, response::content::RawXml, serde::Serialize}; +use rocket::{ + State, + http::{ContentType, Status}, + response::content::RawXml, + serde::Serialize, +}; use rocket_dyn_templates::{Template, context}; #[get("/?&")] @@ -25,9 +30,8 @@ fn index( ) -> Result { #[derive(Serialize)] #[serde(crate = "rocket::serde")] - struct Content { + struct Row { content_id: u64, - description: String, link: String, time: String, title: String, @@ -81,15 +85,14 @@ fn index( .into_iter() .map(|content| { let channel_item = conn.channel_item(content.channel_item_id).unwrap().unwrap(); - Content { + Row { content_id: content.content_id, - description: content.description, link: channel_item.link, time: time(channel_item.pub_date).format(&global.format_time).to_string(), title: content.title, } }) - .collect::>(), + .collect::>(), page: page.unwrap_or(1), pages: (total as f64 / global.list_limit as f64).ceil(), total, @@ -140,6 +143,21 @@ fn info( } } +#[get("/image/")] +fn image(image_id: u64, db: &State) -> Result<(ContentType, Vec), Status> { + let mut conn = db.connection().map_err(|e| { + error!("Could not connect database: `{e}`"); + Status::InternalServerError + })?; + match conn.image(image_id).map_err(|e| { + error!("Could not get content image `{image_id}`: `{e}`"); + Status::InternalServerError + })? { + Some(image) => Ok((ContentType::Bytes, image.data)), + None => Err(Status::NotFound), + } +} + #[get("/rss?")] fn rss( search: Option<&str>, @@ -221,7 +239,7 @@ fn rocket() -> _ { title: config.title, version: env!("CARGO_PKG_VERSION").into(), }) - .mount("/", routes![index, rss, info]) + .mount("/", routes![index, rss, info, image]) } const S: &str = " • "; diff --git a/crates/http/templates/index.html.tera b/crates/http/templates/index.html.tera index d695261..1e87e54 100644 --- a/crates/http/templates/index.html.tera +++ b/crates/http/templates/index.html.tera @@ -5,10 +5,7 @@

{{ row.title }}

- {% if row.time %}

{{ row.time }}

{% endif %} -
- {{ row.description | safe }} -
+ {{ row.time }}
{% endfor %} {% else %} diff --git a/crates/mysql/src/connection.rs b/crates/mysql/src/connection.rs index c59e2df..6b6bda6 100644 --- a/crates/mysql/src/connection.rs +++ b/crates/mysql/src/connection.rs @@ -80,11 +80,15 @@ impl Connection { ) } - pub fn images(&mut self, limit: Option) -> Result, Error> { - self.conn.query(format!( - "SELECT `image_id`, `source`, `data` FROM `image` LIMIT {}", - limit.unwrap_or(DEFAULT_LIMIT) - )) + pub fn image(&mut self, image_id: u64) -> Result, Error> { + self.conn.exec_first( + "SELECT `image_id`, + `sha256`, + `src`, + `url`, + `data` FROM `image` WHERE `image_id` = ?", + (image_id,), + ) } pub fn provider_id_by_name(&mut self, name: &str) -> Result, Error> { diff --git a/crates/mysql/src/transaction.rs b/crates/mysql/src/transaction.rs index 919b56b..82618dc 100644 --- a/crates/mysql/src/transaction.rs +++ b/crates/mysql/src/transaction.rs @@ -107,6 +107,19 @@ impl Transaction { Ok(self.tx.last_insert_id().unwrap()) } + pub fn replace_content_description( + &mut self, + content_id: u64, + from: &str, + to: &str, + ) -> Result<(), Error> { + self.tx.exec_drop( + "UPDATE `content` SET `description` = REPLACE(`description`, ?, ?) + WHERE`content_id` = ?", + (from, to, content_id), + ) + } + pub fn insert_content_image(&mut self, content_id: u64, image_id: u64) -> Result { self.tx.exec_drop( "INSERT INTO `content_image` SET `content_id` = ?, `image_id` = ?",