mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-10 07:18:30 +00:00
api: add support for newgrounds
Some checks are pending
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Run service tests / test service: ${{ matrix.service }} (push) Blocked by required conditions
Run service tests / test service functionality (push) Waiting to run
Run tests / check lockfile correctness (push) Waiting to run
Run tests / web sanity check (push) Waiting to run
Run tests / api sanity check (push) Waiting to run
Some checks are pending
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Run service tests / test service: ${{ matrix.service }} (push) Blocked by required conditions
Run service tests / test service functionality (push) Waiting to run
Run tests / check lockfile correctness (push) Waiting to run
Run tests / web sanity check (push) Waiting to run
Run tests / api sanity check (push) Waiting to run
closes #620, replaces #1368 Co-authored-by: hyperdefined <contact@hyper.lol>
This commit is contained in:
parent
172fb4c561
commit
61de303dc4
@ -23,6 +23,7 @@ if the desired service isn't supported yet, feel free to create an appropriate i
|
|||||||
| instagram | ✅ | ✅ | ✅ | ➖ | ➖ |
|
| instagram | ✅ | ✅ | ✅ | ➖ | ➖ |
|
||||||
| facebook | ✅ | ❌ | ✅ | ➖ | ➖ |
|
| facebook | ✅ | ❌ | ✅ | ➖ | ➖ |
|
||||||
| loom | ✅ | ❌ | ✅ | ✅ | ➖ |
|
| loom | ✅ | ❌ | ✅ | ✅ | ➖ |
|
||||||
|
| newgrounds | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| ok.ru | ✅ | ❌ | ✅ | ✅ | ✅ |
|
| ok.ru | ✅ | ❌ | ✅ | ✅ | ✅ |
|
||||||
| pinterest | ✅ | ✅ | ✅ | ➖ | ➖ |
|
| pinterest | ✅ | ✅ | ✅ | ➖ | ➖ |
|
||||||
| reddit | ✅ | ✅ | ✅ | ❌ | ❌ |
|
| reddit | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||||
|
@ -180,6 +180,7 @@ export default function({
|
|||||||
|
|
||||||
case "ok":
|
case "ok":
|
||||||
case "xiaohongshu":
|
case "xiaohongshu":
|
||||||
|
case "newgrounds":
|
||||||
params = { type: "proxy" };
|
params = { type: "proxy" };
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import loom from "./services/loom.js";
|
|||||||
import facebook from "./services/facebook.js";
|
import facebook from "./services/facebook.js";
|
||||||
import bluesky from "./services/bluesky.js";
|
import bluesky from "./services/bluesky.js";
|
||||||
import xiaohongshu from "./services/xiaohongshu.js";
|
import xiaohongshu from "./services/xiaohongshu.js";
|
||||||
|
import newgrounds from "./services/newgrounds.js";
|
||||||
|
|
||||||
let freebind;
|
let freebind;
|
||||||
|
|
||||||
@ -268,6 +269,13 @@ export default async function({ host, patternMatch, params, authType }) {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "newgrounds":
|
||||||
|
r = await newgrounds({
|
||||||
|
...patternMatch,
|
||||||
|
quality: params.videoQuality,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return createResponse("error", {
|
return createResponse("error", {
|
||||||
code: "error.api.service.unsupported"
|
code: "error.api.service.unsupported"
|
||||||
|
@ -74,6 +74,12 @@ export const services = {
|
|||||||
"url_shortener/:shortLink"
|
"url_shortener/:shortLink"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
newgrounds: {
|
||||||
|
patterns: [
|
||||||
|
"portal/view/:id",
|
||||||
|
"audio/listen/:audioId",
|
||||||
|
]
|
||||||
|
},
|
||||||
reddit: {
|
reddit: {
|
||||||
patterns: [
|
patterns: [
|
||||||
"comments/:id",
|
"comments/:id",
|
||||||
|
@ -79,4 +79,7 @@ export const testers = {
|
|||||||
"xiaohongshu": pattern =>
|
"xiaohongshu": pattern =>
|
||||||
pattern.id?.length <= 24 && pattern.token?.length <= 64
|
pattern.id?.length <= 24 && pattern.token?.length <= 64
|
||||||
|| pattern.shareId?.length <= 24,
|
|| pattern.shareId?.length <= 24,
|
||||||
|
|
||||||
|
"newgrounds": pattern =>
|
||||||
|
pattern.id?.length <= 12 || pattern.audioId?.length <= 12,
|
||||||
}
|
}
|
||||||
|
103
api/src/processing/services/newgrounds.js
Normal file
103
api/src/processing/services/newgrounds.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { genericUserAgent } from "../../config.js";
|
||||||
|
|
||||||
|
const getVideo = async ({ id, quality }) => {
|
||||||
|
const json = await fetch(`https://www.newgrounds.com/portal/video/${id}`, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": genericUserAgent,
|
||||||
|
"X-Requested-With": "XMLHttpRequest", // required to get the JSON response
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.catch(() => {});
|
||||||
|
|
||||||
|
if (!json) return { error: "fetch.empty" };
|
||||||
|
|
||||||
|
const videoSources = json.sources;
|
||||||
|
const videoQualities = Object.keys(videoSources);
|
||||||
|
|
||||||
|
if (videoQualities.length === 0) {
|
||||||
|
return { error: "fetch.empty" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const bestVideo = videoSources[videoQualities[0]]?.[0],
|
||||||
|
userQuality = quality === "2160" ? "4k" : `${quality}p`,
|
||||||
|
preferredVideo = videoSources[userQuality]?.[0],
|
||||||
|
video = preferredVideo || bestVideo,
|
||||||
|
videoQuality = preferredVideo ? userQuality : videoQualities[0];
|
||||||
|
|
||||||
|
if (!bestVideo || !video.type.includes("mp4")) {
|
||||||
|
return { error: "fetch.empty" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileMetadata = {
|
||||||
|
title: decodeURIComponent(json.title),
|
||||||
|
artist: decodeURIComponent(json.author),
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
urls: video.src,
|
||||||
|
filenameAttributes: {
|
||||||
|
service: "newgrounds",
|
||||||
|
id,
|
||||||
|
title: fileMetadata.title,
|
||||||
|
author: fileMetadata.artist,
|
||||||
|
extension: "mp4",
|
||||||
|
qualityLabel: videoQuality,
|
||||||
|
resolution: videoQuality,
|
||||||
|
},
|
||||||
|
fileMetadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMusic = async ({ id }) => {
|
||||||
|
const html = await fetch(`https://www.newgrounds.com/audio/listen/${id}`, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": genericUserAgent,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(r => r.text())
|
||||||
|
.catch(() => {});
|
||||||
|
|
||||||
|
if (!html) return { error: "fetch.fail" };
|
||||||
|
|
||||||
|
const params = JSON.parse(
|
||||||
|
`{${html.split(',"params":{')[1]?.split(',"images":')[0]}}`
|
||||||
|
);
|
||||||
|
if (!params) return { error: "fetch.empty" };
|
||||||
|
|
||||||
|
if (!params.name || !params.artist || !params.filename || !params.icon) {
|
||||||
|
return { error: "fetch.empty" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileMetadata = {
|
||||||
|
title: decodeURIComponent(params.name),
|
||||||
|
artist: decodeURIComponent(params.artist),
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
urls: params.filename,
|
||||||
|
filenameAttributes: {
|
||||||
|
service: "newgrounds",
|
||||||
|
id,
|
||||||
|
title: fileMetadata.title,
|
||||||
|
author: fileMetadata.artist,
|
||||||
|
},
|
||||||
|
fileMetadata,
|
||||||
|
cover:
|
||||||
|
params.icon.includes(".png?") || params.icon.includes(".jpg?")
|
||||||
|
? params.icon
|
||||||
|
: undefined,
|
||||||
|
isAudioOnly: true,
|
||||||
|
bestAudio: "mp3",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function({ id, audioId, quality }) {
|
||||||
|
if (id) {
|
||||||
|
return getVideo({ id, quality });
|
||||||
|
} else if (audioId) {
|
||||||
|
return getMusic({ id: audioId });
|
||||||
|
}
|
||||||
|
|
||||||
|
return { error: "fetch.empty" };
|
||||||
|
}
|
42
api/src/util/tests/newgrounds.json
Normal file
42
api/src/util/tests/newgrounds.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "regular video",
|
||||||
|
"url": "https://www.newgrounds.com/portal/view/938050",
|
||||||
|
"params": {},
|
||||||
|
"expected": {
|
||||||
|
"code": 200,
|
||||||
|
"status": "tunnel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "regular video (audio only)",
|
||||||
|
"url": "https://www.newgrounds.com/portal/view/938050",
|
||||||
|
"params": {
|
||||||
|
"downloadMode": "audio"
|
||||||
|
},
|
||||||
|
"expected": {
|
||||||
|
"code": 200,
|
||||||
|
"status": "tunnel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "regular video (muted)",
|
||||||
|
"url": "https://www.newgrounds.com/portal/view/938050",
|
||||||
|
"params": {
|
||||||
|
"downloadMode": "mute"
|
||||||
|
},
|
||||||
|
"expected": {
|
||||||
|
"code": 200,
|
||||||
|
"status": "tunnel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "regular music",
|
||||||
|
"url": "https://www.newgrounds.com/audio/listen/500476",
|
||||||
|
"params": {},
|
||||||
|
"expected": {
|
||||||
|
"code": 200,
|
||||||
|
"status": "tunnel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user