use build-in tera filters

This commit is contained in:
yggverse 2025-08-20 14:37:59 +03:00
parent c1ae25f04b
commit d95cee6c09
7 changed files with 51 additions and 53 deletions

View file

@ -18,5 +18,4 @@ chrono = { version = "0.4.41", features = ["serde"] }
url = { version = "2.5", features = ["serde"] } url = { version = "2.5", features = ["serde"] }
urlencoding = "2.1" urlencoding = "2.1"
rocket_dyn_templates = { version = "0.2", features = ["tera"] } rocket_dyn_templates = { version = "0.2", features = ["tera"] }
plurify = "0.2"
rand = "0.9" rand = "0.9"

View file

@ -70,7 +70,10 @@ impl Feed {
self.buffer.push_str("<description>"); self.buffer.push_str("<description>");
self.buffer self.buffer
.push_str(&format!("{}\n{}", torrent.size(), torrent.files())); .push_str(&format!("size: {}", size(torrent.size)));
if let Some(f) = torrent.files() {
self.buffer.push_str(&format!(" / files: {f}"));
}
self.buffer.push_str("</description>"); self.buffer.push_str("</description>");
self.buffer.push_str("<pubDate>"); self.buffer.push_str("<pubDate>");
@ -87,6 +90,9 @@ impl Feed {
} }
} }
// @TODO use tera filters?
// https://keats.github.io/tera/docs/#built-in-filters
fn escape(value: &str) -> String { fn escape(value: &str) -> String {
value value
.replace('&', "&amp;") .replace('&', "&amp;")
@ -95,3 +101,21 @@ fn escape(value: &str) -> String {
.replace('"', "&quot;") .replace('"', "&quot;")
.replace("'", "&apos;") .replace("'", "&apos;")
} }
fn size(value: u64) -> String {
const KB: f32 = 1024.0;
const MB: f32 = KB * KB;
const GB: f32 = MB * KB;
let f = value as f32;
if f < KB {
format!("{value} B")
} else if f < MB {
format!("{:.2} KB", f / KB)
} else if f < GB {
format!("{:.2} MB", f / MB)
} else {
format!("{:.2} GB", f / GB)
}
}

View file

@ -11,7 +11,6 @@ mod torrent;
use config::Config; use config::Config;
use feed::Feed; use feed::Feed;
use meta::Meta; use meta::Meta;
use plurify::Plurify;
use public::{Order, Public, Sort}; use public::{Order, Public, Sort};
use rocket::{State, http::Status, response::content::RawXml, serde::Serialize}; use rocket::{State, http::Status, response::content::RawXml, serde::Serialize};
use rocket_dyn_templates::{Template, context}; use rocket_dyn_templates::{Template, context};
@ -31,11 +30,11 @@ fn index(
#[serde(crate = "rocket::serde")] #[serde(crate = "rocket::serde")]
struct R { struct R {
created: Option<String>, created: Option<String>,
files: String, files: Option<usize>,
indexed: String, indexed: String,
magnet: String, magnet: String,
scrape: Option<Scrape>, scrape: Option<Scrape>,
size: String, size: u64,
torrent: Torrent, torrent: Torrent,
} }
let (total, torrents) = public let (total, torrents) = public
@ -85,7 +84,7 @@ fn index(
indexed: torrent.time.format(&meta.format_time).to_string(), indexed: torrent.time.format(&meta.format_time).to_string(),
magnet: torrent.magnet(meta.trackers.as_ref()), magnet: torrent.magnet(meta.trackers.as_ref()),
scrape: scraper.scrape(&torrent.info_hash), scrape: scraper.scrape(&torrent.info_hash),
size: torrent.size(), size: torrent.size,
torrent torrent
}), }),
Err(e) => { Err(e) => {
@ -94,12 +93,9 @@ fn index(
} }
}) })
.collect::<Vec<R>>(), .collect::<Vec<R>>(),
pagination_totals: if total > 0 { Some(format!( page: page.unwrap_or(1),
"Page {} / {} ({total} {} total)", pages: (total as f64 / public.default_limit as f64).ceil(),
page.unwrap_or(1), total,
(total as f64 / public.default_limit as f64).ceil(),
total.plurify(&["torrent", "torrents", "torrents"])
)) } else { None },
search search
}, },
)) ))
@ -119,7 +115,7 @@ fn info(
struct F { struct F {
href: Option<String>, href: Option<String>,
path: String, path: String,
size: String, size: u64,
} }
let torrent = Torrent::from_public(&t.bytes, t.time).map_err(|e| { let torrent = Torrent::from_public(&t.bytes, t.time).map_err(|e| {
error!("Torrent parse error: `{e}`"); error!("Torrent parse error: `{e}`");
@ -147,7 +143,7 @@ fn info(
F { F {
href: public.href(&torrent.info_hash, &p), href: public.href(&torrent.info_hash, &p),
path: p, path: p,
size: f.size(), size: f.length,
} }
}) })
.collect::<Vec<F>>() .collect::<Vec<F>>()
@ -155,7 +151,7 @@ fn info(
indexed: torrent.time.format(&meta.format_time).to_string(), indexed: torrent.time.format(&meta.format_time).to_string(),
magnet: torrent.magnet(meta.trackers.as_ref()), magnet: torrent.magnet(meta.trackers.as_ref()),
scrape: scraper.scrape(&torrent.info_hash), scrape: scraper.scrape(&torrent.info_hash),
size: torrent.size(), size: torrent.size,
torrent torrent
}, },
)) ))

