From 7da285ca699abf32e6ecfc6cbc747a23c871ab8c Mon Sep 17 00:00:00 2001 From: yggverse Date: Tue, 5 Aug 2025 15:06:44 +0300 Subject: [PATCH] implement magnet links --- src/feed.rs | 24 +++--------------------- src/format.rs | 15 +++++++++++++++ src/main.rs | 23 ++++++++++++++++++----- templates/index.html.tera | 17 ++++++++++++----- templates/layout/default.html.tera | 10 ++++++++++ 5 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/feed.rs b/src/feed.rs index 8c2daa7..95cae11 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -7,8 +7,7 @@ pub struct Feed { description: Option, link: Option, title: String, - /// Valid, parsed from Url, ready-to-use address string donor - trackers: Option>, + trackers: Option>, } impl Feed { @@ -22,7 +21,7 @@ impl Feed { description: description.map(escape), link: link.map(|s| escape(s.to_string())), title: escape(title), - trackers: trackers.map(|v| v.into_iter().map(|u| u.to_string()).collect()), + trackers, } } @@ -70,7 +69,7 @@ impl Feed { .map(|b| b.to_string()) .unwrap_or("?".into()) // @TODO ), - escape(self.magnet(&torrent.info_hash)) + escape(format::magnet(&torrent.info_hash, self.trackers.as_ref())) )); if let Some(d) = item_description(torrent.length, torrent.files) { @@ -91,23 +90,6 @@ impl Feed { buffer.push_str(""); buffer } - - // Tools - - fn magnet(&self, info_hash: &str) -> String { - let mut b = if info_hash.len() == 40 { - format!("magnet:?xt=urn:btih:{info_hash}") - } else { - todo!("info-hash v2 is not supported by librqbit") - }; - if let Some(ref trackers) = self.trackers { - for tracker in trackers { - b.push_str("&tr="); - b.push_str(&urlencoding::encode(tracker)) - } - } - b - } } fn escape(subject: String) -> String { diff --git a/src/format.rs b/src/format.rs index e5ffd96..b3b0d11 100644 --- a/src/format.rs +++ b/src/format.rs @@ -15,3 +15,18 @@ pub fn bytes(value: u64) -> String { format!("{:.2} GB", f / GB) } } + +pub fn magnet(info_hash: &str, trackers: Option<&std::collections::HashSet>) -> String { + let mut b = if info_hash.len() == 40 { + format!("magnet:?xt=urn:btih:{info_hash}") + } else { + todo!("info-hash v2 is not supported by librqbit") + }; + if let Some(t) = trackers { + for tracker in t { + b.push_str("&tr="); + b.push_str(&urlencoding::encode(tracker.as_str())) + } + } + b +} diff --git a/src/main.rs b/src/main.rs index 31d5ba6..13e79a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,8 @@ use rocket::{ serde::Serialize, }; use rocket_dyn_templates::{Template, context}; -use storage::{Order, Sort, Storage}; +use std::collections::HashSet; +use storage::{Order, Sort, Storage, Torrent}; use url::Url; #[derive(Clone, Debug, Serialize)] @@ -25,21 +26,33 @@ pub struct Meta { pub description: Option, pub stats: Option, pub title: String, - pub trackers: Option>, + pub trackers: Option>, } #[get("/")] fn index(storage: &State, meta: &State) -> Result> { + #[derive(Serialize)] + #[serde(crate = "rocket::serde")] + struct Row { + torrent: Torrent, + magnet: String, + } Ok(Template::render( "index", context! { meta: meta.inner(), - torrents: storage + rows: storage .torrents( Some((Sort::Modified, Order::Asc)), Some(storage.default_limit), ) .map_err(|e| Custom(Status::InternalServerError, e.to_string()))? + .into_iter() + .map(|torrent| Row { + magnet: format::magnet(&torrent.info_hash, meta.trackers.as_ref()), + torrent, + }) + .collect::>() }, )) } @@ -67,7 +80,7 @@ fn rocket() -> _ { config.title.clone(), config.description.clone(), config.link.clone(), - config.tracker.clone().map(|u| u.into_iter().collect()), // make sure it's unique + config.tracker.clone().map(|u| u.into_iter().collect()), ); let storage = Storage::init(config.storage, config.limit, config.capacity).unwrap(); // @TODO handle rocket::build() @@ -84,7 +97,7 @@ fn rocket() -> _ { description: config.description, stats: config.stats, title: config.title, - trackers: config.tracker, + trackers: config.tracker.map(|u| u.into_iter().collect()), }) .mount("/", routes![index, rss]) } diff --git a/templates/index.html.tera b/templates/index.html.tera index b679e02..863b466 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -1,9 +1,16 @@ {% extends "layout/default" %} {% block content %} -{% for torrent in torrents %} -
- -

{{ torrent.name }}

-
+{% for row in rows %} +
+ +

{{ row.torrent.name }}

+ +
{% endfor %} {% endblock content %} \ No newline at end of file diff --git a/templates/layout/default.html.tera b/templates/layout/default.html.tera index e490cec..6af7a3e 100644 --- a/templates/layout/default.html.tera +++ b/templates/layout/default.html.tera @@ -86,12 +86,22 @@ margin: 0 auto; } + /* item row */ main > div { background-color: #34384f; border-radius: 3px; margin: 8px 0; padding: 24px; } + + /* controls */ + main > div > div { + float: right; + } + + main > div > div > a> svg { + vertical-align: middle; + }