feat: finsih qbit adapter

This commit is contained in:
master 2025-04-05 14:24:47 +08:00
parent b0c12acbc6
commit a3609696c7
4 changed files with 29 additions and 89 deletions

View File

@ -23,8 +23,7 @@ where
&self,
selector: Self::Selector,
) -> Result<Self::IdSelector, DownloaderError> {
let hashes =
<Self as TorrentDownloaderTrait>::query_torrent_hashes(&self, selector).await?;
let hashes = <Self as TorrentDownloaderTrait>::query_torrent_hashes(self, selector).await?;
self.pause_torrents(hashes).await
}
@ -32,16 +31,14 @@ where
&self,
selector: Self::Selector,
) -> Result<Self::IdSelector, DownloaderError> {
let hashes =
<Self as TorrentDownloaderTrait>::query_torrent_hashes(&self, selector).await?;
let hashes = <Self as TorrentDownloaderTrait>::query_torrent_hashes(self, selector).await?;
self.resume_torrents(hashes).await
}
async fn remove_downloads(
&self,
selector: Self::Selector,
) -> Result<Self::IdSelector, DownloaderError> {
let hashes =
<Self as TorrentDownloaderTrait>::query_torrent_hashes(&self, selector).await?;
let hashes = <Self as TorrentDownloaderTrait>::query_torrent_hashes(self, selector).await?;
self.remove_torrents(hashes).await
}

View File

@ -131,7 +131,7 @@ impl TorrentFileSource {
.boxed()
.and_then(|s| {
s.path_segments()
.and_then(|p| p.last())
.and_then(|mut p| p.next_back())
.map(String::from)
.ok_or_else(|| anyhow::anyhow!("invalid url"))
.to_dyn_boxed()

View File

@ -2,7 +2,6 @@ use std::{
borrow::Cow,
collections::{HashMap, HashSet},
fmt::Debug,
io,
sync::{Arc, Weak},
time::Duration,
};
@ -167,6 +166,7 @@ impl TorrentTaskTrait for QBittorrentTask {
.as_deref()
.unwrap_or("")
.split(',')
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map(Cow::Borrowed)
}
@ -357,7 +357,7 @@ impl QBittorrentDownloader {
save_path: creation.save_path.into(),
wait_sync_timeout: creation
.wait_sync_timeout
.unwrap_or(Duration::from_millis(10000)),
.unwrap_or(Duration::from_secs(10)),
downloader_id: creation.downloader_id,
sync_watch: watch::channel(Utc::now()).0,
sync_data: Arc::new(RwLock::new(QBittorrentSyncData::default())),
@ -433,8 +433,12 @@ impl QBittorrentDownloader {
category: &str,
) -> Result<(), DownloaderError> {
{
let category_no_exists = {
let sync_data = self.sync_data.read().await;
if !sync_data.categories.contains_key(category) {
!sync_data.categories.contains_key(category)
};
if category_no_exists {
self.add_category(category).await?;
}
}
@ -495,49 +499,6 @@ impl QBittorrentDownloader {
Ok(())
}
#[instrument(level = "debug", skip(self, replacer))]
pub async fn move_torrent_contents<F: FnOnce(String) -> String>(
&self,
hash: &str,
replacer: F,
) -> Result<(), DownloaderError> {
let old_path = {
let sync_data = self.sync_data.read().await;
sync_data
.torrents
.get(hash)
.and_then(|t| t.content_path.as_deref())
.ok_or_else(|| {
io::Error::new(
io::ErrorKind::NotFound,
"no torrent or torrent does not contain content path",
)
})?
.to_string()
};
let new_path = replacer(old_path.clone());
self.client
.rename_file(hash, old_path.clone(), new_path.to_string())
.await?;
self.wait_sync_until(
|sync_data| {
let torrents = &sync_data.torrents;
torrents.get(hash).is_some_and(|t| {
t.content_path.as_deref().is_some_and(|p| {
path_equals_as_file_url(p, &new_path)
.inspect_err(|error| {
tracing::warn!(name = "path_equals_as_file_url", error = ?error);
})
.unwrap_or(false)
})
})
},
None,
)
.await?;
Ok(())
}
#[instrument(level = "debug", skip(self))]
pub async fn move_torrents(
&self,
@ -608,17 +569,23 @@ impl QBittorrentDownloader {
where
S: Fn(&QBittorrentSyncData) -> bool,
{
{
let sync_data = &self.sync_data.read().await;
if stop_wait_fn(sync_data) {
return Ok(());
}
}
let timeout = timeout.unwrap_or(self.wait_sync_timeout);
let start_time = Utc::now();
let mut receiver = self.sync_watch.subscribe();
while let Ok(()) = receiver.changed().await {
let has_timeout = {
let sync_time = *receiver.borrow();
sync_time
.signed_duration_since(start_time)
.num_milliseconds()
> timeout.as_millis() as i64
let diff_time = sync_time - start_time;
diff_time.num_milliseconds() > timeout.as_millis() as i64
};
if has_timeout {
tracing::warn!(name = "wait_until timeout", timeout = ?timeout);
@ -958,7 +925,7 @@ pub mod tests {
.init();
let torrents_image = create_torrents_testcontainers().await?;
let torrents_container = torrents_image.start().await?;
let _torrents_container = torrents_image.start().await?;
let torrents_req = MockRequest {
id: "f10ebdda-dd2e-43f8-b80c-bf0884d071c4".into(),
@ -1022,8 +989,6 @@ pub mod tests {
)
.await?;
torrents_container.stop().await?;
Ok(())
}
@ -1090,12 +1055,11 @@ pub mod tests {
assert!(!files.is_empty());
let first_file = files.first().expect("should have first file");
assert_eq!(
&first_file.name,
r#"[Nekomoe kissaten&LoliHouse] Boku no Kokoro no Yabai Yatsu - 20 [WebRip 1080p HEVC-10bit AAC ASSx2].mkv"#
assert!(
&first_file.name.ends_with(r#"[Nekomoe kissaten&LoliHouse] Boku no Kokoro no Yabai Yatsu - 20 [WebRip 1080p HEVC-10bit AAC ASSx2].mkv"#)
);
let test_tag = format!("test_tag_{}", Utc::now().timestamp());
let test_tag = "test_tag".to_string();
downloader
.add_torrent_tags(vec![torrent_hash.clone()], vec![test_tag.clone()])
@ -1138,29 +1102,6 @@ pub mod tests {
)?
);
downloader
.move_torrent_contents(&torrent_hash, |f| {
f.replace(&folder_name, &format!("moved_{}", &folder_name))
})
.await?;
let target_torrent = get_torrent().await?;
let actual_content_path = &target_torrent
.torrent
.content_path
.expect("failed to get actual content path");
assert!(
path_equals_as_file_url(
actual_content_path,
base_save_path.join(actual_content_path)
)
.whatever_context::<_, RError>(
"failed to compare actual content path and found expected content path"
)?
);
downloader
.remove_torrents(vec![torrent_hash.clone()].into())
.await?;
@ -1175,6 +1116,8 @@ pub mod tests {
assert!(torrent_infos1.is_empty());
tracing::info!("test finished");
Ok(())
}
}

View File

@ -15,7 +15,7 @@ docker buildx build --platform linux/amd64 --tag konobangu-testing-torrents:late
## Run
```bash
docker run --network_mode=host --name konobangu-testing-torrents konobangu-testing-torrents:latest
docker run -p 6080:6080 -p 6081:6081 -p 6082:6082 --name konobangu-testing-torrents konobangu-testing-torrents:latest
```
## Publish