api: flatten code directories, better filenames, remove old files
This commit is contained in:
124
api/src/processing/services/reddit.js
Normal file
124
api/src/processing/services/reddit.js
Normal file
@@ -0,0 +1,124 @@
|
||||
import { genericUserAgent, env } from "../../config.js";
|
||||
import { getCookie, updateCookieValues } from "../cookie/manager.js";
|
||||
|
||||
async function getAccessToken() {
|
||||
/* "cookie" in cookiefile needs to contain:
|
||||
* client_id, client_secret, refresh_token
|
||||
* e.g. client_id=bla; client_secret=bla; refresh_token=bla
|
||||
*
|
||||
* you can get these by making a reddit app and
|
||||
* authenticating an account against reddit's oauth2 api
|
||||
* see: https://github.com/reddit-archive/reddit/wiki/OAuth2
|
||||
*
|
||||
* any additional cookie fields are managed by this code and you
|
||||
* should not touch them unless you know what you're doing. **/
|
||||
const cookie = await getCookie('reddit');
|
||||
if (!cookie) return;
|
||||
|
||||
const values = cookie.values(),
|
||||
needRefresh = !values.access_token
|
||||
|| !values.expiry
|
||||
|| Number(values.expiry) < new Date().getTime();
|
||||
if (!needRefresh) return values.access_token;
|
||||
|
||||
const data = await fetch('https://www.reddit.com/api/v1/access_token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Basic ${Buffer.from(
|
||||
[values.client_id, values.client_secret].join(':')
|
||||
).toString('base64')}`,
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
'user-agent': genericUserAgent,
|
||||
'accept': 'application/json'
|
||||
},
|
||||
body: `grant_type=refresh_token&refresh_token=${encodeURIComponent(values.refresh_token)}`
|
||||
}).then(r => r.json()).catch(() => {});
|
||||
if (!data) return;
|
||||
|
||||
const { access_token, refresh_token, expires_in } = data;
|
||||
if (!access_token) return;
|
||||
|
||||
updateCookieValues(cookie, {
|
||||
...cookie.values(),
|
||||
access_token, refresh_token,
|
||||
expiry: new Date().getTime() + (expires_in * 1000),
|
||||
});
|
||||
|
||||
return access_token;
|
||||
}
|
||||
|
||||
export default async function(obj) {
|
||||
let url = new URL(`https://www.reddit.com/r/${obj.sub}/comments/${obj.id}.json`);
|
||||
|
||||
if (obj.user) {
|
||||
url.pathname = `/user/${obj.user}/comments/${obj.id}.json`;
|
||||
}
|
||||
|
||||
const accessToken = await getAccessToken();
|
||||
if (accessToken) url.hostname = 'oauth.reddit.com';
|
||||
|
||||
let data = await fetch(
|
||||
url, {
|
||||
headers: {
|
||||
'User-Agent': genericUserAgent,
|
||||
accept: 'application/json',
|
||||
authorization: accessToken && `Bearer ${accessToken}`
|
||||
}
|
||||
}
|
||||
).then(r => r.json()).catch(() => {});
|
||||
|
||||
if (!data || !Array.isArray(data)) return { error: 'ErrorCouldntFetch' };
|
||||
|
||||
data = data[0]?.data?.children[0]?.data;
|
||||
|
||||
if (data?.url?.endsWith('.gif')) return {
|
||||
typeId: "redirect",
|
||||
urls: data.url
|
||||
}
|
||||
|
||||
if (!data.secure_media?.reddit_video)
|
||||
return { error: 'ErrorEmptyDownload' };
|
||||
|
||||
if (data.secure_media?.reddit_video?.duration > env.durationLimit)
|
||||
return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
|
||||
|
||||
let audio = false,
|
||||
video = data.secure_media?.reddit_video?.fallback_url?.split('?')[0],
|
||||
audioFileLink = `${data.secure_media?.reddit_video?.fallback_url?.split('DASH')[0]}audio`;
|
||||
|
||||
if (video.match('.mp4')) {
|
||||
audioFileLink = `${video.split('_')[0]}_audio.mp4`
|
||||
}
|
||||
|
||||
// test the existence of audio
|
||||
await fetch(audioFileLink, { method: "HEAD" }).then(r => {
|
||||
if (Number(r.status) === 200) {
|
||||
audio = true
|
||||
}
|
||||
}).catch(() => {})
|
||||
|
||||
// fallback for videos with variable audio quality
|
||||
if (!audio) {
|
||||
audioFileLink = `${video.split('_')[0]}_AUDIO_128.mp4`
|
||||
await fetch(audioFileLink, { method: "HEAD" }).then(r => {
|
||||
if (Number(r.status) === 200) {
|
||||
audio = true
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
let id = `${String(obj.sub).toLowerCase()}_${obj.id}`;
|
||||
|
||||
if (!audio) return {
|
||||
typeId: "redirect",
|
||||
urls: video
|
||||
}
|
||||
|
||||
return {
|
||||
typeId: "stream",
|
||||
type: "render",
|
||||
urls: [video, audioFileLink],
|
||||
audioFilename: `reddit_${id}_audio`,
|
||||
filename: `reddit_${id}.mp4`
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user