mirror of
https://github.com/YGGverse/rssto.git
synced 2026-03-31 09:05:29 +00:00
implement local image features
This commit is contained in:
parent
3e94399ccb
commit
e86b241ee6
6 changed files with 52 additions and 21 deletions
|
|
@ -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)?;
|
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}`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
title = "rssto"
|
title = "rssto"
|
||||||
#description = ""
|
#description = ""
|
||||||
|
|
||||||
# Replace image sources with local
|
|
||||||
# * if crawled with the `persist_images_selector` selector
|
|
||||||
local_images = true
|
|
||||||
|
|
||||||
format_time = "%d/%m/%Y %H:%M"
|
format_time = "%d/%m/%Y %H:%M"
|
||||||
|
|
||||||
# Provider ID (`provider` table)
|
# Provider ID (`provider` table)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,12 @@ use feed::Feed;
|
||||||
use global::Global;
|
use global::Global;
|
||||||
use meta::Meta;
|
use meta::Meta;
|
||||||
use mysql::{Database, table::Sort};
|
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};
|
use rocket_dyn_templates::{Template, context};
|
||||||
|
|
||||||
#[get("/?<search>&<page>")]
|
#[get("/?<search>&<page>")]
|
||||||
|
|
@ -25,9 +30,8 @@ fn index(
|
||||||
) -> Result<Template, Status> {
|
) -> Result<Template, Status> {
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
struct Content {
|
struct Row {
|
||||||
content_id: u64,
|
content_id: u64,
|
||||||
description: String,
|
|
||||||
link: String,
|
link: String,
|
||||||
time: String,
|
time: String,
|
||||||
title: String,
|
title: String,
|
||||||
|
|
@ -81,15 +85,14 @@ fn index(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|content| {
|
.map(|content| {
|
||||||
let channel_item = conn.channel_item(content.channel_item_id).unwrap().unwrap();
|
let channel_item = conn.channel_item(content.channel_item_id).unwrap().unwrap();
|
||||||
Content {
|
Row {
|
||||||
content_id: content.content_id,
|
content_id: content.content_id,
|
||||||
description: content.description,
|
|
||||||
link: channel_item.link,
|
link: channel_item.link,
|
||||||
time: time(channel_item.pub_date).format(&global.format_time).to_string(),
|
time: time(channel_item.pub_date).format(&global.format_time).to_string(),
|
||||||
title: content.title,
|
title: content.title,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<Content>>(),
|
.collect::<Vec<Row>>(),
|
||||||
page: page.unwrap_or(1),
|
page: page.unwrap_or(1),
|
||||||
pages: (total as f64 / global.list_limit as f64).ceil(),
|
pages: (total as f64 / global.list_limit as f64).ceil(),
|
||||||
total,
|
total,
|
||||||
|
|
@ -140,6 +143,21 @@ fn info(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/image/<image_id>")]
|
||||||
|
fn image(image_id: u64, db: &State<Database>) -> Result<(ContentType, Vec<u8>), 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?<search>")]
|
#[get("/rss?<search>")]
|
||||||
fn rss(
|
fn rss(
|
||||||
search: Option<&str>,
|
search: Option<&str>,
|
||||||
|
|
@ -221,7 +239,7 @@ fn rocket() -> _ {
|
||||||
title: config.title,
|
title: config.title,
|
||||||
version: env!("CARGO_PKG_VERSION").into(),
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
})
|
})
|
||||||
.mount("/", routes![index, rss, info])
|
.mount("/", routes![index, rss, info, image])
|
||||||
}
|
}
|
||||||
|
|
||||||
const S: &str = " • ";
|
const S: &str = " • ";
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,7 @@
|
||||||
<div>
|
<div>
|
||||||
<a name="{{ row.content_id }}"></a>
|
<a name="{{ row.content_id }}"></a>
|
||||||
<h2><a href="{{ row.content_id }}">{{ row.title }}</a></h2>
|
<h2><a href="{{ row.content_id }}">{{ row.title }}</a></h2>
|
||||||
{% if row.time %}<p>{{ row.time }}</p>{% endif %}
|
{{ row.time }}
|
||||||
<div>
|
|
||||||
{{ row.description | safe }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,15 @@ impl Connection {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn images(&mut self, limit: Option<usize>) -> Result<Vec<Image>, Error> {
|
pub fn image(&mut self, image_id: u64) -> Result<Option<Image>, Error> {
|
||||||
self.conn.query(format!(
|
self.conn.exec_first(
|
||||||
"SELECT `image_id`, `source`, `data` FROM `image` LIMIT {}",
|
"SELECT `image_id`,
|
||||||
limit.unwrap_or(DEFAULT_LIMIT)
|
`sha256`,
|
||||||
))
|
`src`,
|
||||||
|
`url`,
|
||||||
|
`data` FROM `image` WHERE `image_id` = ?",
|
||||||
|
(image_id,),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provider_id_by_name(&mut self, name: &str) -> Result<Option<u64>, Error> {
|
pub fn provider_id_by_name(&mut self, name: &str) -> Result<Option<u64>, Error> {
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,19 @@ impl Transaction {
|
||||||
Ok(self.tx.last_insert_id().unwrap())
|
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<u64, Error> {
|
pub fn insert_content_image(&mut self, content_id: u64, image_id: u64) -> Result<u64, Error> {
|
||||||
self.tx.exec_drop(
|
self.tx.exec_drop(
|
||||||
"INSERT INTO `content_image` SET `content_id` = ?, `image_id` = ?",
|
"INSERT INTO `content_image` SET `content_id` = ?, `image_id` = ?",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue