implement scrape frontend, optimize css, init static svg assets

This commit is contained in:
yggverse 2025-08-06 21:00:46 +03:00
parent 4d5e0f5b79
commit 70c0174fbc
7 changed files with 104 additions and 39 deletions

View file

@ -39,12 +39,20 @@ fn index(
use plurify::Plurify; use plurify::Plurify;
#[derive(Serialize)] #[derive(Serialize)]
#[serde(crate = "rocket::serde")] #[serde(crate = "rocket::serde")]
struct Scrape {
leechers: usize,
peers: usize,
seeders: usize,
}
#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct Row { struct Row {
created: Option<String>, created: Option<String>,
files: String,
indexed: String, indexed: String,
magnet: String, magnet: String,
scrape: Option<Scrape>,
size: String, size: String,
files: String,
torrent: Torrent, torrent: Torrent,
} }
let (total, torrents) = storage let (total, torrents) = storage
@ -69,6 +77,7 @@ fn index(
.map(|t| t.format(&meta.format_time).to_string()), .map(|t| t.format(&meta.format_time).to_string()),
indexed: torrent.time.format(&meta.format_time).to_string(), indexed: torrent.time.format(&meta.format_time).to_string(),
magnet: format::magnet(&torrent.info_hash, meta.trackers.as_ref()), magnet: format::magnet(&torrent.info_hash, meta.trackers.as_ref()),
scrape: None, // @TODO
size: format::bytes(torrent.size), size: format::bytes(torrent.size),
files: torrent.files.as_ref().map_or("1 file".into(), |f| { files: torrent.files.as_ref().map_or("1 file".into(), |f| {
let l = f.len(); let l = f.len();

View file

@ -15,9 +15,17 @@
transition: opacity .2s ease-in-out; transition: opacity .2s ease-in-out;
} }
:root {
--accent: #96d9a1;
--background: #282b3c;
--default: #ccc;
--item: #34384f;
}
body { body {
background: #282b3c; background: var(--background);
color: #ccc; color: var(--default);
font-family: Sans-serif; font-family: Sans-serif;
font-size: 13px; font-size: 13px;
} }
@ -25,7 +33,7 @@ body {
a, a,
a:visited, a:visited,
a:active { a:active {
color: #96d9a1; color: var(--accent);
text-decoration: none; text-decoration: none;
opacity: .9; opacity: .9;
} }
@ -40,7 +48,7 @@ h1 {
} }
h2 { h2 {
color: #ccc; color: var(--default);
font-size: 14px; font-size: 14px;
} }
@ -59,12 +67,12 @@ header > a,
header > a:active, header > a:active,
header > a:hover, header > a:hover,
header > a:visited { header > a:visited {
color: #ccc; color: var(--default);
font-size: 20px; font-size: 20px;
} }
header::first-letter { header::first-letter {
color: #96d9a1; color: var(--accent);
} }
header > div { header > div {
@ -82,7 +90,7 @@ main {
/* pagination */ /* pagination */
main > a { main > a {
background: #34384f; background: var(--item);
border-radius: 3px; border-radius: 3px;
float: right; float: right;
margin-left: 8px; margin-left: 8px;
@ -92,7 +100,7 @@ main > a {
/* item row */ /* item row */
main > div { main > div {
background-color: #34384f; background-color: var(--item);
border-radius: 3px; border-radius: 3px;
margin: 8px 0; margin: 8px 0;
padding: 24px; padding: 24px;
@ -122,6 +130,7 @@ main > div > div > ul > li {
main > div > div > ul > li > span { main > div > div > ul > li > span {
color: white; color: white;
display: inline-block;
font-size: smaller; font-size: smaller;
opacity: 0.7; opacity: 0.7;
} }
@ -135,9 +144,42 @@ main > div > div > ul > li:not(:last-child)::after {
margin: 0 6px; margin: 0 6px;
} }
main > div > div > a > svg { main > div > div > ul > li > span.leechers {
background-image: url('leechers.svg');
background-position: left center;
background-repeat: no-repeat;
padding-left: 16px;
}
main > div > div > ul > li > span.peers {
background-image: url('peers.svg');
background-position: left center;
background-repeat: no-repeat;
padding-left: 16px;
}
main > div > div > ul > li > span.seeders {
background-image: url('seeders.svg');
background-position: left center;
background-repeat: no-repeat;
padding-left: 16px;
}
/* control actions */
main > div > div > div {
float: right; float: right;
vertical-align: middle; }
main > div > div > div > a {
background-position: center;
background-repeat: no-repeat;
display: inline-block;
height: 16px;
width: 16px;
}
main > div > div > div > a.magnet {
background-image: url('magnet.svg');
} }
/* pagination info */ /* pagination info */
@ -147,6 +189,6 @@ main > span {
} }
footer { footer {
margin: 16px auto 24px; margin: 16px auto 36px;
text-align: center; text-align: center;
} }

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" fill="white" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6H.5ZM13 12.5a2.01 2.01 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5ZM2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175Z"/>
<path d="m4.4.8-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 3.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8Zm3 0-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 6.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8Zm3 0-.003.004-.014.019a4.077 4.077 0 0 0-.204.31 2.337 2.337 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.198 3.198 0 0 1-.202.388 5.385 5.385 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 9.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8Z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

3
static/theme/magnet.svg Normal file
View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" fill="#96d9a1" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 335 B

3
static/theme/peers.svg Normal file
View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" fill="white" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/>
</svg>

After

Width:  |  Height:  |  Size: 279 B

3
static/theme/seeders.svg Normal file
View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" fill="white" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 281 B

View file

@ -1,32 +1,33 @@
{% extends "layout/default" %} {% extends "layout/default" %}
{% block content %} {% block content %}
{% if rows %} {% if rows %}
{% for row in rows %} {% for row in rows %}
<div>
<a name="{{ row.torrent.info_hash }}"></a>
<h2>{{ row.torrent.name }}</h2>
{% if row.torrent.comment %}<p>{{ row.torrent.comment }}</p>{% endif %}
<div> <div>
<ul> <a name="{{ row.torrent.info_hash }}"></a>
<li><span title="Indexed">{{ row.indexed }}</span></li> <h2>{{ row.torrent.name }}</h2>
{% if row.created %}<li><span title="Created">({{ row.created }})</span></li>{% endif %} {% if row.torrent.comment %}<p>{{ row.torrent.comment }}</p>{% endif %}
{% if row.size %}<li><span title="Size">{{ row.size }}</span></li>{% endif %} <div>
<li><span title="Files">{{ row.files }}</span></li> <ul>
</ul> <li><span title="Indexed">{{ row.indexed }}</span></li>
<a rel="nofollow" href="{{ row.magnet }}" title="Magnet"> {% if row.created %}<li><span title="Created">({{ row.created }})</span></li>{% endif %}
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16"> {% if row.size %}<li><span title="Size">{{ row.size }}</span></li>{% endif %}
<path d="M15 12h-4v3h4v-3ZM5 12H1v3h4v-3ZM0 8a8 8 0 1 1 16 0v8h-6V8a2 2 0 1 0-4 0v8H0V8Z"/> <li><span title="Files">{{ row.files }}</span></li>
</svg> {% if row.scrape %}
</a> <li><span title="Seeders" class="seeders">{{ row.scrape.seeders }}</span></li>
<li><span title="Peers" class="peers">{{ row.scrape.seeders }}</span></li>
<li><span title="Leechers" class="leechers">{{ row.scrape.seeders }}</span></li>
{% endif %}
</ul>
<div>
<a rel="nofollow" href="{{ row.magnet }}" title="Get magnet" class="action magnet"></a>
</div>
</div>
</div> </div>
</div> {% endfor %}
{% endfor %} {% else %}
{% else %} <div>Nothing.</div>
<div> {% endif %}
Nothing. {% if next %}<a href="{{ next }}">Next</a>{% endif %}
</div> {% if back %}<a href="{{ back }}">Back</a>{% endif %}
{% endif %} <span>{{ pagination_totals }}</span>
{% if next %}<a href="{{ next }}">Next</a>{% endif %}
{% if back %}<a href="{{ back }}">Back</a>{% endif %}
<span>{{ pagination_totals }}</span>
{% endblock content %} {% endblock content %}