mirror of
https://github.com/wukko/cobalt.git
synced 2025-06-13 05:37:44 +02:00
moved to new repo
This commit is contained in:
51
modules/sub/api-helper.js
Normal file
51
modules/sub/api-helper.js
Normal file
@ -0,0 +1,51 @@
|
||||
import { createStream } from "../stream/manage.js";
|
||||
|
||||
export function apiJSON(type, obj) {
|
||||
try {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return { status: 400, body: { status: "error", text: obj.t } };
|
||||
case 1:
|
||||
return { status: 200, body: { status: "redirect", url: obj.u } };
|
||||
case 2:
|
||||
return { status: 200, body: { status: "stream", url: createStream(obj) } };
|
||||
case 3:
|
||||
return { status: 200, body: { status: "success", text: obj.t } };
|
||||
case 4:
|
||||
return { status: 429, body: { status: "rate-limit", text: obj.t } };
|
||||
default:
|
||||
return { status: 400, body: { status: "error", text: "Bad Request" } };
|
||||
}
|
||||
} catch (e) {
|
||||
return { status: 500, body: { status: "error", text: "Internal Server Error" } };
|
||||
}
|
||||
}
|
||||
export function msToTime(d) {
|
||||
let milliseconds = parseInt((d % 1000) / 100),
|
||||
seconds = parseInt((d / 1000) % 60),
|
||||
minutes = parseInt((d / (1000 * 60)) % 60),
|
||||
hours = parseInt((d / (1000 * 60 * 60)) % 24),
|
||||
r;
|
||||
|
||||
hours = (hours < 10) ? "0" + hours : hours;
|
||||
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
||||
r = hours + ":" + minutes + ":" + seconds;
|
||||
milliseconds ? r += "." + milliseconds : r += "";
|
||||
return r;
|
||||
}
|
||||
export function cleanURL(url, host) {
|
||||
url = url.replace('}', '').replace('{', '').replace(')', '').replace('(', '').replace(' ', '');
|
||||
if (url.includes('youtube.com/shorts/')) {
|
||||
url = url.split('?')[0].replace('shorts/', 'watch?v=');
|
||||
}
|
||||
if (host == "youtube") {
|
||||
url = url.split('&')[0];
|
||||
} else {
|
||||
url = url.split('?')[0];
|
||||
if (url.substring(url.length - 1) == "/") {
|
||||
url = url.substring(0, url.length - 1);
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
49
modules/sub/console-text.js
Normal file
49
modules/sub/console-text.js
Normal file
@ -0,0 +1,49 @@
|
||||
export function t(color, tt) {
|
||||
return color + tt + "\x1b[0m"
|
||||
}
|
||||
export function Reset(tt) {
|
||||
return "\x1b[0m" + tt
|
||||
}
|
||||
export function Bright(tt) {
|
||||
return t("\x1b[1m", tt)
|
||||
}
|
||||
export function Dim(tt) {
|
||||
return t("\x1b[2m", tt)
|
||||
}
|
||||
export function Underscore(tt) {
|
||||
return t("\x1b[4m", tt)
|
||||
}
|
||||
export function Blink(tt) {
|
||||
return t("\x1b[5m", tt)
|
||||
}
|
||||
export function Reverse(tt) {
|
||||
return t("\x1b[7m", tt)
|
||||
}
|
||||
export function Hidden(tt) {
|
||||
return t("\x1b[8m", tt)
|
||||
}
|
||||
|
||||
export function Black(tt) {
|
||||
return t("\x1b[30m", tt)
|
||||
}
|
||||
export function Red(tt) {
|
||||
return t("\x1b[31m", tt)
|
||||
}
|
||||
export function Green(tt) {
|
||||
return t("\x1b[32m", tt)
|
||||
}
|
||||
export function Yellow(tt) {
|
||||
return t("\x1b[33m", tt)
|
||||
}
|
||||
export function Blue(tt) {
|
||||
return t("\x1b[34m", tt)
|
||||
}
|
||||
export function Magenta(tt) {
|
||||
return t("\x1b[35m", tt)
|
||||
}
|
||||
export function Cyan(tt) {
|
||||
return t("\x1b[36m", tt)
|
||||
}
|
||||
export function White(tt) {
|
||||
return t("\x1b[37m", tt)
|
||||
}
|
11
modules/sub/crypto.js
Normal file
11
modules/sub/crypto.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { createHmac, createHash, randomUUID } from "crypto";
|
||||
|
||||
export function encrypt(str, salt) {
|
||||
return createHmac("sha256", salt).update(str).digest("hex");
|
||||
}
|
||||
export function md5(string) {
|
||||
return createHash('md5').update(string).digest('hex');
|
||||
}
|
||||
export function UUID() {
|
||||
return randomUUID();
|
||||
}
|
5
modules/sub/current-commit.js
Normal file
5
modules/sub/current-commit.js
Normal file
@ -0,0 +1,5 @@
|
||||
import { execSync } from "child_process";
|
||||
|
||||
export default function() {
|
||||
return execSync('git rev-parse --short HEAD').toString().trim()
|
||||
}
|
11
modules/sub/errors.js
Normal file
11
modules/sub/errors.js
Normal file
@ -0,0 +1,11 @@
|
||||
import loc from "./loc.js";
|
||||
|
||||
export function internalError(res) {
|
||||
res.status(501).json({ status: "error", text: "Internal Server Error" });
|
||||
}
|
||||
export function errorUnsupported(lang) {
|
||||
return loc(lang, 'apiError', 'notSupported') + loc(lang, 'apiError', 'letMeKnow');
|
||||
}
|
||||
export function genericError(lang, host) {
|
||||
return loc(lang, 'apiError', 'brokenLink', host) + loc(lang, 'apiError', 'letMeKnow');
|
||||
}
|
9
modules/sub/load-json.js
Normal file
9
modules/sub/load-json.js
Normal file
@ -0,0 +1,9 @@
|
||||
import * as fs from "fs";
|
||||
|
||||
export default function(path) {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(path, 'utf-8'))
|
||||
} catch(e) {
|
||||
return false
|
||||
}
|
||||
}
|
22
modules/sub/loc.js
Normal file
22
modules/sub/loc.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { supportedLanguages, appName } from "../config.js";
|
||||
import loadJson from "./load-json.js";
|
||||
|
||||
export default function(lang, cat, string, replacement) {
|
||||
if (!lang in supportedLanguages) {
|
||||
lang = 'en'
|
||||
}
|
||||
try {
|
||||
let str = loadJson(`./strings/${lang}/${cat}.json`);
|
||||
if (str && str[string]) {
|
||||
let s = str[string].replace(/\n/g, '<br/>').replace(/{appName}/g, appName)
|
||||
if (replacement) {
|
||||
s = s.replace(/{s}/g, replacement)
|
||||
}
|
||||
return s + ' '
|
||||
} else {
|
||||
return string
|
||||
}
|
||||
} catch (e) {
|
||||
return string
|
||||
}
|
||||
}
|
90
modules/sub/match.js
Normal file
90
modules/sub/match.js
Normal file
@ -0,0 +1,90 @@
|
||||
import { apiJSON } from "./api-helper.js";
|
||||
import { errorUnsupported, genericError } from "./errors.js";
|
||||
|
||||
import bilibili from "../services/bilibili.js";
|
||||
import reddit from "../services/reddit.js";
|
||||
import twitter from "../services/twitter.js";
|
||||
import youtube from "../services/youtube.js";
|
||||
import vk from "../services/vk.js";
|
||||
|
||||
export default async function (host, patternMatch, url, ip, lang, format, quality) {
|
||||
try {
|
||||
switch (host) {
|
||||
case "twitter":
|
||||
if (patternMatch["id"] && patternMatch["id"].length < 20) {
|
||||
let r = await twitter({
|
||||
id: patternMatch["id"],
|
||||
lang: lang
|
||||
});
|
||||
return (!r.error) ? apiJSON(1, { u: r.split('?')[0] }) : apiJSON(0, { t: r.error })
|
||||
} else throw Error()
|
||||
case "vk":
|
||||
if (patternMatch["userId"] && patternMatch["videoId"] && patternMatch["userId"].length <= 10 && patternMatch["videoId"].length == 9) {
|
||||
let r = await vk({
|
||||
userId: patternMatch["userId"],
|
||||
videoId: patternMatch["videoId"],
|
||||
lang: lang, quality: quality
|
||||
});
|
||||
return (!r.error) ? apiJSON(2, { type: "bridge", urls: r.url, filename: r.filename, service: host, ip: ip, salt: process.env.streamSalt }) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
case "bilibili":
|
||||
if (patternMatch["id"] && patternMatch["id"].length >= 12) {
|
||||
let r = await bilibili({
|
||||
id: patternMatch["id"].slice(0, 12),
|
||||
lang: lang
|
||||
});
|
||||
return (!r.error) ? apiJSON(2, {
|
||||
type: "render", urls: r.urls,
|
||||
service: host, ip: ip,
|
||||
filename: r.filename,
|
||||
salt: process.env.streamSalt, time: r.time
|
||||
}) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
case "youtube":
|
||||
if (patternMatch["id"]) {
|
||||
let fetchInfo = {
|
||||
id: patternMatch["id"].slice(0, 11),
|
||||
lang: lang, quality: quality,
|
||||
format: "mp4"
|
||||
};
|
||||
switch (format) {
|
||||
case "webm":
|
||||
fetchInfo["format"] = "webm";
|
||||
break;
|
||||
case "audio":
|
||||
fetchInfo["format"] = "webm";
|
||||
fetchInfo["isAudioOnly"] = true;
|
||||
fetchInfo["quality"] = "max";
|
||||
break;
|
||||
}
|
||||
if (url.match('music.youtube.com')) {
|
||||
fetchInfo["isAudioOnly"] = true;
|
||||
}
|
||||
let r = await youtube(fetchInfo);
|
||||
return (!r.error) ? apiJSON(2, {
|
||||
type: r.type, urls: r.urls, service: host, ip: ip,
|
||||
filename: r.filename, salt: process.env.streamSalt,
|
||||
isAudioOnly: fetchInfo["isAudioOnly"] ? fetchInfo["isAudioOnly"] : false,
|
||||
time: r.time,
|
||||
}) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
case "reddit":
|
||||
if (patternMatch["sub"] && patternMatch["id"] && patternMatch["title"] && patternMatch["sub"].length <= 22 && patternMatch["id"].length <= 10 && patternMatch["title"].length <= 96) {
|
||||
let r = await reddit({
|
||||
sub: patternMatch["sub"],
|
||||
id: patternMatch["id"],
|
||||
title: patternMatch["title"]
|
||||
});
|
||||
return (!r.error) ? apiJSON(2, {
|
||||
type: "render", urls: r.urls,
|
||||
service: host, ip: ip,
|
||||
filename: r.filename, salt: process.env.streamSalt
|
||||
}) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
default:
|
||||
return apiJSON(0, { t: errorUnsupported(lang) })
|
||||
}
|
||||
} catch (e) {
|
||||
return apiJSON(0, { t: genericError(lang, host) })
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user