implement public storage preview

This commit is contained in:
yggverse 2025-09-09 00:12:34 +03:00
parent 1786f999a8
commit 4dd4ef6f55
3 changed files with 51 additions and 9 deletions

View file

@ -157,7 +157,33 @@ fn response(
use titanite::response::*;
debug!("Incoming request from `{peer}` to `{}`", request.url.path());
send(
&match Route::from_url(&request.url) {
&match Route::from_url(&request.url, public) {
Route::File(ref path) => success::Default {
data: &std::fs::read(path).unwrap(),
meta: success::default::Meta {
mime: match path.extension() {
Some(extension) => {
let e = extension.to_ascii_lowercase();
if e == "jpeg" || e == "jpg" {
"image/jpeg"
} else if e == "gif" {
"image/gif"
} else if e == "png" {
"image/png"
} else if e == "webp" {
"image/webp"
} else if e == "txt" || e == "log" {
"text/plain"
} else {
todo!()
}
}
None => todo!(),
}
.to_string(),
},
}
.into_bytes(),
Route::List { page, keyword } => match list(config, public, keyword.as_deref(), page) {
Ok(data) => success::Default {
data: data.as_bytes(),
@ -179,7 +205,7 @@ fn response(
})
.into_bytes(),
Route::Info(id) => match public.torrent(id) {
Some(torrent) => match info(config, torrent) {
Some(torrent) => match info(config, public, torrent) {
Ok(data) => success::Default {
data: data.as_bytes(),
meta: success::default::Meta {
@ -337,7 +363,7 @@ fn list(
Ok(b.join("\n"))
}
fn info(config: &Config, torrent: Torrent) -> Result<String> {
fn info(config: &Config, public: &Public, torrent: Torrent) -> Result<String> {
struct File {
path: Option<PathBuf>,
length: u64,
@ -396,7 +422,16 @@ fn info(config: &Config, torrent: Torrent) -> Result<String> {
}) {
b.push("## Files\n".into());
for file in files {
b.push(format!("* {} ({})", file.path(), format::size(file.length)));
let p = file.path();
b.push(match public.href(&i.info_hash.as_string(), &p) {
Some(href) => format!(
"=> {} {} ({})",
urlencoding::encode(&href),
p,
format::size(file.length)
),
None => format!("{} ({})", p, format::size(file.length)), // * ?
})
}
}

View file

@ -1,10 +1,11 @@
use std::str::FromStr;
use btracker_fs::public::Public;
use librqbit_core::Id20;
use regex::Regex;
use std::{path::PathBuf, str::FromStr};
use url::Url;
pub enum Route {
File(PathBuf),
Info(Id20),
List {
keyword: Option<String>,
@ -15,8 +16,9 @@ pub enum Route {
}
impl Route {
pub fn from_url(url: &Url) -> Self {
let p = url.path().to_lowercase();
pub fn from_url(url: &Url, public: &Public) -> Self {
let p = urlencoding::decode(url.path()).ok().unwrap_or_default();
let t = p.trim_matches('/');
let q = url.query();
if p.is_empty() {
@ -26,7 +28,11 @@ impl Route {
};
}
if let Ok(id) = Id20::from_str(p.trim_matches('/')) {
if let Some(path) = public.filepath(t) {
return Self::File(path);
}
if let Ok(id) = Id20::from_str(t) {
return Self::Info(id);
}