UNPKG

qbittorrent-api-client

Version:
483 lines (478 loc) 15.8 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { ErrorType: () => ErrorType, QBittorrentClient: () => QBittorrentClient, QBittorrentClientError: () => QBittorrentClientError, QBittorrentTorrentContentPriority: () => QBittorrentTorrentContentPriority, QBittorrentTorrentTrackerStatus: () => QBittorrentTorrentTrackerStatus, default: () => QBittorrentClient }); module.exports = __toCommonJS(src_exports); // src/classes/QBittorrentClient.ts var import_axios = __toESM(require("axios"), 1); // src/utils/QBittorrentClientError.ts var ErrorType = /* @__PURE__ */ ((ErrorType2) => { ErrorType2["FORBIDDEN"] = "FORBIDDEN"; ErrorType2["IP_BANNED"] = "IP_BANNED"; ErrorType2["INVALID_CREDENTIALS"] = "INVALID_CREDENTIALS"; ErrorType2["OPERATION_FAILED"] = "OPERATION_FAILED"; return ErrorType2; })(ErrorType || {}); var QBittorrentClientError = class extends Error { name = "QBittorrentClientError"; type; constructor(message, context) { super(message ?? "qBittorrent client error"); this.type = context?.type; } }; // src/classes/QBittorrentClient.ts var import_form_data = __toESM(require("form-data"), 1); var QBittorrentClient = class { constructor(options) { this.options = options; this.httpClient.defaults.baseURL = this.baseUrl; this.httpClient.interceptors.response.use((response) => response, (error) => { if (error.response.status === 403) { throw new QBittorrentClientError("Authentication needed", { type: "FORBIDDEN" /* FORBIDDEN */ }); } throw error; }); } httpClient = import_axios.default.create(); sessionCookie; get baseUrl() { return this.options.baseUrl + "/api/v2"; } async authenticate(username, password) { return this.login(username, password).then((sessionCookie) => { if (!sessionCookie) { throw new Error("No session cookie"); } this.sessionCookie = sessionCookie; this.httpClient.defaults.headers.common["Cookie"] = sessionCookie; }); } async login(username, password) { const params = new URLSearchParams(); if (username) params.append("username", username); if (password) params.append("password", password); return this.httpClient("auth/login", { method: "POST", data: params, withCredentials: true }).then( async (response) => { if (response.status === 403) { throw new QBittorrentClientError("Too many failed attempts, your IP is banned", { type: "IP_BANNED" /* IP_BANNED */ }); } if (response.data === "Fails.") { throw new QBittorrentClientError("Invalid credentials", { type: "INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */ }); } const cookies = response.headers["set-cookie"]; if (Array.isArray(cookies)) { return cookies.find((cookie) => cookie.startsWith("SID="))?.split(";")[0]; } return void 0; }, (error) => { if (error.response.status === 403) { throw new QBittorrentClientError("Too many failed attempts, your IP is banned", { type: "IP_BANNED" /* IP_BANNED */ }); } throw error; } ); } async logout() { await this.httpClient("/auth/logout", { method: "POST", withCredentials: true }); } async version() { return this.httpClient.get("app/version").then((response) => response.data); } async getAppPreferences() { return this.httpClient.get(`app/preferences`).then((res) => res.data); } async setAppPreferences(preferences) { await this.httpClient.post(`app/setPreferences`, `json=${JSON.stringify(preferences)}`); } async getTorrentInfos() { return this.httpClient.get("torrents/info").then((res) => res.data); } async getTorrentContents(hash) { return this.httpClient.get(`torrents/files`, { params: { hash: hash.toLowerCase() } }).then((res) => res.data); } async getTorrentProperties(hash) { return this.httpClient.get(`torrents/properties`, { params: { hash: hash.toLowerCase() } }).then((res) => res.data); } async getTorrentTrackers(hash) { return this.httpClient.get(`torrents/trackers`, { params: { hash: hash.toLowerCase() } }).then((res) => res.data); } async getTransferInfo() { return this.httpClient.get(`transfer/info`, {}).then((res) => res.data); } // async syncMainData(): Promise<QBittorrentMainData> { // const headers = await this.getRequestHeaders() // // if (this.isMainDataPending == false) { // this.isMainDataPending = true // this.syncRids.mainData = this.syncRids.mainData.then((rid) => // this.client // .get<QBittorrentSyncMainData>(`sync/maindata`, { // params: { // rid, // }, // headers, // }) // .then(({ data }) => { // const { // rid: newRid = 0, // full_update = false, // categories = {}, // categories_removed = [], // server_state = EMPTY_SERVER_STATE, // tags = [], // tags_removed = [], // torrents = {}, // torrents_removed = [], // trackers = {}, // trackers_removed = [], // } = data // // if (full_update) { // this.syncStates.mainData = { // categories, // server_state, // tags, // torrents, // trackers, // } // } else { // // categories // Object.keys(categories).forEach((category) => { // this.syncStates.mainData.categories[category] = { // ...this.syncStates.mainData.categories[category], // ...categories[category], // } // }) // // categories_removed.forEach((category) => { // delete this.syncStates.mainData.categories[category] // }) // // // tags // this.syncStates.mainData.tags.push(...tags) // this.syncStates.mainData.tags = this.syncStates.mainData.tags.filter( // (tag) => !tags_removed.includes(tag), // ) // // // torrents // Object.keys(torrents).forEach((torrent) => { // this.syncStates.mainData.torrents[torrent] = { // ...this.syncStates.mainData.torrents[torrent], // ...torrents[torrent], // } // }) // // torrents_removed.forEach((torrent) => { // delete this.syncStates.mainData.torrents[torrent] // }) // // // trackers // Object.keys(trackers).forEach((tracker) => { // this.syncStates.mainData.trackers[tracker] = { // ...this.syncStates.mainData.trackers[tracker], // ...trackers[tracker], // } // }) // // trackers_removed.forEach((tracker) => { // delete this.syncStates.mainData.trackers[tracker] // }) // } // // return newRid // }) // .finally(() => { // this.isMainDataPending = false // }), // ) // } // // try { // await this.syncRids.mainData // } catch (e) { // this.syncRids.mainData = Promise.resolve(0) // throw e // } // // return this.syncStates.mainData // } async syncTorrentPeers(hash) { return this.httpClient.get(`sync/torrentPeers`, { params: { hash: hash.toLowerCase(), rid: 0 } }).then(({ data }) => data.peers); } async torrentsPause(hashes) { return this.httpClient.get(`torrents/pause`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } async torrentsResume(hashes) { return this.httpClient.get(`torrents/resume`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } async torrentsDelete(hashes, deleteFiles) { return this.httpClient.get(`torrents/delete`, { params: { hashes: hashes.join("|").toLowerCase(), deleteFiles: deleteFiles ? "true" : "false" } }).then(() => { }); } async torrentsRecheck(hashes) { return this.httpClient.get(`torrents/recheck`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } async torrentsSetLocation(hashes, location) { return this.httpClient.get(`torrents/setLocation`, { params: { hashes: hashes.join("|").toLowerCase(), location } }).then(() => { }); } async torrentsSetTopPrio(hashes) { return this.httpClient.get(`torrents/topPrio`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } async torrentsSetBottomPrio(hashes) { return this.httpClient.get(`torrents/bottomPrio`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } async torrentsAddFiles(files, options) { const form = new import_form_data.default(); files.forEach((file, index) => { form.append("torrents", file, { filename: `${index}.torrent`, contentType: "application/x-bittorrent" }); }); Object.keys(options).forEach((key) => { const property = key; form.append(property, `${options[property]}`); }); const headers = form.getHeaders({ Cookie: this.sessionCookie, "Content-Length": form.getLengthSync() }); return this.httpClient.post(`torrents/add`, form, { headers }).then((response) => { if (response.data === "Fails.") { throw new QBittorrentClientError("Can not add torrent file", { type: "OPERATION_FAILED" /* OPERATION_FAILED */ }); } }); } async torrentsAddURLs(urls, options) { const form = new import_form_data.default(); form.append("urls", urls.join("\n")); Object.keys(options).forEach((key) => { const property = key; form.append(property, `${options[property]}`); }); const headers = form.getHeaders({ Cookie: this.sessionCookie, "Content-Length": form.getLengthSync() }); return this.httpClient.post(`torrents/add`, form, { headers }).then(() => { }); } async torrentsAddTags(hashes, tags) { return this.httpClient.get(`torrents/addTags`, { params: { hashes: hashes.join("|").toLowerCase(), tags: tags.join(",") } }).then(() => { }); } async torrentsRemoveTags(hashes, tags) { return this.httpClient.get(`torrents/removeTags`, { params: { hashes: hashes.join("|").toLowerCase(), tags: tags?.join(",") } }).then(() => { }); } async torrentsAddTrackers(hash, urls) { if (urls.length > 0) { return this.httpClient.get(`torrents/addTrackers`, { params: { hash: hash.toLowerCase(), urls: urls.join("\n") } }).then(() => { }); } } async torrentsReannounce(hashes) { if (hashes.length > 0) { return this.httpClient.get(`torrents/reannounce`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } } async torrentsRemoveTrackers(hash, urls) { if (urls.length > 0) { return this.httpClient.get(`torrents/removeTrackers`, { params: { hash: hash.toLowerCase(), urls: urls.join("|") } }).then(() => { }); } } async torrentsSetSuperSeeding(hashes, value) { if (hashes.length > 0) { return this.httpClient.get(`torrents/setSuperSeeding`, { params: { hashes: hashes.join("|").toLowerCase(), value: value ? "true" : "false" } }).then(() => { }); } } async torrentsToggleSequentialDownload(hashes) { if (hashes.length > 0) { return this.httpClient.get(`torrents/toggleSequentialDownload`, { params: { hashes: hashes.join("|").toLowerCase() } }).then(() => { }); } } async torrentsFilePrio(hash, ids, priority) { return this.httpClient.get(`torrents/filePrio`, { params: { hash: hash.toLowerCase(), id: ids.join("|"), priority } }).then(() => { }); } }; // src/types/QBittorrentTorrentsMethods.ts var QBittorrentTorrentContentPriority = /* @__PURE__ */ ((QBittorrentTorrentContentPriority2) => { QBittorrentTorrentContentPriority2[QBittorrentTorrentContentPriority2["DO_NOT_DOWNLOAD"] = 0] = "DO_NOT_DOWNLOAD"; QBittorrentTorrentContentPriority2[QBittorrentTorrentContentPriority2["NORMAL"] = 1] = "NORMAL"; QBittorrentTorrentContentPriority2[QBittorrentTorrentContentPriority2["HIGH"] = 6] = "HIGH"; QBittorrentTorrentContentPriority2[QBittorrentTorrentContentPriority2["MAXIMUM"] = 7] = "MAXIMUM"; return QBittorrentTorrentContentPriority2; })(QBittorrentTorrentContentPriority || {}); var QBittorrentTorrentTrackerStatus = /* @__PURE__ */ ((QBittorrentTorrentTrackerStatus2) => { QBittorrentTorrentTrackerStatus2[QBittorrentTorrentTrackerStatus2["DISABLED"] = 0] = "DISABLED"; QBittorrentTorrentTrackerStatus2[QBittorrentTorrentTrackerStatus2["NOT_CONTACTED"] = 1] = "NOT_CONTACTED"; QBittorrentTorrentTrackerStatus2[QBittorrentTorrentTrackerStatus2["CONTACTED"] = 2] = "CONTACTED"; QBittorrentTorrentTrackerStatus2[QBittorrentTorrentTrackerStatus2["UPDATING"] = 3] = "UPDATING"; QBittorrentTorrentTrackerStatus2[QBittorrentTorrentTrackerStatus2["ERROR"] = 4] = "ERROR"; return QBittorrentTorrentTrackerStatus2; })(QBittorrentTorrentTrackerStatus || {}); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ErrorType, QBittorrentClient, QBittorrentClientError, QBittorrentTorrentContentPriority, QBittorrentTorrentTrackerStatus }); //# sourceMappingURL=index.cjs.map