mirror of
https://github.com/YGGverse/btracker.git
synced 2026-03-31 17:15:31 +00:00
use link to the info page instead of magnet, update feed transaction logic
This commit is contained in:
parent
9bc434375f
commit
add71e9749
2 changed files with 66 additions and 71 deletions
108
src/feed.rs
108
src/feed.rs
|
|
@ -3,94 +3,94 @@ use url::Url;
|
||||||
|
|
||||||
/// Export crawl index to the RSS file
|
/// Export crawl index to the RSS file
|
||||||
pub struct Feed {
|
pub struct Feed {
|
||||||
description: Option<String>,
|
buffer: String,
|
||||||
link: Option<String>,
|
canonical: Option<Url>,
|
||||||
title: String,
|
|
||||||
trackers: Option<Vec<Url>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Feed {
|
impl Feed {
|
||||||
pub fn init(
|
pub fn new(
|
||||||
title: String,
|
title: &str,
|
||||||
description: Option<String>,
|
description: Option<&str>,
|
||||||
link: Option<Url>,
|
canonical: Option<Url>,
|
||||||
trackers: Option<Vec<Url>>,
|
capacity: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
|
||||||
description: description.map(escape),
|
|
||||||
link: link.map(|s| escape(s.to_string())),
|
|
||||||
title: escape(title),
|
|
||||||
trackers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn transaction(&self, capacity: usize) -> String {
|
|
||||||
let t = chrono::Utc::now().to_rfc2822();
|
let t = chrono::Utc::now().to_rfc2822();
|
||||||
let mut b = String::with_capacity(capacity);
|
let mut buffer = String::with_capacity(capacity);
|
||||||
|
|
||||||
b.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss version=\"2.0\"><channel>");
|
buffer.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss version=\"2.0\"><channel>");
|
||||||
|
|
||||||
b.push_str("<pubDate>");
|
buffer.push_str("<pubDate>");
|
||||||
b.push_str(&t);
|
buffer.push_str(&t);
|
||||||
b.push_str("</pubDate>");
|
buffer.push_str("</pubDate>");
|
||||||
|
|
||||||
b.push_str("<lastBuildDate>");
|
buffer.push_str("<lastBuildDate>");
|
||||||
b.push_str(&t);
|
buffer.push_str(&t);
|
||||||
b.push_str("</lastBuildDate>");
|
buffer.push_str("</lastBuildDate>");
|
||||||
|
|
||||||
b.push_str("<title>");
|
buffer.push_str("<title>");
|
||||||
b.push_str(&self.title);
|
buffer.push_str(title);
|
||||||
b.push_str("</title>");
|
buffer.push_str("</title>");
|
||||||
|
|
||||||
if let Some(ref description) = self.description {
|
if let Some(d) = description {
|
||||||
b.push_str("<description>");
|
buffer.push_str("<description>");
|
||||||
b.push_str(description);
|
buffer.push_str(d);
|
||||||
b.push_str("</description>")
|
buffer.push_str("</description>")
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref link) = self.link {
|
if let Some(ref c) = canonical {
|
||||||
b.push_str("<link>");
|
// @TODO required the RSS specification!
|
||||||
b.push_str(link);
|
buffer.push_str("<link>");
|
||||||
b.push_str("</link>")
|
buffer.push_str(c.as_str());
|
||||||
|
buffer.push_str("</link>")
|
||||||
}
|
}
|
||||||
b
|
Self { buffer, canonical }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append `item` to the feed `channel`
|
/// Append `item` to the feed `channel`
|
||||||
pub fn push(&self, buffer: &mut String, torrent: Torrent) {
|
pub fn push(&mut self, torrent: Torrent) {
|
||||||
buffer.push_str(&format!(
|
self.buffer.push_str(&format!(
|
||||||
"<item><guid>{}</guid><title>{}</title><link>{}</link>",
|
"<item><guid>{}</guid><title>{}</title><link>{}</link>",
|
||||||
torrent.info_hash,
|
torrent.info_hash,
|
||||||
escape(
|
escape(
|
||||||
torrent
|
&torrent
|
||||||
.name
|
.name
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|b| b.to_string())
|
.map(|b| b.to_string())
|
||||||
.unwrap_or("?".into()) // @TODO
|
.unwrap_or("?".into()) // @TODO
|
||||||
),
|
),
|
||||||
escape(torrent.magnet(self.trackers.as_ref()))
|
self.canonical
|
||||||
|
.clone()
|
||||||
|
.map(|mut c| escape({
|
||||||
|
c.set_path(&torrent.info_hash);
|
||||||
|
c.set_fragment(None);
|
||||||
|
c.set_query(None);
|
||||||
|
c.as_str()
|
||||||
|
}))
|
||||||
|
.unwrap_or(escape(&torrent.info_hash)) // should be non-optional absolute URL
|
||||||
|
// by the RSS specification @TODO
|
||||||
));
|
));
|
||||||
|
|
||||||
buffer.push_str("<description>");
|
self.buffer.push_str("<description>");
|
||||||
buffer.push_str(&format!("{}\n{}", torrent.size(), torrent.files()));
|
self.buffer
|
||||||
buffer.push_str("</description>");
|
.push_str(&format!("{}\n{}", torrent.size(), torrent.files()));
|
||||||
|
self.buffer.push_str("</description>");
|
||||||
|
|
||||||
buffer.push_str("<pubDate>");
|
self.buffer.push_str("<pubDate>");
|
||||||
buffer.push_str(&torrent.time.to_rfc2822());
|
self.buffer.push_str(&torrent.time.to_rfc2822());
|
||||||
buffer.push_str("</pubDate>");
|
self.buffer.push_str("</pubDate>");
|
||||||
|
|
||||||
buffer.push_str("</item>")
|
self.buffer.push_str("</item>")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write final bytes
|
/// Write final bytes
|
||||||
pub fn commit(&self, mut buffer: String) -> String {
|
pub fn commit(mut self) -> String {
|
||||||
buffer.push_str("</channel></rss>");
|
self.buffer.push_str("</channel></rss>");
|
||||||
buffer
|
self.buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn escape(subject: String) -> String {
|
fn escape(value: &str) -> String {
|
||||||
subject
|
value
|
||||||
.replace('&', "&")
|
.replace('&', "&")
|
||||||
.replace('<', "<")
|
.replace('<', "<")
|
||||||
.replace('>', ">")
|
.replace('>', ">")
|
||||||
|
|
|
||||||
29
src/main.rs
29
src/main.rs
|
|
@ -141,8 +141,13 @@ fn info(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/rss")]
|
#[get("/rss")]
|
||||||
fn rss(feed: &State<Feed>, public: &State<Public>) -> Result<RawXml<String>, Custom<String>> {
|
fn rss(meta: &State<Meta>, public: &State<Public>) -> Result<RawXml<String>, Custom<String>> {
|
||||||
let mut b = feed.transaction(1024); // @TODO
|
let mut f = Feed::new(
|
||||||
|
&meta.title,
|
||||||
|
meta.description.as_deref(),
|
||||||
|
meta.canonical.clone(),
|
||||||
|
1024, // @TODO
|
||||||
|
);
|
||||||
for t in public
|
for t in public
|
||||||
.torrents(
|
.torrents(
|
||||||
Some((Sort::Modified, Order::Desc)),
|
Some((Sort::Modified, Order::Desc)),
|
||||||
|
|
@ -155,27 +160,18 @@ fn rss(feed: &State<Feed>, public: &State<Public>) -> Result<RawXml<String>, Cus
|
||||||
})?
|
})?
|
||||||
.1
|
.1
|
||||||
{
|
{
|
||||||
feed.push(
|
f.push(Torrent::from_public(&t.bytes, t.time).map_err(|e| {
|
||||||
&mut b,
|
error!("Torrent parse error: `{e}`");
|
||||||
Torrent::from_public(&t.bytes, t.time).map_err(|e| {
|
Custom(Status::InternalServerError, E.to_string())
|
||||||
error!("Torrent parse error: `{e}`");
|
})?)
|
||||||
Custom(Status::InternalServerError, E.to_string())
|
|
||||||
})?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Ok(RawXml(feed.commit(b)))
|
Ok(RawXml(f.commit()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
fn rocket() -> _ {
|
fn rocket() -> _ {
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
let config = Config::parse();
|
let config = Config::parse();
|
||||||
let feed = Feed::init(
|
|
||||||
config.title.clone(),
|
|
||||||
config.description.clone(),
|
|
||||||
config.canonical_url.clone(),
|
|
||||||
config.tracker.clone(),
|
|
||||||
);
|
|
||||||
let scraper = Scraper::init(
|
let scraper = Scraper::init(
|
||||||
config
|
config
|
||||||
.scrape
|
.scrape
|
||||||
|
|
@ -215,7 +211,6 @@ fn rocket() -> _ {
|
||||||
rocket::Config::default()
|
rocket::Config::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.manage(feed)
|
|
||||||
.manage(scraper)
|
.manage(scraper)
|
||||||
.manage(Public::init(config.public.clone(), config.list_limit, config.capacity).unwrap())
|
.manage(Public::init(config.public.clone(), config.list_limit, config.capacity).unwrap())
|
||||||
.manage(Meta {
|
.manage(Meta {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue