mx-sanebot: pretty-print torrent search results

This commit is contained in:
Colin 2023-04-29 10:32:19 +00:00
parent f300cb1202
commit b5a6a7a57c
3 changed files with 69 additions and 14 deletions

View File

@ -1360,6 +1360,8 @@ dependencies = [
"matrix-sdk", "matrix-sdk",
"ruma", "ruma",
"ruma-client-api", "ruma-client-api",
"serde",
"serde_json",
"tokio", "tokio",
] ]

View File

@ -8,7 +8,9 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
futures = "0.3" futures = "0.3"
matrix-sdk = "0.6.2" matrix-sdk = "0.6.2" # TODO: bump
ruma = "*" # matrix-sdk dep ruma = "*" # matrix-sdk dep
ruma-client-api = "*" # ruma dep ruma-client-api = "*" # ruma dep
serde = "*"
serde_json = "*"
tokio = { version = "1.20.1", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.20.1", features = ["macros", "rt-multi-thread"] }

View File

@ -3,6 +3,9 @@ use std::fmt;
use std::process; use std::process;
use std::str; use std::str;
use serde_json;
use serde::Deserialize;
use super::parsing::{self, Parser}; use super::parsing::{self, Parser};
@ -200,24 +203,36 @@ impl Request {
fn evaluate(self) -> Response { fn evaluate(self) -> Response {
match self { match self {
Request::Help => Response::Help, Request::Help => Response::Help,
Request::Bt => Response::Bt( Request::Bt => match exec_stdout("sane-bt-show", &[]) {
exec_stdout("sane-bt-show", &[]) Some(m) => Response::Bt(m),
.unwrap_or_else(|| None => Response::Error("failed to execute sane-bt-show".to_owned()),
"failed to retrieve torrent status".to_owned()) },
), Request::BtSearch(phrase) => match exec_stdout("sane-bt-search", &[&*phrase, "--json"]) {
Request::BtSearch(phrase) => Response::BtSearch( Some(r) => match serde_json::from_str(&r) {
exec_stdout("sane-bt-search", &[&*phrase]) Ok(torrents) => Response::BtSearch(torrents),
.unwrap_or_else(|| Err(e) => Response::Error(format!("failed to decode sane-bt-search response: {e}\nresponse: {r}")),
"failed to complete torrent search".to_owned()) },
), None => Response::Error("failed to execute sane-bt-search".to_owned()),
},
} }
} }
} }
#[derive(Deserialize)]
pub struct Torrent {
seeders: u32,
pub_date: String, // YYYY-MM-DD
size: u64,
tracker: String,
title: String,
magnet: String,
}
pub enum Response { pub enum Response {
Error(String),
Help, Help,
Bt(String), Bt(String),
BtSearch(String), BtSearch(Vec<Torrent>),
} }
impl Response { impl Response {
@ -233,7 +248,42 @@ impl Response {
</ul> </ul>
"#.to_owned() "#.to_owned()
), ),
// not yet implemented Response::BtSearch(torrents) => Some({
let fmt_torrents = torrents.into_iter().map(|t| {
let Torrent {
seeders,
pub_date,
size,
tracker,
title,
magnet,
} = t;
let mib = size >> 20;
format!(r#"
<tr>
<th>{seeders}</th>
<th>{pub_date}</th>
<th>{mib}<th>
<th>{tracker}</th>
<th>{title}</th>
<th>{magnet}</th>
</tr>
"#)
}).collect::<String>();
format!(r#"
<table>
<tr>
<th>Seeders</th>
<th>Date</th>
<th>Size (MiB)</th>
<th>Tracker</th>
<th>Title</th>
<th>URL</th>
</tr>
{fmt_torrents}
</table>
"#)
}),
_ => None, _ => None,
} }
} }
@ -242,6 +292,7 @@ impl Response {
impl fmt::Display for Response { impl fmt::Display for Response {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Response::Error(e) => write!(f, "{}", e)?,
Response::Help => { Response::Help => {
write!(f, "commands:\n")?; write!(f, "commands:\n")?;
write!(f, " !help => show this message\n")?; write!(f, " !help => show this message\n")?;
@ -249,7 +300,7 @@ impl fmt::Display for Response {
write!(f, " !bt search <phrase> => search for torrents\n")?; write!(f, " !bt search <phrase> => search for torrents\n")?;
}, },
Response::Bt(stdout) => write!(f, "{}", stdout)?, Response::Bt(stdout) => write!(f, "{}", stdout)?,
Response::BtSearch(stdout) => write!(f, "{}", stdout)?, Response::BtSearch(torrents) => write!(f, "{} torrents", torrents.len())?,
} }
Ok(()) Ok(())
} }