feat: ability to categorize

This commit is contained in:
Mark
2026-03-02 00:28:51 +01:00
parent 19f51c5732
commit a9a02a3632
5 changed files with 176 additions and 116 deletions

View File

@@ -2,8 +2,8 @@ use std::{collections::BTreeMap, os::unix::fs::PermissionsExt, path::Path, time:
use tokio::time::Instant;
const SLASHINFO: &'static str = "/srv/tomatenmhark-slashinfo/";
const REDIRECT: &'static str = "/srv/tomatenmhark-redirect/";
const SLASHINFO: &str = "/srv/tomatenmhark-slashinfo/";
const REDIRECT: &str = "/srv/tomatenmhark-redirect/";
pub struct Status(
pub BTreeMap<String, (bool, bool, String, Option<String>, Option<Duration>)>,
@@ -40,36 +40,31 @@ impl Status {
);
let mut rest = BTreeMap::new();
if let Ok(rd) = std::fs::read_dir(SLASHINFO) {
for f in rd {
if let Ok(f) = f {
if let Some(id) = f.file_name().to_str() {
if !map.contains_key(id) {
let mut p = f.path();
p.push("desc");
if let Ok(desc) = std::fs::read_to_string(&p) {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info = info.starts_with(SLASHINFO)
&& info.try_exists().ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& redirect.try_exists().ok() == Some(true);
let desc = desc.trim();
if let Some(i) = desc.find('\n') {
rest.insert(
id.to_owned(),
(
info,
redirect,
desc[0..i].trim().to_owned(),
Some(desc[i + 1..].trim().to_owned()),
),
);
} else {
rest.insert(
id.to_owned(),
(info, redirect, desc.to_owned(), None),
);
}
for f in rd.filter_map(Result::ok) {
if let Some(id) = f.file_name().to_str() {
if !map.contains_key(id) {
let mut p = f.path();
p.push("desc");
if let Ok(desc) = std::fs::read_to_string(&p) {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info =
info.starts_with(SLASHINFO) && info.try_exists().ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& redirect.try_exists().ok() == Some(true);
let desc = desc.trim();
if let Some(i) = desc.find('\n') {
rest.insert(
id.to_owned(),
(
info,
redirect,
desc[0..i].trim().to_owned(),
Some(desc[i + 1..].trim().to_owned()),
),
);
} else {
rest.insert(id.to_owned(), (info, redirect, desc.to_owned(), None));
}
}
}
@@ -143,26 +138,25 @@ impl Status {
fn query_status_sync(mut func: impl FnMut(&str, bool, bool, &str, Option<Duration>), dbg: bool) {
if let Ok(rd) = std::fs::read_dir("/tmp/") {
for f in rd {
if let Ok(f) = f {
if let Some(name) = f.file_name().to_str() {
if name.starts_with("tomatenmhark-status-") {
let id = name["tomatenmhark-status-".len()..].trim();
if !id.is_empty() {
if let Ok(status) = std::fs::read_to_string(f.path())
.as_ref()
.map(|v| v.trim_end())
{
if !status.is_empty() {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info = info.starts_with(SLASHINFO)
&& info.try_exists().ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& redirect.try_exists().ok() == Some(true);
func(id, info, redirect, status, None);
}
}
for f in rd.filter_map(Result::ok) {
if let Some(name) = f.file_name().to_str() {
if let Some(id) = name
.strip_prefix("tomatenmhark-status-")
.map(|v| v.trim())
.filter(|v| !v.is_empty())
{
if let Ok(status) = std::fs::read_to_string(f.path())
.as_ref()
.map(|v| v.trim_end())
{
if !status.is_empty() {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info =
info.starts_with(SLASHINFO) && info.try_exists().ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& redirect.try_exists().ok() == Some(true);
func(id, info, redirect, status, None);
}
}
}
@@ -170,28 +164,26 @@ fn query_status_sync(mut func: impl FnMut(&str, bool, bool, &str, Option<Duratio
}
}
if let Ok(rd) = std::fs::read_dir("/srv/tomatenmhark-dystatus/") {
for f in rd {
if let Ok(f) = f {
if let Some(name) = f.file_name().to_str() {
if f.metadata()
.is_ok_and(|meta| meta.is_file() && meta.permissions().mode() & 1 == 1)
{
let id = name.trim();
if !id.is_empty() {
let start = dbg.then(Instant::now);
if let Ok(output) = std::process::Command::new(f.path()).output() {
let elapsed = start.map(|v| v.elapsed());
let out = String::from_utf8_lossy(&output.stdout);
let out = out.trim_end();
if dbg || !out.is_empty() {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info = info.starts_with(SLASHINFO)
&& info.try_exists().ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& redirect.try_exists().ok() == Some(true);
func(id, info, redirect, out, elapsed);
}
for f in rd.filter_map(Result::ok) {
if let Some(name) = f.file_name().to_str() {
if f.metadata()
.is_ok_and(|meta| meta.is_file() && meta.permissions().mode() & 1 == 1)
{
let id = name.trim();
if !id.is_empty() {
let start = dbg.then(Instant::now);
if let Ok(output) = std::process::Command::new(f.path()).output() {
let elapsed = start.map(|v| v.elapsed());
let out = String::from_utf8_lossy(&output.stdout);
let out = out.trim_end();
if dbg || !out.is_empty() {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info = info.starts_with(SLASHINFO)
&& info.try_exists().ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& redirect.try_exists().ok() == Some(true);
func(id, info, redirect, out, elapsed);
}
}
}
@@ -207,23 +199,24 @@ async fn query_status_async(
if let Ok(mut rd) = tokio::fs::read_dir("/tmp/").await {
while let Ok(Some(f)) = rd.next_entry().await {
if let Some(name) = f.file_name().to_str() {
if name.starts_with("tomatenmhark-status-") {
let id = name["tomatenmhark-status-".len()..].trim();
if !id.is_empty() {
if let Ok(status) = tokio::fs::read_to_string(f.path())
.await
.as_ref()
.map(|v| v.trim_end())
{
if !status.is_empty() {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info = info.starts_with(SLASHINFO)
&& tokio::fs::try_exists(info).await.ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& tokio::fs::try_exists(redirect).await.ok() == Some(true);
func(id, info, redirect, status, None);
}
if let Some(id) = name
.strip_prefix("tomatenmhark-status-")
.map(|v| v.trim())
.filter(|v| !v.is_empty())
{
if let Ok(status) = tokio::fs::read_to_string(f.path())
.await
.as_ref()
.map(|v| v.trim_end())
{
if !status.is_empty() {
let info = Path::new(SLASHINFO).join(id).join("index.html");
let info = info.starts_with(SLASHINFO)
&& tokio::fs::try_exists(info).await.ok() == Some(true);
let redirect = Path::new(REDIRECT).join(id);
let redirect = redirect.starts_with(REDIRECT)
&& tokio::fs::try_exists(redirect).await.ok() == Some(true);
func(id, info, redirect, status, None);
}
}
}