make api source response optional, implement tests

This commit is contained in:
yggverse 2025-07-07 19:22:11 +03:00
parent 6a3915a3f5
commit 15c8d8c350
4 changed files with 140 additions and 141 deletions

View file

@ -1,10 +1,17 @@
/// Parse infohash from the source filepath, /// Parse infohash from the source filepath,
/// decode JSON to array on success, return None if the feed is damaged (incomplete) /// decode JSON to array on success, return None if the feed file is not reachable
pub fn infohashes(path: &str) -> anyhow::Result<Option<Vec<String>>> { pub fn get(path: &str) -> Option<Vec<String>> {
if path.contains("://") { if path.contains("://") {
todo!("URL sources yet not supported") todo!("URL sources yet not supported")
} }
let s = std::fs::read_to_string(path)?; let s = std::fs::read_to_string(path).ok()?; // is updating?
let r: Option<Vec<String>> = serde_json::from_str(&s).ok(); let r: Option<Vec<String>> = serde_json::from_str(&s).ok(); // is incomplete?
Ok(r) r
}
#[test]
fn test() {
assert!(get("test/api/0.json").is_none());
assert!(get("test/api/1.json").is_some());
assert!(get("test/api/2.json").is_none());
} }

View file

@ -88,10 +88,8 @@ async fn main() -> Result<()> {
debug.info(&format!("Index source `{source}`...")); debug.info(&format!("Index source `{source}`..."));
// grab latest info-hashes from this source // grab latest info-hashes from this source
// * aquatic server may update the stats at this moment, handle result manually // * aquatic server may update the stats at this moment, handle result manually
match api::infohashes(source) { for i in match api::get(source) {
Ok(infohashes) => { Some(i) => i,
for i in match infohashes {
Some(h) => h,
None => { None => {
// skip without panic // skip without panic
debug.error(&format!( debug.error(&format!(
@ -155,17 +153,17 @@ async fn main() -> Result<()> {
if let Some(ref p) = preload { if let Some(ref p) = preload {
for (id, info) in m.file_infos.iter().enumerate() { for (id, info) in m.file_infos.iter().enumerate() {
if p.matches(info.relative_filename.to_str().unwrap()) { if p.matches(info.relative_filename.to_str().unwrap()) {
if p.max_filesize.is_some_and( if p.max_filesize.is_some_and(|limit| {
|limit| only_files_size + info.len > limit, only_files_size + info.len > limit
) { }) {
debug.info(&format!( debug.info(&format!(
"Total files size limit `{i}` reached!" "Total files size limit `{i}` reached!"
)); ));
break; break;
} }
if p.max_filecount.is_some_and( if p.max_filecount
|limit| only_files.len() + 1 > limit, .is_some_and(|limit| only_files.len() + 1 > limit)
) { {
debug.info(&format!( debug.info(&format!(
"Total files count limit for `{i}` reached!" "Total files count limit for `{i}` reached!"
)); ));
@ -173,8 +171,8 @@ async fn main() -> Result<()> {
} }
only_files_size += info.len; only_files_size += info.len;
if let Some(ref p) = preload { if let Some(ref p) = preload {
only_files_keep.push( only_files_keep
p.absolute(&i, &info.relative_filename)) .push(p.absolute(&i, &info.relative_filename))
} }
only_files.insert(id); only_files.insert(id);
} }
@ -209,12 +207,7 @@ async fn main() -> Result<()> {
// use `r.info` for Memory, SQLite, // use `r.info` for Memory, SQLite,
// Manticore and other alternative storage type // Manticore and other alternative storage type
index.insert( index.insert(i, 0, r.info.name.map(|n| n.to_string()), r.info.length)
i,
0,
r.info.name.map(|n| n.to_string()),
r.info.length,
)
} }
// unexpected as should be deleted // unexpected as should be deleted
Ok(AddTorrentResponse::AlreadyManaged(..)) => panic!(), Ok(AddTorrentResponse::AlreadyManaged(..)) => panic!(),
@ -224,9 +217,7 @@ async fn main() -> Result<()> {
} }
} }
} }
Err(e) => debug.error(&format!("API issue for `{source}`: `{e}`")),
}
}
if let Some(ref export_rss) = config.export_rss if let Some(ref export_rss) = config.export_rss
&& index.is_changed() && index.is_changed()
{ {

0
test/api/0.json Normal file
View file

1
test/api/1.json Normal file
View file

@ -0,0 +1 @@
["1","2","3"]