teddit/routes/home.js

269 行
8.4 KiB
JavaScript
Raw パーマリンク Blame 履歴

このファイルには曖昧(ambiguous)なUnicode文字が含まれています

このファイルには、他の文字と見間違える可能性があるUnicode文字が含まれています。 それが意図的なものと考えられる場合は、この警告を無視して構いません。 それらの文字を表示するにはエスケープボタンを使用します。

const config = require('../config');
const { redis, fetch } = require('../app');
const homeRoute = require('express').Router();
const processJsonSubreddit = require('../inc/processJsonSubreddit.js');
const tedditApiSubreddit = require('../inc/teddit_api/handleSubreddit.js')();
const processMoreComments = require('../inc/processMoreComments.js')();
homeRoute.get('/', (req, res, next) => {
if (
(config.clean_homepage && req.cookies.prefer_frontpage !== 'true') ||
(!config.clean_homepage && req.cookies.prefer_frontpage == 'undefined')
) {
return res.render('homepage', {
user_preferences: req.cookies,
instance_config: config,
});
}
next();
});
homeRoute.get([`/:sort?`, '/frontpage'], async (req, res, next) => {
let past = req.query.t;
let before = req.query.before;
let after = req.query.after;
let sortby = req.params.sort || '';
let api_req = req.query.api;
let api_type = req.query.type;
let api_target = req.query.target;
let proxyable =
sortby.includes('.jpg') ||
sortby.includes('.png') ||
sortby.includes('.jpeg') ||
sortby.includes('.mp4') ||
sortby.includes('.gif') ||
sortby.includes('.gifv')
? true
: false;
if (proxyable) {
let media_url = '';
const replacable_media_domains = ['i.redd.it', 'v.redd.it', 'external-preview.redd.it', 'preview.redd.it']
if (req.query.teddit_proxy) {
if (replacable_media_domains.includes(req.query.teddit_proxy)) {
let full_url = req.protocol + '://' + req.get('host') + req.originalUrl;
let u = new URL(full_url);
let filename = u.pathname || '';
let query = u.search || '';
if (query != '') {
let params = new URLSearchParams(query);
params.delete('teddit_proxy');
query = '?' + params.toString();
}
media_url = `https://${req.query.teddit_proxy}${filename}${query}`;
}
} else {
let params = new URLSearchParams(req.query).toString();
media_url = `https://preview.redd.it/${sortby}?${params}`;
if (media_url.includes('teddit_proxy')) {
// if the URL includes teddit_proxy query param, remove everything after it
media_url = media_url.split('%3Fteddit_proxy')[0];
}
}
let proxied_media = await downloadAndSave(media_url);
if (proxied_media) {
return res.redirect(proxied_media);
} else {
return res.redirect('/');
}
}
let is_comment =
(sortby.length == 6 || sortby.length == 7) &&
sortby != "rising"
? true
: false;
if (is_comment) {
return res.redirect('/comments/' + sortby);
}
let d = `&after=${after}`;
if (before) {
d = `&before=${before}`;
}
if (sortby == '' || sortby == 'frontpage') {
sortby = 'hot';
}
if (
[
'apple-touch-icon.png',
'apple-touch-icon-precomposed.png',
'apple-touch-icon-120x120.png',
'apple-touch-icon-120x120-precomposed.png',
].includes(sortby)
) {
return res.sendStatus(404); // return 404 on shitty apple favicon stuff
}
if (
!['new', 'rising', 'controversial', 'top', 'gilded', 'hot'].includes(sortby)
) {
console.log(`Got invalid sort.`, req.originalUrl);
return res.redirect('/');
}
if (past) {
if (sortby === 'controversial' || sortby === 'top') {
if (!['hour', 'day', 'week', 'month', 'year', 'all'].includes(past)) {
console.error(`Got invalid past.`, req.originalUrl);
return res.redirect(`/`);
}
} else {
past = undefined;
}
} else {
if (sortby === 'controversial' || sortby === 'top') {
past = 'day';
}
}
if (req.query.hasOwnProperty('api')) api_req = true;
else api_req = false;
let raw_json = api_req && req.query.raw_json == '1' ? 1 : 0;
let key = `/after:${after}:before:${before}:sort:${sortby}:past:${past}:raw_json:${raw_json}`;
let subbed_subreddits = req.cookies.subbed_subreddits;
let get_subbed_subreddits = false;
if (subbed_subreddits && Array.isArray(subbed_subreddits)) {
get_subbed_subreddits = true;
subbed_subreddits = subbed_subreddits.join('+');
key = `${subbed_subreddits.toLowerCase()}:${after}:${before}:sort:${sortby}:past:${past}:raw_json:${raw_json}`;
}
redis.get(key, (error, json) => {
if (error) {
console.error('Error getting the frontpage key from redis.', error);
return res.render('frontpage', {
json: null,
user_preferences: req.cookies,
instance_config: config,
});
}
if (json) {
console.log('Got frontpage key from redis.');
(async () => {
if (api_req) {
return handleTedditApiSubreddit(
json,
req,
res,
'redis',
api_type,
api_target,
'/',
'full'
);
} else {
let processed_json = await processJsonSubreddit(
json,
'redis',
null,
req.cookies
);
return res.render('frontpage', {
json: processed_json,
sortby: sortby,
past: past,
user_preferences: req.cookies,
redis_key: key,
instance_config: config,
});
}
})();
} else {
let url = '';
if (config.use_reddit_oauth) {
if (get_subbed_subreddits)
url = `https://oauth.reddit.com/r/${subbed_subreddits}/${sortby}?api_type=json&count=25&g=GLOBAL&t=${past}${d}&raw_json=${raw_json}`;
else
url = `https://oauth.reddit.com/${sortby}?api_type=json&g=GLOBAL&t=${past}${d}&raw_json=${raw_json}`;
} else {
if (get_subbed_subreddits)
url = `https://reddit.com/r/${subbed_subreddits}/${sortby}.json?api_type=json&count=25&g=GLOBAL&t=${past}${d}&raw_json=${raw_json}`;
else
url = `https://reddit.com/${sortby}.json?g=GLOBAL&t=${past}${d}&raw_json=${raw_json}`;
}
fetch(encodeURI(url), redditApiGETHeaders())
.then((result) => {
if (result.status === 200) {
result.json().then((json) => {
redis.setex(
key,
config.setexs.frontpage,
JSON.stringify(json),
(error) => {
if (error) {
console.error(
'Error setting the frontpage key to redis.',
error
);
return res.render('frontpage', {
json: null,
user_preferences: req.cookies,
instance_config: config,
});
} else {
console.log('Fetched the frontpage from Reddit.');
(async () => {
if (api_req) {
return handleTedditApiSubreddit(
json,
req,
res,
'from_online',
api_type,
api_target,
'/',
'full'
);
} else {
let processed_json = await processJsonSubreddit(
json,
'from_online',
null,
req.cookies
);
return res.render('frontpage', {
json: processed_json,
sortby: sortby,
past: past,
user_preferences: req.cookies,
redis_key: key,
instance_config: config,
});
}
})();
}
}
);
});
} else {
console.error(
`Something went wrong while fetching data from Reddit. ${result.status} ${result.statusText}`
);
console.error(config.reddit_api_error_text);
return res.render('frontpage', {
json: null,
http_status_code: result.status,
user_preferences: req.cookies,
instance_config: config,
});
}
})
.catch((error) => {
console.error('Error fetching the frontpage JSON file.', error);
});
}
});
});
module.exports = homeRoute;