View file

@ -71,16 +71,8 @@ impl Torrent {
// Format getters // Format getters
pub fn files(&self) -> String { pub fn files(&self) -> Option<usize> {
use plurify::Plurify; self.files.as_ref().map(|f| f.len())
self.files.as_ref().map_or("1 file".into(), |f| {
let l = f.len();
format!("{l} {}", l.plurify(&["file", "files", "files"]))
})
}
pub fn size(&self) -> String {
size(self.size)
} }
pub fn magnet(&self, trackers: Option<&Vec<url::Url>>) -> String { pub fn magnet(&self, trackers: Option<&Vec<url::Url>>) -> String {
@ -98,21 +90,3 @@ impl Torrent {
b b
} }
} }
fn size(value: u64) -> String {
const KB: f32 = 1024.0;
const MB: f32 = KB * KB;
const GB: f32 = MB * KB;
let f = value as f32;
if f < KB {
format!("{value} B")
} else if f < MB {
format!("{:.2} KB", f / KB)
} else if f < GB {
format!("{:.2} MB", f / MB)
} else {
format!("{:.2} GB", f / GB)
}
}

View file

@ -12,7 +12,4 @@ impl File {
.map(|p| p.to_string_lossy().into()) .map(|p| p.to_string_lossy().into())
.unwrap_or("?".into()) .unwrap_or("?".into())
} }
pub fn size(&self) -> String {
super::size(self.length)
}
} }

View file

@ -10,8 +10,8 @@
<ul> <ul>
<li><span title="Indexed">{{ row.indexed }}</span></li> <li><span title="Indexed">{{ row.indexed }}</span></li>
{% if row.created %}<li><span title="Created">({{ row.created }})</span></li>{% endif %} {% if row.created %}<li><span title="Created">({{ row.created }})</span></li>{% endif %}
{% if row.size %}<li><span title="Size">{{ row.size }}</span></li>{% endif %} <li><span title="Size">{{ row.size | filesizeformat }}</span></li>
<li><span title="Files">{{ row.files }}</span></li> {% if row.files %}<li><span title="Files">{{ row.files }} file{{ row.files | pluralize(plural="s") }}</span></li>{% endif %}
{% if row.scrape %} {% if row.scrape %}
<li><span title="Seeders" class="seeders">{{ row.scrape.seeders }}</span></li> <li><span title="Seeders" class="seeders">{{ row.scrape.seeders }}</span></li>
<li><span title="Peers" class="peers">{{ row.scrape.peers }}</span></li> <li><span title="Peers" class="peers">{{ row.scrape.peers }}</span></li>
@ -29,5 +29,9 @@
{% endif %} {% endif %}
{% if next %}<a href="{{ next }}">Next</a>{% endif %} {% if next %}<a href="{{ next }}">Next</a>{% endif %}
{% if back %}<a href="{{ back }}">Back</a>{% endif %} {% if back %}<a href="{{ back }}">Back</a>{% endif %}
{% if pagination_totals %}<span>{{ pagination_totals }}</span>{% endif %} {% if total %}
<span>
Page {{ page }} / {{ pages }} ({{ total }} torrent{{ total | pluralize(plural="s") }} total)
</span>
{% endif %}
{% endblock content %} {% endblock content %}

View file

@ -6,9 +6,13 @@
<div> <div>
<ul> <ul>
<li><span title="Indexed">{{ indexed }}</span></li> <li><span title="Indexed">{{ indexed }}</span></li>
{% if created %}<li><span title="Created">({{ created }})</span></li>{% endif %} {% if created %}
<li><span title="Size">{{ size }}</span></li> <li><span title="Created">({{ created }})</span></li>
<li><span title="Files">{{ files_total }}</span></li> {% endif %}
<li><span title="Size">{{ size | filesizeformat }}</span></li>
{% if files_total %}
<li><span title="Files">{{ files_total }} file{{ files_total | pluralize(plural="s") }}</span></li>
{% endif %}
{% if scrape %} {% if scrape %}
<li><span title="Seeders" class="seeders">{{ scrape.seeders }}</span></li> <li><span title="Seeders" class="seeders">{{ scrape.seeders }}</span></li>
<li><span title="Peers" class="peers">{{ scrape.peers }}</span></li> <li><span title="Peers" class="peers">{{ scrape.peers }}</span></li>
@ -38,7 +42,7 @@
{{ file.path }} {{ file.path }}
{% endif %} {% endif %}
</td> </td>
<td>{{ file.size }}</td> <td>{{ file.size | filesizeformat }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>