server: handle case difference in ".torrent" download

This commit is contained in:
Jesse Chan
2021-01-13 18:55:23 +08:00
parent f56e320a9e
commit 1b03d3d180
5 changed files with 28 additions and 18 deletions
+8 -5
View File
@@ -569,15 +569,17 @@ router.get<{hashes: string}>(
return;
}
const sessionDirectory = await req.services?.clientGatewayService
?.getClientSessionDirectory()
.catch(() => undefined);
const {path: sessionDirectory, case: torrentCase} =
(await req.services?.clientGatewayService?.getClientSessionDirectory().catch(() => undefined)) || {};
if (sessionDirectory == null || !fs.existsSync(sessionDirectory)) {
res.status(500).json(new Error('Failed to get session directory.'));
return;
}
const torrentFileNames = hashes.map((hash) => `${hash}.torrent`);
const torrentFileNames = hashes.map(
(hash) => `${torrentCase === 'lower' ? hash.toLowerCase() : hash.toUpperCase()}.torrent`,
);
if (hashes.length < 2) {
res.attachment(torrentFileNames[0]);
@@ -590,7 +592,8 @@ router.get<{hashes: string}>(
fs.accessSync(path.join(sessionDirectory, torrentFileName), fs.constants.R_OK),
);
} catch {
res.status(500).json('Failed to access torrent files.');
res.status(404).json('Failed to access torrent files.');
return;
}
res.attachment(`torrents-${Date.now()}.tar`);
@@ -422,11 +422,11 @@ class TransmissionClientGatewayService extends ClientGatewayService {
});
}
async getClientSessionDirectory(): Promise<string> {
async getClientSessionDirectory(): Promise<{path: string; case: 'lower' | 'upper'}> {
return this.clientRequestManager
.getSessionProperties(['config-dir'])
.then(this.processClientRequestSuccess, this.processClientRequestError)
.then((properties) => path.join(properties['config-dir'], 'torrents'));
.then((properties) => ({path: path.join(properties['config-dir'], 'torrents'), case: 'lower'}));
}
async getClientSettings(): Promise<ClientSettings> {
@@ -183,9 +183,9 @@ abstract class ClientGatewayService extends BaseService<ClientGatewayServiceEven
/**
* Gets session directory (where .torrent files are stored) of the torrent client
*
* @return {Promise<string>} - Resolves with path of session directory or rejects with error.
* @return {Promise<{path: string; case: 'lower' | 'upper'}>} - Resolves with path of session directory or rejects with error.
*/
abstract getClientSessionDirectory(): Promise<string>;
abstract getClientSessionDirectory(): Promise<{path: string; case: 'lower' | 'upper'}>;
/**
* Gets settings of the torrent client
@@ -386,19 +386,19 @@ class QBittorrentClientGatewayService extends ClientGatewayService {
});
}
async getClientSessionDirectory(): Promise<string> {
async getClientSessionDirectory(): Promise<{path: string; case: 'lower' | 'upper'}> {
// qBittorrent API does not provide session directory.
// We can only guess with the common locations here.
switch (process.platform) {
case 'win32':
if (process.env.LOCALAPPDATA) {
return path.join(process.env.LOCALAPPDATA, '\\qBittorrent\\BT_backup');
return {path: path.join(process.env.LOCALAPPDATA, '\\qBittorrent\\BT_backup'), case: 'lower'};
}
return path.join(homedir(), '\\AppData\\Local\\qBittorrent\\BT_backup');
return {path: path.join(homedir(), '\\AppData\\Local\\qBittorrent\\BT_backup'), case: 'lower'};
case 'darwin':
return path.join(homedir(), '/Library/Application Support/qBittorrent/BT_backup');
return {path: path.join(homedir(), '/Library/Application Support/qBittorrent/BT_backup'), case: 'lower'};
default:
return path.join(homedir(), '/.local/share/data/qBittorrent/BT_backup');
return {path: path.join(homedir(), '/.local/share/data/qBittorrent/BT_backup'), case: 'lower'};
}
}
@@ -517,11 +517,17 @@ class RTorrentClientGatewayService extends ClientGatewayService {
.methodCall('system.multicall', [methodCalls])
.then(this.processClientRequestSuccess, this.processClientRequestError);
const sessionDirectory = await this.getClientSessionDirectory();
const {path: sessionDirectory, case: torrentCase} = await this.getClientSessionDirectory();
await Promise.all(
[...new Set(hashes)].map(async (hash) =>
setTrackers(path.join(sessionDirectory, sanitize(`${hash}.torrent`)), trackers),
setTrackers(
path.join(
sessionDirectory,
sanitize(`${torrentCase === 'lower' ? hash.toLowerCase() : hash.toUpperCase()}.torrent`),
),
trackers,
),
),
);
}
@@ -677,10 +683,11 @@ class RTorrentClientGatewayService extends ClientGatewayService {
});
}
async getClientSessionDirectory(): Promise<string> {
async getClientSessionDirectory(): Promise<{path: string; case: 'lower' | 'upper'}> {
return this.clientRequestManager
.methodCall('session.path', [])
.then(this.processClientRequestSuccess, this.processClientRequestError);
.then(this.processClientRequestSuccess, this.processClientRequestError)
.then((response) => ({path: response, case: 'upper'}));
}
async getClientSettings(): Promise<ClientSettings> {