Consistent error rejection & resolve around spawn calls.
This commit is contained in:
@@ -5,55 +5,117 @@ import { spawn } from "child_process";
|
|||||||
import establishedDatabase from "../database/database.js";
|
import establishedDatabase from "../database/database.js";
|
||||||
import cache from "../cache/redis.js";
|
import cache from "../cache/redis.js";
|
||||||
|
|
||||||
function getMagnetFromURL(url) {
|
class SearchPackageNotFoundError extends Error {
|
||||||
return new Promise(resolve => {
|
constructor() {
|
||||||
const options = new URL(url);
|
const message = "Search is not setup, view logs.";
|
||||||
if (options.protocol.includes("magnet")) resolve(url);
|
super(message);
|
||||||
|
|
||||||
|
const warningMessage = `Warning! Package 'torrentSearch' not setup! View project README.`;
|
||||||
|
console.log(warningMessage); /* eslint-disable-line no-console */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddMagnetPackageNotFoundError extends Error {
|
||||||
|
constructor() {
|
||||||
|
const message = "Adding magnet is not setup, view logs.";
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
const warningMessage = `Warning! Package 'delugeClient' not setup! View project README.`;
|
||||||
|
console.log(warningMessage); /* eslint-disable-line no-console */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InvalidMagnetUrlError extends Error {
|
||||||
|
constructor() {
|
||||||
|
const message = "Invalid magnet url.";
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnexpectedScriptError extends Error {
|
||||||
|
constructor(_package, error = null) {
|
||||||
|
const message = `There was an unexpected error while running package: ${_package}`;
|
||||||
|
super(message);
|
||||||
|
this.error = error;
|
||||||
|
|
||||||
|
// console.log("Unexpected script error:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMagnetFromURL(url) {
|
||||||
|
const options = new URL(url);
|
||||||
|
if (options?.protocol?.includes("magnet")) return Promise.resolve(url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
http.get(options, res => {
|
http.get(options, res => {
|
||||||
if (res.statusCode === 301 || res.statusCode === 302) {
|
if (res.statusCode !== 301 && res.statusCode !== 302)
|
||||||
resolve(res.headers.location);
|
reject(new InvalidMagnetUrlError());
|
||||||
}
|
if (!res?.headers?.location?.includes("magnet"))
|
||||||
|
reject(new InvalidMagnetUrlError());
|
||||||
|
|
||||||
|
return resolve(res.headers.location);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeNewLineListItem(list) {
|
function removeNewLineListItem(list) {
|
||||||
return list.filter(el => !el.includes("\n"));
|
return list.map(el => el.replace("\n", "")).filter(el => el.length !== 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function find(searchterm, callback) {
|
function decodeBufferListToString(bufferList) {
|
||||||
let data = [];
|
let data = bufferList.map(bufferElement => bufferElement.toString());
|
||||||
|
if (data.length === 0) return null;
|
||||||
|
|
||||||
|
data = removeNewLineListItem(data);
|
||||||
|
return data.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMagnetScript(magnet, callback) {
|
||||||
|
const data = [];
|
||||||
|
let error = null;
|
||||||
|
const args = ["add", magnet];
|
||||||
|
|
||||||
|
const addMagnet = spawn("delugeclient", args);
|
||||||
|
|
||||||
|
addMagnet.stdout.on("data", bufferedData => data.push(bufferedData));
|
||||||
|
addMagnet.stderr.on("data", bufferedError => {
|
||||||
|
error = bufferedError.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
addMagnet.on("exit", () => callback(error, decodeBufferListToString(data)));
|
||||||
|
addMagnet.on("error", error => {
|
||||||
|
callback(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAddMagnetScriptError(error) {
|
||||||
|
if (error?.code === "ENOENT") return new AddMagnetPackageNotFoundError();
|
||||||
|
|
||||||
|
return new UnexpectedScriptError("delugeClient", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchScript(searchterm, callback) {
|
||||||
|
const data = [];
|
||||||
|
let error = null;
|
||||||
const args = [searchterm, "-s", "jackett", "--print"];
|
const args = [searchterm, "-s", "jackett", "--print"];
|
||||||
|
|
||||||
const torrentSearch = spawn("torrentsearch", args);
|
const torrentSearch = spawn("torrentsearch", args);
|
||||||
|
|
||||||
torrentSearch.stdout.on("data", d => {
|
torrentSearch.stdout.on("data", bufferedData => data.push(bufferedData));
|
||||||
console.log("got data, appending:", d);
|
torrentSearch.stderr.on("data", bufferedError => {
|
||||||
data.push(d.toString());
|
error = bufferedError.toString();
|
||||||
});
|
});
|
||||||
|
|
||||||
torrentSearch.on("exit", () => {
|
torrentSearch.on("exit", () =>
|
||||||
data = removeNewLineListItem(data);
|
callback(error, decodeBufferListToString(data))
|
||||||
data = data.join("");
|
);
|
||||||
console.log("returning to callback:", data);
|
torrentSearch.on("error", error => callback(error));
|
||||||
|
|
||||||
callback(null, data);
|
|
||||||
});
|
|
||||||
|
|
||||||
PythonShell.run("torrentsearch", options, callback);
|
|
||||||
// PythonShell does not support return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function callPythonAddMagnet(url, callback) {
|
function handleSearchScriptError(error) {
|
||||||
getMagnetFromURL(url)
|
if (error?.code === "ENOENT") return new SearchPackageNotFoundError();
|
||||||
.then(magnet => {
|
|
||||||
const options = { args: ["add", magnet] };
|
|
||||||
|
|
||||||
PythonShell.run("delugeClient", options, callback);
|
return new UnexpectedScriptError("torrentSearch", error);
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
throw new Error(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SearchPiratebay(_query) {
|
export async function SearchPiratebay(_query) {
|
||||||
@@ -64,47 +126,46 @@ export async function SearchPiratebay(_query) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cacheKey = `pirate/${query}`;
|
const cacheKey = `pirate/${query}`;
|
||||||
|
try {
|
||||||
|
const hit = await cache.get(cacheKey);
|
||||||
|
|
||||||
return new Promise((resolve, reject) =>
|
if (hit) {
|
||||||
cache
|
return Promise.resolve(hit);
|
||||||
.get(cacheKey)
|
}
|
||||||
.then(resolve)
|
} catch (_) {}
|
||||||
.catch(() =>
|
|
||||||
find(query, (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
console.log("THERE WAS A FUCKING ERROR!\n", err); // eslint-disable-line no-console
|
|
||||||
reject(Error("There was a error when searching for torrents"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results) {
|
return new Promise((resolve, reject) => {
|
||||||
const jsonData = JSON.parse(results, null, "\t");
|
searchScript(query, (error, results) => {
|
||||||
cache.set(cacheKey, jsonData);
|
if (error || !results) return reject(handleSearchScriptError(error));
|
||||||
resolve(jsonData);
|
|
||||||
}
|
const jsonData = JSON.parse(results, null, "\t");
|
||||||
})
|
cache.set(cacheKey, jsonData);
|
||||||
)
|
return resolve(jsonData);
|
||||||
);
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AddMagnet(magnet, name, tmdbId) {
|
export async function AddMagnet(magnetUrl, name, tmdbId) {
|
||||||
return new Promise((resolve, reject) =>
|
const magnet = await getMagnetFromURL(magnetUrl);
|
||||||
callPythonAddMagnet(magnet, (err, results) => {
|
const insertRequestedMagnetQuery =
|
||||||
if (err) {
|
"INSERT INTO requested_torrent(magnet, torrent_name, tmdb_id) VALUES (?,?,?)";
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.log(err);
|
|
||||||
reject(Error("Enable to add torrent", err));
|
|
||||||
}
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.log("result/error:", err, results);
|
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
addMagnetScript(magnet, (error, result) => {
|
||||||
|
if (error || !result) return reject(handleAddMagnetScriptError(error));
|
||||||
|
|
||||||
|
const magnetHash = result; // TODO save to database
|
||||||
const database = establishedDatabase;
|
const database = establishedDatabase;
|
||||||
const insertQuery =
|
return database
|
||||||
"INSERT INTO requested_torrent(magnet,torrent_name,tmdb_id) VALUES (?,?,?)";
|
.run(insertRequestedMagnetQuery, [magnet, name, tmdbId])
|
||||||
|
.catch(error => reject(error))
|
||||||
const response = database.run(insertQuery, [magnet, name, tmdbId]);
|
.then(() =>
|
||||||
console.log(`Response from requsted_torrent insert: ${response}`);
|
resolve({
|
||||||
|
success: true,
|
||||||
resolve({ success: true });
|
message: "Successfully added magnet",
|
||||||
})
|
hash: magnetHash
|
||||||
);
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,12 @@ function addMagnet(req, res) {
|
|||||||
AddMagnet(magnet, name, tmdbId)
|
AddMagnet(magnet, name, tmdbId)
|
||||||
.then(result => res.send(result))
|
.then(result => res.send(result))
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
res.status(500).send({ success: false, message: error.message });
|
res
|
||||||
|
.status(error?.statusCode || 500)
|
||||||
|
.send({
|
||||||
|
success: false,
|
||||||
|
message: error?.message || "Unexpected error while adding magnet."
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ function updateRequested(req, res) {
|
|||||||
res.send({ success: true, results: result });
|
res.send({ success: true, results: result });
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
res.status(401).send({ success: false, message: error.message });
|
res.status(error?.statusCode || 500).send({
|
||||||
|
success: false,
|
||||||
|
message: error?.message || "Unexpected error while searching."
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user