Skip to content

Commit

Permalink
feat: add normalized functions
Browse files Browse the repository at this point in the history
  • Loading branch information
scttcper committed Mar 6, 2019
1 parent f6cb13b commit 8542ea7
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 51 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ module.exports = {
'no-mixed-operators': 0,
'no-await-in-loop': 0,
'@typescript-eslint/camelcase': 0,
'@typescript-eslint/promise-function-async': 0,
},
};
21 changes: 13 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
"semantic-release": "cd dist && semantic-release"
},
"dependencies": {
"@ctrl/shared-torrent": "^1.0.3",
"@ctrl/shared-torrent": "^1.1.0",
"form-data": "2.3.3",
"got": "9.6.0",
"tough-cookie": "3.0.1"
"tough-cookie": "3.0.1",
"url-join": "^4.0.0"
},
"devDependencies": {
"@types/form-data": "2.2.1",
Expand All @@ -37,9 +38,10 @@
"@types/node": "11.10.4",
"@types/p-wait-for": "2.0.0",
"@types/tough-cookie": "2.3.5",
"@types/url-join": "4.0.0",
"@typescript-eslint/eslint-plugin": "1.4.2",
"@typescript-eslint/parser": "1.4.2",
"eslint": "5.15.0",
"eslint": "5.15.1",
"eslint-config-prettier": "4.1.0",
"eslint-config-xo-space": "0.21.0",
"eslint-config-xo-typescript": "0.8.0",
Expand Down
104 changes: 88 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { resolve } from 'url';
import urljoin from 'url-join';
import got, { Response, GotJSONOptions } from 'got';
import { Cookie } from 'tough-cookie';
import FormData from 'form-data';
import fs from 'fs';
import { TorrentSettings } from '@ctrl/shared-torrent';
import {
TorrentSettings,
TorrentClient,
NormalizedTorrent,
AllClientData,
TorrentState,
} from '@ctrl/shared-torrent';
import {
GetHostsResponse,
GetHostStatusResponse,
Expand All @@ -22,6 +28,7 @@ import {
TorrentFiles,
TorrentStatus,
Tracker,
Torrent,
} from './types';

const defaults: TorrentSettings = {
Expand All @@ -31,7 +38,7 @@ const defaults: TorrentSettings = {
timeout: 5000,
};

export class Deluge {
export class Deluge implements TorrentClient {
config: TorrentSettings;

private _msgId = 0;
Expand Down Expand Up @@ -122,7 +129,7 @@ export class Deluge {
if (check.body && check.body.result) {
return true;
}
// tslint:disable-next-line:no-unused
// tslint:disable-next-line:no-unused
} catch {
// do nothing
}
Expand Down Expand Up @@ -193,7 +200,7 @@ export class Deluge {
form.append('file', torrent);
}

const url = resolve(this.config.baseUrl, '../upload');
const url = urljoin(this.config.baseUrl, '/upload');
const res = await got.post(url, {
headers: form.getHeaders(),
body: form,
Expand Down Expand Up @@ -222,14 +229,8 @@ export class Deluge {
// move_completed_path: '/root/Downloads',
...config,
};
const res = await this.request<BooleanStatus>('web.add_torrents', [
[
{
path,
options,
},
],
]);
const res = await this.request<BooleanStatus>('web.add_torrents', [[{ path, options }]]);

return res.body;
}

Expand Down Expand Up @@ -258,7 +259,32 @@ export class Deluge {
return res.body;
}

async listTorrents(additionalFields: string[] = []) {
async getAllData(): Promise<AllClientData> {
const listTorrents = await this.listTorrents();
const results: AllClientData = {
torrents: [],
labels: [],
};
for (const id of Object.keys(listTorrents.result.torrents)) {
const torrent = listTorrents.result.torrents[id];
const torrentData: NormalizedTorrent = this._normalizeTorrentData(id, torrent);
results.torrents.push(torrentData);
}

if (listTorrents.result.filters.label) {
for (const label of listTorrents.result.filters.label) {
results.labels.push({
id: label[0],
name: label[0],
count: label[1],
});
}
}

return results;
}

async listTorrents(additionalFields: string[] = [], filter: { [key: string]: string } = {}) {
const fields = [
'distributed_copies',
'download_payload_rate',
Expand All @@ -283,15 +309,22 @@ export class Deluge {
'total_wanted',
'tracker_host',
'upload_payload_rate',
// if they don't have the label plugin it shouldn't fail
'label',
...additionalFields,
];
const req = await this.request<TorrentListResponse>('web.update_ui', [
[...new Set(fields)],
{},
filter,
]);
return req.body;
}

async getTorrent(id: string) {
const torrentResponse = await this.getTorrentStatus(id);
return this._normalizeTorrentData(id, torrentResponse.result);
}

/**
* get torrent state/status
* @param additionalFields fields ex - `['label']`
Expand Down Expand Up @@ -333,6 +366,7 @@ export class Deluge {
'max_download_speed',
'max_upload_speed',
'seeds_peers_ratio',
'label',
...additionalFields,
];
const req = await this.request<TorrentStatus>('web.get_torrent_status', [torrentId, fields]);
Expand Down Expand Up @@ -452,7 +486,7 @@ export class Deluge {
const headers: any = {
Cookie: this._cookie && this._cookie.cookieString(),
};
const url = resolve(this.config.baseUrl, this.config.path);
const url = urljoin(this.config.baseUrl, this.config.path);
const options: GotJSONOptions = {
body: {
method,
Expand All @@ -476,6 +510,44 @@ export class Deluge {
return got.post(url, options);
}

private _normalizeTorrentData(id: string, torrent: Torrent): NormalizedTorrent {
const dateAdded = new Date(torrent.time_added * 1000).toISOString();

// normalize state to enum
let state = TorrentState.unknown;
if (Object.keys(TorrentState).includes(torrent.state.toLowerCase())) {
state = TorrentState[torrent.state.toLowerCase() as keyof typeof TorrentState];
}

const isCompleted = torrent.progress >= 100;

const result: NormalizedTorrent = {
id,
name: torrent.name,
state,
isCompleted,
stateMessage: torrent.state,
progress: torrent.progress,
ratio: torrent.ratio,
dateAdded,
dateCompleted: undefined,
label: torrent.label,
savePath: torrent.save_path,
uploadSpeed: torrent.upload_payload_rate,
downloadSpeed: torrent.download_payload_rate,
eta: torrent.eta,
queuePosition: torrent.queue + 1,
connectedPeers: torrent.num_peers,
connectedSeeds: torrent.num_seeds,
totalPeers: torrent.total_peers,
totalSeeds: torrent.total_seeds,
totalSelected: torrent.total_wanted,
totalUploaded: torrent.total_uploaded,
totalDownloaded: torrent.total_done,
};
return result;
}

private async _validateAuth() {
let validAuth = await this.checkSession();
if (!validAuth) {
Expand Down
37 changes: 13 additions & 24 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export interface DefaultResponse {
/**
* mostly usless id that increments with every request
*/
id: number;
error: null | string;
result: any;
Expand All @@ -13,7 +16,13 @@ export interface ListMethods extends DefaultResponse {
}

// {"files": ["/tmp/delugeweb-5Q9ttR/tmpL7xhth.torrent"], "success": true}
/**
* ex -
*/
export interface UploadResponse {
/**
* ex - `["/tmp/delugeweb-5Q9ttR/tmpL7xhth.torrent"]`
*/
files: string[];
success: boolean;
}
Expand Down Expand Up @@ -94,6 +103,9 @@ export interface TorrentList {
filters: TorrentFilters;
}

/**
* ['label', 'id']
*/
export interface TorrentFilters {
state: [string, number][];
tracker_host: [string, number][];
Expand Down Expand Up @@ -173,30 +185,7 @@ export interface Tracker {
}

export interface TorrentStatus extends DefaultResponse {
result: {
max_download_speed?: number;
stop_ratio?: number;
is_auto_managed?: true;
move_completed_path?: string;
private?: boolean;
stop_at_ratio?: boolean;
max_upload_speed?: number;
remove_at_ratio?: boolean;
max_upload_slots?: number;
prioritize_first_last?: boolean;
move_completed?: boolean;
max_connections?: number;
comment?: string;
name?: string;
total_size?: number;
num_files?: number;
tracker?: string;
save_path?: string;
message?: string;
peers?: TorrentPeers;
trackers?: Tracker;
[key: string]: any;
};
result: Torrent;
}

export interface TorrentPeers {
Expand Down

0 comments on commit 8542ea7

Please sign in to comment.