fix: fix paths

This commit is contained in:
master 2025-04-05 10:40:48 +08:00
parent 3dfcf2a536
commit b0c12acbc6
4 changed files with 46 additions and 61 deletions

View File

@ -587,6 +587,7 @@ impl QBittorrentDownloader {
Ok(torrent.save_path.take()) Ok(torrent.save_path.take())
} }
#[instrument(level = "debug", skip(self))]
async fn sync_data(&self) -> Result<(), DownloaderError> { async fn sync_data(&self) -> Result<(), DownloaderError> {
let rid = { self.sync_data.read().await.rid }; let rid = { self.sync_data.read().await.rid };
let sync_data_patch = self.client.sync(Some(rid)).await?; let sync_data_patch = self.client.sync(Some(rid)).await?;
@ -649,7 +650,7 @@ impl DownloaderTrait for QBittorrentDownloader {
&self, &self,
creation: Self::Creation, creation: Self::Creation,
) -> Result<HashSet<Self::Id>, DownloaderError> { ) -> Result<HashSet<Self::Id>, DownloaderError> {
let tag = { let tags = {
let mut tags = vec![TORRENT_TAG_NAME.to_string()]; let mut tags = vec![TORRENT_TAG_NAME.to_string()];
tags.extend(creation.tags); tags.extend(creation.tags);
Some(tags.into_iter().filter(|s| !s.is_empty()).join(",")) Some(tags.into_iter().filter(|s| !s.is_empty()).join(","))
@ -658,7 +659,7 @@ impl DownloaderTrait for QBittorrentDownloader {
let save_path = Some(creation.save_path.into_string()); let save_path = Some(creation.save_path.into_string());
let sources = creation.sources; let sources = creation.sources;
let ids = HashSet::from_iter(sources.iter().map(|s| s.hash_info().to_string())); let hashes = HashSet::from_iter(sources.iter().map(|s| s.hash_info().to_string()));
let (urls_source, files_source) = { let (urls_source, files_source) = {
let mut urls = vec![]; let mut urls = vec![];
let mut files = vec![]; let mut files = vec![];
@ -691,7 +692,20 @@ impl DownloaderTrait for QBittorrentDownloader {
) )
}; };
let category = TORRENT_TAG_NAME.to_string(); let category = creation.category;
if let Some(category) = category.as_deref() {
let has_caetgory = {
self.sync_data
.read()
.await
.categories
.contains_key(category)
};
if !has_caetgory {
self.add_category(category).await?;
}
}
if let Some(source) = urls_source { if let Some(source) = urls_source {
self.client self.client
@ -699,8 +713,8 @@ impl DownloaderTrait for QBittorrentDownloader {
source, source,
savepath: save_path.clone(), savepath: save_path.clone(),
auto_torrent_management: Some(false), auto_torrent_management: Some(false),
category: Some(category.clone()), category: category.clone(),
tags: tag.clone(), tags: tags.clone(),
..Default::default() ..Default::default()
}) })
.await?; .await?;
@ -710,10 +724,10 @@ impl DownloaderTrait for QBittorrentDownloader {
self.client self.client
.add_torrent(AddTorrentArg { .add_torrent(AddTorrentArg {
source, source,
savepath: save_path.clone(), savepath: save_path,
auto_torrent_management: Some(false), auto_torrent_management: Some(false),
category: Some(category.clone()), category,
tags: tag, tags,
..Default::default() ..Default::default()
}) })
.await?; .await?;
@ -721,12 +735,12 @@ impl DownloaderTrait for QBittorrentDownloader {
self.wait_sync_until( self.wait_sync_until(
|sync_data| { |sync_data| {
let torrents = &sync_data.torrents; let torrents = &sync_data.torrents;
ids.iter().all(|id| torrents.contains_key(id)) hashes.iter().all(|hash| torrents.contains_key(hash))
}, },
None, None,
) )
.await?; .await?;
Ok(ids) Ok(hashes)
} }
async fn pause_downloads( async fn pause_downloads(
@ -769,6 +783,7 @@ impl DownloaderTrait for QBittorrentDownloader {
} }
})) }))
.await?; .await?;
let tasks = torrent_list let tasks = torrent_list
.into_iter() .into_iter()
.zip(torrent_contents) .zip(torrent_contents)
@ -938,7 +953,7 @@ pub mod tests {
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_max_level(tracing::Level::TRACE) .with_max_level(tracing::Level::DEBUG)
.with_test_writer() .with_test_writer()
.init(); .init();
@ -946,16 +961,16 @@ pub mod tests {
let torrents_container = torrents_image.start().await?; let torrents_container = torrents_image.start().await?;
let torrents_req = MockRequest { let torrents_req = MockRequest {
id: "test".into(), id: "f10ebdda-dd2e-43f8-b80c-bf0884d071c4".into(),
file_list: vec![MockFileItem { file_list: vec![MockFileItem {
path: "test.torrent".into(), path: "[Nekomoe kissaten&LoliHouse] Boku no Kokoro no Yabai Yatsu - 20 [WebRip \
1080p HEVC-10bit AAC ASSx2].mkv"
.into(),
size: 1024, size: 1024,
}], }],
}; };
let torrent_res: MockResponse = reqwest::Client::builder() let torrent_res: MockResponse = reqwest::Client::new()
.pool_max_idle_per_host(0)
.build()?
.post("http://127.0.0.1:6080/api/torrents/mock") .post("http://127.0.0.1:6080/api/torrents/mock")
.json(&torrents_req) .json(&torrents_req)
.send() .send()
@ -988,10 +1003,7 @@ pub mod tests {
let password = logs let password = logs
.lines() .lines()
.find_map(|line| { .find_map(|line| {
if line.contains( if line.contains("A temporary password is provided for") {
"A temporary password is provided for this
session",
) {
line.split_whitespace().last() line.split_whitespace().last()
} else { } else {
None None
@ -1074,6 +1086,7 @@ pub mod tests {
let target_torrent = get_torrent().await?; let target_torrent = get_torrent().await?;
let files = target_torrent.contents; let files = target_torrent.contents;
assert!(!files.is_empty()); assert!(!files.is_empty());
let first_file = files.first().expect("should have first file"); let first_file = files.first().expect("should have first file");

View File

@ -6,7 +6,6 @@ import fsp from 'node:fs/promises';
import path from 'node:path'; import path from 'node:path';
// @ts-ignore // @ts-ignore
import TrackerServer from 'bittorrent-tracker/server'; import TrackerServer from 'bittorrent-tracker/server';
import createTorrent from 'create-torrent';
import WebTorrent, { type Torrent } from 'webtorrent'; import WebTorrent, { type Torrent } from 'webtorrent';
// Configuration // Configuration
@ -17,7 +16,7 @@ const STATIC_API_PATH = '/api/static';
const LOCAL_IP = '127.0.0.1'; const LOCAL_IP = '127.0.0.1';
const WORKSPACE_PATH = 'workspace'; const WORKSPACE_PATH = 'workspace';
const TRACKER_URL = `http://${LOCAL_IP}:${TRACKER_PORT}/announce`; const TRACKER_URL = `http://${LOCAL_IP}:${TRACKER_PORT}/announce`;
const API_BASE_URL = `http://${LOCAL_IP}:${API_PORT}/${STATIC_API_PATH}/`; const API_BASE_URL = `http://${LOCAL_IP}:${API_PORT}${STATIC_API_PATH}/`;
// Initialize Fastify instance // Initialize Fastify instance
const app = Fastify({ logger: true }); const app = Fastify({ logger: true });
@ -90,44 +89,22 @@ async function generateMockFile(filePath: string, size: number) {
await fsp.truncate(filePath, size); await fsp.truncate(filePath, size);
} }
// Generate bittorrent file // Add bittorrent and seed
function generateTorrent(folderPath: string, torrentPath: string) { async function seedTorrent(
return new Promise<void>((resolve, reject) => { torrentPath: string,
createTorrent( contentFolder: string
folderPath, ): Promise<Torrent> {
return new Promise((resolve) => {
const torrent = webTorrent.seed(
contentFolder,
{ {
announceList: [[TRACKER_URL]], // Specify tracker URL announceList: [[TRACKER_URL]], // Specify tracker URL
private: false, private: false,
createdBy: 'WebTorrent', createdBy: 'Konobangu Testing Torrents',
comment: 'Generated by WebTorrent server',
urlList: [API_BASE_URL], urlList: [API_BASE_URL],
}, },
async (err, torrent) => { async (t) => {
if (err) { await fsp.writeFile(torrentPath, t.torrentFile);
reject(new Error(`Failed to create torrent: ${err}`));
return;
}
await fsp.writeFile(torrentPath, torrent);
if (!fs.existsSync(torrentPath)) {
reject(new Error(`Torrent file ${torrentPath} was not created`));
return;
}
console.log(`Generated torrent with tracker: ${TRACKER_URL}`);
resolve();
}
);
});
}
// Add bittorrent and seed
async function seedTorrent(torrentPath: string): Promise<Torrent> {
return new Promise((resolve) => {
const torrent = webTorrent.seed(
torrentPath,
{
announce: [TRACKER_URL],
},
(t) => {
resolve(t); resolve(t);
} }
); );
@ -156,9 +133,8 @@ app.post<{ Body: RequestSchema }>('/api/torrents/mock', async (req, _reply) => {
} }
const torrentPath = path.join(WORKSPACE_PATH, `${id}.torrent`); const torrentPath = path.join(WORKSPACE_PATH, `${id}.torrent`);
await generateTorrent(idFolder, torrentPath);
const torrent = await seedTorrent(torrentPath); const torrent = await seedTorrent(torrentPath, idFolder);
const magnetUrl = `magnet:?xt=urn:btih:${torrent.infoHash}&tr=${TRACKER_URL}`; const magnetUrl = `magnet:?xt=urn:btih:${torrent.infoHash}&tr=${TRACKER_URL}`;
return { return {

View File

@ -10,7 +10,6 @@
"dependencies": { "dependencies": {
"@fastify/static": "^8.1.1", "@fastify/static": "^8.1.1",
"bittorrent-tracker": "^11.2.1", "bittorrent-tracker": "^11.2.1",
"create-torrent": "^6.1.0",
"fastify": "^5.2.2", "fastify": "^5.2.2",
"tsx": "^4.19.2", "tsx": "^4.19.2",
"webtorrent": "^2.5.19" "webtorrent": "^2.5.19"

View File

@ -14,9 +14,6 @@ importers:
bittorrent-tracker: bittorrent-tracker:
specifier: ^11.2.1 specifier: ^11.2.1
version: 11.2.1 version: 11.2.1
create-torrent:
specifier: ^6.1.0
version: 6.1.0
fastify: fastify:
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2 version: 5.2.2