|
|
|
@ -1,6 +1,48 @@
|
|
|
|
|
import RuTorrent from "rutorrent-promise";
|
|
|
|
|
|
|
|
|
|
import getServiceWidget from "utils/config/service-helpers";
|
|
|
|
|
import { httpProxy } from "utils/proxy/http";
|
|
|
|
|
import widgets from "widgets/widgets";
|
|
|
|
|
import { formatApiCall } from "utils/proxy/api-helpers";
|
|
|
|
|
import createLogger from "utils/logger";
|
|
|
|
|
|
|
|
|
|
const logger = createLogger("rutorrentProxyHandler");
|
|
|
|
|
|
|
|
|
|
// from https://github.com/ctessier/node-rutorrent-promise/blob/next/utils.js
|
|
|
|
|
const getTorrentInfo = (data) => ({
|
|
|
|
|
'd.is_open': data[0],
|
|
|
|
|
'd.is_hash_checking': data[1],
|
|
|
|
|
'd.is_hash_checked': data[2],
|
|
|
|
|
'd.get_state': data[3],
|
|
|
|
|
'd.get_name': data[4],
|
|
|
|
|
'd.get_size_bytes': data[5],
|
|
|
|
|
'd.get_completed_chunks': data[6],
|
|
|
|
|
'd.get_size_chunks': data[7],
|
|
|
|
|
'd.get_bytes_done': data[8],
|
|
|
|
|
'd.get_up_total': data[9],
|
|
|
|
|
'd.get_ratio': data[10],
|
|
|
|
|
'd.get_up_rate': data[11],
|
|
|
|
|
'd.get_down_rate': data[12],
|
|
|
|
|
'd.get_chunk_size': data[13],
|
|
|
|
|
'd.get_custom1': data[14],
|
|
|
|
|
'd.get_peers_accounted': data[15],
|
|
|
|
|
'd.get_peers_not_connected': data[16],
|
|
|
|
|
'd.get_peers_connected': data[17],
|
|
|
|
|
'd.get_peers_complete': data[18],
|
|
|
|
|
'd.get_left_bytes': data[19],
|
|
|
|
|
'd.get_priority': data[20],
|
|
|
|
|
'd.get_state_changed': data[21],
|
|
|
|
|
'd.get_skip_total': data[22],
|
|
|
|
|
'd.get_hashing': data[23],
|
|
|
|
|
'd.get_chunks_hashed': data[24],
|
|
|
|
|
'd.get_base_path': data[25],
|
|
|
|
|
'd.get_creation_date': data[26],
|
|
|
|
|
'd.get_tracker_focus': data[27],
|
|
|
|
|
'd.is_active': data[28],
|
|
|
|
|
'd.get_message': data[29],
|
|
|
|
|
'd.get_custom2': data[30],
|
|
|
|
|
'd.get_free_diskspace': data[31],
|
|
|
|
|
'd.is_private': data[32],
|
|
|
|
|
'd.is_multi_file': data[33],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default async function rutorrentProxyHandler(req, res) {
|
|
|
|
|
const { group, service } = req.query;
|
|
|
|
@ -9,27 +51,35 @@ export default async function rutorrentProxyHandler(req, res) {
|
|
|
|
|
const widget = await getServiceWidget(group, service);
|
|
|
|
|
|
|
|
|
|
if (widget) {
|
|
|
|
|
const constructedUrl = new URL(widget.url);
|
|
|
|
|
const api = widgets?.[widget.type]?.api;
|
|
|
|
|
const url = new URL(formatApiCall(api, { ...widget }));
|
|
|
|
|
|
|
|
|
|
let rtPort = constructedUrl.port;
|
|
|
|
|
if (rtPort === '') {
|
|
|
|
|
rtPort = constructedUrl.protocol === "https:" ? 443 : 80;
|
|
|
|
|
const headers = {}
|
|
|
|
|
if (widget.username) {
|
|
|
|
|
headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const rutorrent = new RuTorrent({
|
|
|
|
|
host: constructedUrl.hostname,
|
|
|
|
|
port: rtPort,
|
|
|
|
|
path: constructedUrl.pathname,
|
|
|
|
|
ssl: constructedUrl.protocol === "https:",
|
|
|
|
|
username: widget.username,
|
|
|
|
|
password: widget.password,
|
|
|
|
|
const [status, , data] = await httpProxy(url, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers,
|
|
|
|
|
body: 'mode=list'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const data = await rutorrent.get(["d.get_down_rate", "d.get_up_rate", "d.get_state"]);
|
|
|
|
|
if (status !== 200) {
|
|
|
|
|
logger.error("HTTP Error %d calling %s", status, url.toString());
|
|
|
|
|
return res.status(status).json({error: {message: "HTTP Error", url, data}});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res.status(200).send(data);
|
|
|
|
|
try {
|
|
|
|
|
const rawData = JSON.parse(data);
|
|
|
|
|
const parsedData = Object.keys(rawData.t).map((hashString) => getTorrentInfo(rawData.t[hashString]));
|
|
|
|
|
|
|
|
|
|
return res.status(200).send(parsedData);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return res.status(500).json({error: {message: e?.toString() ?? 'Error parsing rutorrent data', url, data}});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
|
|
|
|
return res.status(500).json({ error: "Invalid proxy service type" });
|
|
|
|
|
}
|
|
|
|
|