Merge branch 'main' into main

This commit is contained in:
Anshuman Kumar 2023-01-02 11:46:26 +00:00
commit 0969d694db
10 changed files with 933 additions and 1993 deletions

View File

@ -12,4 +12,6 @@ COPY config.js.template ./config.js
RUN find ./static/ -type d -exec chmod -R 777 {} \;
EXPOSE 8080
CMD npm start

View File

@ -201,11 +201,15 @@ You can also run teddit from a process manager like [pm2](https://www.npmjs.com/
```
## To run:
npm install pm2 -g
pm2 start app.js
pm2 start app.js --name teddit
## To run on startup:
pm2 startup
pm2 save
pm2 save ## if using systemd, see below.
## To restart or stop
pm2 restart teddit
pm2 stop teddit
```
See also the [pm2 instructions for running a project on startup](https://pm2.keymetrics.io/docs/usage/startup/), and in particular the section on waiting for your machine to connect to its network.
See also the [pm2 instructions for running a project on startup](https://pm2.keymetrics.io/docs/usage/startup/). In particular, if using systemd, see the section on how to modify the systemd init file so that it runs after your system connects to the network.

View File

@ -73,7 +73,7 @@ module.exports = function(fetch) {
})
}
this.redditApiGETHeaders = function() {
let cookies = '_options=%7B%22pref_quarantine_optin%22%3A%20true%7D'
let cookies = `edgebucket=; _options={%22pref_gated_sr_optin%22:true,%22pref_quarantine_optin%22:true}`
if(!config.use_reddit_oauth)
return { headers: { cookie: cookies }, method: 'GET' }

View File

@ -1,5 +1,6 @@
const compilePostComments = require('./compilePostComments.js')();
const procPostMedia = require('./processPostMedia.js')();
const config = require('../config');
async function processReplies(data, post_id, depth, user_preferences) {
let return_replies = [];
@ -399,8 +400,141 @@ async function finalizeJsonPost(
return { post_data: post_data, comments: comments_html };
}
async function processJsonPostList(posts, mode) {
let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
for (var i = 0; i < posts.length; i++) {
let link = posts[i];
let valid_reddit_self_domains = ['reddit.com'];
let is_self_link = false;
if (link.domain) {
let tld = link.domain.split('self.');
if (tld.length > 1) {
if (!tld[1].includes('.')) {
is_self_link = true;
link.url = teddifyUrl(link.url);
}
}
if (
config.valid_media_domains.includes(link.domain) ||
valid_reddit_self_domains.includes(link.domain)
) {
is_self_link = true;
link.url = teddifyUrl(link.url);
}
}
link.permalink = `${protocol}://${config.domain}${link.permalink}`;
if (is_self_link) link.url = link.permalink;
if (link.images) {
if (link.images.thumb !== 'self') {
link.images.thumb = `${protocol}://${config.domain}${link.images.thumb}`;
}
}
if (mode === 'light') {
link.selftext_html = null;
}
}
return posts;
}
async function getPostItem(post_json, req, protocol) {
let thumbnail = '';
let post_image = '';
let is_self_link = false;
let valid_reddit_self_domains = ['reddit.com'];
if (post_json.domain) {
let tld = post_json.domain.split('self.');
if (tld.length > 1) {
if (!tld[1].includes('.')) {
is_self_link = true;
post_json.url = teddifyUrl(post_json.url);
}
}
if (
config.valid_media_domains.includes(post_json.domain) ||
valid_reddit_self_domains.includes(post_json.domain)
) {
is_self_link = true;
post_json.url = teddifyUrl(post_json.url);
}
}
if (post_json.preview && post_json.thumbnail !== 'self') {
if (!post_json.url.startsWith('/r/') && isGif(post_json.url)) {
let s = await downloadAndSave(post_json.thumbnail, 'thumb_');
thumbnail = `${protocol}://${config.domain}${s}`;
} else {
if (post_json.preview.images[0].resolutions[0]) {
let s = await downloadAndSave(
post_json.preview.images[0].resolutions[0].url,
'thumb_'
);
thumbnail = `${protocol}://${config.domain}${s}`;
if (!isGif(post_json.url) && !post_json.post_hint.includes(':video')) {
s = await downloadAndSave(post_json.preview.images[0].source.url);
post_image = `${protocol}://${config.domain}${s}`;
}
}
}
}
post_json.permalink = `${protocol}://${config.domain}${post_json.permalink}`;
if (is_self_link) post_json.url = post_json.permalink;
if (req.query.hasOwnProperty('full_thumbs')) {
if (!post_image) post_image = thumbnail;
thumbnail = post_image;
}
let enclosure = '';
if (thumbnail != '') {
let mime = '';
let ext = thumbnail.split('.').pop();
if (ext === 'png') mime = 'image/png';
else mime = 'image/jpeg';
enclosure = `<enclosure length="0" type="${mime}" url="${thumbnail}" />`;
}
let append_desc_html = `<br/><a href="${post_json.url}">[link]</a> <a href="${post_json.permalink}">[comments]</a>`;
return `
<item>
<title>${post_json.title}</title>
<author>${post_json.author}</author>
<created>${post_json.created}</created>
<pubDate>${new Date(
post_json.created_utc * 1000
).toGMTString()}</pubDate>
<domain>${post_json.domain}</domain>
<id>${post_json.id}</id>
<thumbnail>${thumbnail}</thumbnail>
${enclosure}
<link>${post_json.permalink}</link>
<url>${post_json.url}</url>
<description><![CDATA[${unescape(
post_json.selftext_html
)}${append_desc_html}]]></description>
<num_comments>${post_json.num_comments}</num_comments>
<ups>${post_json.ups}</ups>
<stickied>${post_json.stickied}</stickied>
<is_self_link>${is_self_link}</is_self_link>
</item>
`;
}
module.exports = {
processReplies,
processJsonPost,
finalizeJsonPost,
processJsonPostList,
getPostItem
};

View File

@ -64,4 +64,15 @@ async function processSubredditAbout(subreddit, redis, fetch, RedditAPI) {
}
}
module.exports = processSubredditAbout;
async function processJsonSubredditAbout(json, parsed) {
if (!parsed) {
json = JSON.parse(json);
}
return returnRelevantKeys(json);
}
module.exports = {
processSubredditAbout,
processJsonSubredditAbout
};

View File

@ -0,0 +1,87 @@
const { processJsonPost, getPostItem } = require('../processJsonPost');
module.exports = function () {
const config = require('../../config');
this.handleTedditApiPost = async (
json,
req,
res,
from,
api_type,
api_target
) => {
if (!config.api_enabled) {
res.setHeader('Content-Type', 'application/json');
let msg = {
info: 'This instance do not support API requests. Please see https://codeberg.org/teddit/teddit#instances for instances that support API, or setup your own instance.',
};
return res.end(JSON.stringify(msg));
}
console.log('Teddit API request - post');
if (from === 'redis') json = JSON.parse(json);
if (api_type === 'rss') {
let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
let items = '';
let post = json[0].data.children[0].data;
let comments = json[1].data.children;
items += await getPostItem(post, req, protocol);
for (var i = 0; i < comments.length; i++) {
let comment = comments[i].data;
let kind = comments[i].kind;
let title = `/u/${comment.author} on ${post.title}`;
comment.permalink = `${protocol}://${config.domain}${comment.permalink}`;
if (kind !== 'more') {
items += `
<item>
<title>${title}</title>
<author>${comment.author}</author>
<created>${comment.created}</created>
<pubDate>${new Date(
comment.created_utc * 1000
).toGMTString()}</pubDate>
<id>${comment.id}</id>
<link>${comment.permalink}</link>
<description><![CDATA[${unescape(
comment.body_html
)}]]></description>
<ups>${comment.ups}</ups>
</item>
`;
}
}
let xml_output = `<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<atom:link href="${post.permalink}?api&amp;type=rss" rel="self" type="application/rss+xml" />
<title>${post.title}</title>
<link>${post.url}</link>
${items}
</channel>
</rss>`;
res.setHeader('Content-Type', 'application/rss+xml');
return res.end(xml_output);
} else {
res.setHeader('Content-Type', 'application/json');
if (api_target === 'reddit') {
return res.end(JSON.stringify(json));
} else {
let processed_json = await processJsonPost(
json,
true,
req.cookies
);
return res.end(JSON.stringify(processed_json));
}
}
};
};

View File

@ -1,4 +1,8 @@
const processJsonSubreddit = require('../processJsonSubreddit');
const { processJsonSubredditAbout } = require('../processSubredditAbout');
const processSearchResults = require('../processSearchResults.js');
const { processJsonPostList, getPostItem } = require('../processJsonPost');
const processJsonSubredditsExplore = require('../processSubredditsExplore.js');
module.exports = function () {
const config = require('../../config');
@ -27,93 +31,10 @@ module.exports = function () {
if (api_type === 'rss') {
let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
let items = '';
for (var i = 0; i < json.data.children.length; i++) {
let link = json.data.children[i].data;
let thumbnail = '';
let post_image = '';
let is_self_link = false;
let valid_reddit_self_domains = ['reddit.com'];
if (link.domain) {
let tld = link.domain.split('self.');
if (tld.length > 1) {
if (!tld[1].includes('.')) {
is_self_link = true;
link.url = teddifyUrl(link.url);
}
}
if (
config.valid_media_domains.includes(link.domain) ||
valid_reddit_self_domains.includes(link.domain)
) {
is_self_link = true;
link.url = teddifyUrl(link.url);
}
}
if (link.preview && link.thumbnail !== 'self') {
if (!link.url.startsWith('/r/') && isGif(link.url)) {
let s = await downloadAndSave(link.thumbnail, 'thumb_');
thumbnail = `${protocol}://${config.domain}${s}`;
} else {
if (link.preview.images[0].resolutions[0]) {
let s = await downloadAndSave(
link.preview.images[0].resolutions[0].url,
'thumb_'
);
thumbnail = `${protocol}://${config.domain}${s}`;
if (!isGif(link.url) && !link.post_hint.includes(':video')) {
s = await downloadAndSave(link.preview.images[0].source.url);
post_image = `${protocol}://${config.domain}${s}`;
}
}
}
}
link.permalink = `${protocol}://${config.domain}${link.permalink}`;
if (is_self_link) link.url = link.permalink;
if (req.query.hasOwnProperty('full_thumbs')) {
if (!post_image) post_image = thumbnail;
thumbnail = post_image;
}
let enclosure = '';
if (thumbnail != '') {
let mime = '';
let ext = thumbnail.split('.').pop();
if (ext === 'png') mime = 'image/png';
else mime = 'image/jpeg';
enclosure = `<enclosure length="0" type="${mime}" url="${thumbnail}" />`;
}
let append_desc_html = `<br/><a href="${link.url}">[link]</a> <a href="${link.permalink}">[comments]</a>`;
items += `
<item>
<title>${link.title}</title>
<author>${link.author}</author>
<created>${link.created}</created>
<pubDate>${new Date(
link.created_utc * 1000
).toGMTString()}</pubDate>
<domain>${link.domain}</domain>
<id>${link.id}</id>
<thumbnail>${thumbnail}</thumbnail>
${enclosure}
<link>${link.permalink}</link>
<url>${link.url}</url>
<description><![CDATA[${unescape(
link.selftext_html
)}${append_desc_html}]]></description>
<num_comments>${link.num_comments}</num_comments>
<ups>${link.ups}</ups>
<stickied>${link.stickied}</stickied>
<is_self_link>${is_self_link}</is_self_link>
</item>
`;
let post = json.data.children[i].data;
items += await getPostItem(post, req, protocol);
}
let r_subreddit = '/r/' + subreddit;
@ -149,43 +70,185 @@ module.exports = function () {
req.cookies
);
let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
for (var i = 0; i < processed_json.links.length; i++) {
let link = processed_json.links[i];
let valid_reddit_self_domains = ['reddit.com'];
let is_self_link = false;
await processJsonPostList(processed_json.links, mode);
if (link.domain) {
let tld = link.domain.split('self.');
if (tld.length > 1) {
if (!tld[1].includes('.')) {
is_self_link = true;
link.url = teddifyUrl(link.url);
}
}
if (
config.valid_media_domains.includes(link.domain) ||
valid_reddit_self_domains.includes(link.domain)
) {
is_self_link = true;
link.url = teddifyUrl(link.url);
}
}
return res.end(JSON.stringify(processed_json));
}
}
};
this.handleTedditApiSubredditAbout = async (
json,
res,
from,
api_target
) => {
if (!config.api_enabled) {
res.setHeader('Content-Type', 'application/json');
let msg = {
info: 'This instance do not support API requests. Please see https://codeberg.org/teddit/teddit#instances for instances that support API, or setup your own instance.',
};
return res.end(JSON.stringify(msg));
}
link.permalink = `${protocol}://${config.domain}${link.permalink}`;
console.log('Teddit API request - subreddit about');
if (from === 'redis') json = JSON.parse(json);
if (is_self_link) link.url = link.permalink;
res.setHeader('Content-Type', 'application/json');
if (link.images) {
if (link.images.thumb !== 'self') {
link.images.thumb = `${protocol}://${config.domain}${link.images.thumb}`;
}
}
if (api_target === 'reddit') {
return res.end(JSON.stringify(json));
} else {
let subreddit_about = await processJsonSubredditAbout(
json,
true
);
if (mode === 'light') {
link.selftext_html = null;
}
}
return res.end(JSON.stringify(subreddit_about));
}
};
this.handleTedditApiSubredditSearch = async (
json,
req,
res,
from,
api_type,
api_target,
subreddit,
query,
mode
) => {
if (!config.api_enabled) {
res.setHeader('Content-Type', 'application/json');
let msg = {
info: 'This instance do not support API requests. Please see https://codeberg.org/teddit/teddit#instances for instances that support API, or setup your own instance.',
};
return res.end(JSON.stringify(msg));
}
console.log('Teddit API request - subreddit search');
if (from === 'redis') json = JSON.parse(json);
if (api_type === 'rss') {
let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
let items = '';
for (var i = 0; i < json.data.children.length; i++) {
let post = json.data.children[i].data;
items += await getPostItem(post, req, protocol);
}
let r_subreddit = '/r/' + subreddit;
let title = `${query} - ${r_subreddit}`;
let link = `${protocol}://${config.domain}${r_subreddit}/search?q=${query}`;
let xml_output = `<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<atom:link href="${link}&amp;api&amp;type=rss" rel="self" type="application/rss+xml" />
<title>${title}</title>
<link>${link}</link>
<description>Results for: ${query} - ${r_subreddit}</description>
${items}
</channel>
</rss>`;
res.setHeader('Content-Type', 'application/rss+xml');
return res.end(xml_output);
} else {
res.setHeader('Content-Type', 'application/json');
if (api_target === 'reddit') {
return res.end(JSON.stringify(json));
} else {
let processed_json = await processSearchResults(
json,
true,
null,
null,
req.cookies
);
await processJsonPostList(processed_json.posts, mode);
return res.end(JSON.stringify(processed_json));
}
}
};
this.handleTedditApiSubredditsExplore = async (
json,
req,
res,
from,
api_type,
api_target,
query
) => {
if (!config.api_enabled) {
res.setHeader('Content-Type', 'application/json');
let msg = {
info: 'This instance do not support API requests. Please see https://codeberg.org/teddit/teddit#instances for instances that support API, or setup your own instance.',
};
return res.end(JSON.stringify(msg));
}
console.log('Teddit API request - subreddit explore');
if (from === 'redis') json = JSON.parse(json);
if (api_type === 'rss') {
let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
let items = '';
let children_len = json.data.children.length;
for (var i = 0; i < children_len; i++) {
let data = json.data.children[i].data;
items += `
<item>
<title>${data.title}</title>
<created>${data.created}</created>
<pubDate>${new Date(
data.created_utc * 1000
).toGMTString()}</pubDate>
<id>${data.id}</id>
<name>${data.display_name}</name>
<name_prefixed>${data.display_name_prefixed}</name_prefixed>
<url>${replaceDomains(data.url, req.cookies)}</url>
<description><![CDATA[${unescape(
data.public_description_html
)}]]></description>
<subscribers>${data.subscribers}</subscribers>
<over_18>${data.over18}</over_18>
</item>
`;
}
let title = `${query}`;
let link = `${protocol}://${config.domain}/subreddits/search?q=${query}`;
let xml_output = `<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<atom:link href="${link}&amp;api&amp;type=rss" rel="self" type="application/rss+xml" />
<title>${title}</title>
<link>${link}</link>
<description>Results for: ${query}</description>
${items}
</channel>
</rss>`;
res.setHeader('Content-Type', 'application/rss+xml');
return res.end(xml_output);
} else {
res.setHeader('Content-Type', 'application/json');
if (api_target === 'reddit') {
return res.end(JSON.stringify(json));
} else {
let processed_json = await processJsonSubredditsExplore(
json,
true,
null,
req.cookies
);
return res.end(JSON.stringify(processed_json));
}

1818
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@
"dependencies": {
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"express": "^4.17.1",
"express": "^4.18.2",
"helmet": "^4.6.0",
"https-proxy-agent": "^5.0.0",
"minizlib": "^2.1.2",

View File

@ -6,16 +6,28 @@ const {
processJsonPost,
finalizeJsonPost,
} = require('../inc/processJsonPost.js');
const processSubredditAbout = require('../inc/processSubredditAbout.js');
const {
processSubredditAbout
} = require('../inc/processSubredditAbout.js');
const processSearchResults = require('../inc/processSearchResults.js');
const processJsonSubreddit = require('../inc/processJsonSubreddit.js');
const tedditApiSubreddit = require('../inc/teddit_api/handleSubreddit.js')();
const tedditApiPost = require('../inc/teddit_api/handlePost.js')();
const processMoreComments = require('../inc/processMoreComments.js');
const processJsonSubredditsExplore = require('../inc/processSubredditsExplore.js');
subredditRoutes.get('/r/:subreddit/search', (req, res, next) => {
let subreddit = req.params.subreddit;
let q = req.query.q;
let api_req = req.query.api;
let api_type = req.query.type;
let api_target = req.query.target;
let api_mode = req.query.mode;
if (req.query.hasOwnProperty('api')) api_req = true;
else api_req = false;
let raw_json = api_req && req.query.raw_json == '1' ? 1 : 0;
if (typeof q === 'undefined') {
return res.render('search', {
@ -62,7 +74,7 @@ subredditRoutes.get('/r/:subreddit/search', (req, res, next) => {
count = '';
}
let key = `search:${subreddit}:${q}:${restrict_sr}:${sortby}:${past}:${after}:${before}:${nsfw}`;
let key = `search:${subreddit}:${q}:${restrict_sr}:${sortby}:${past}:${after}:${before}:${nsfw}:raw_json:${raw_json}`;
redis.get(key, (error, json) => {
if (error) {
console.error('Error getting the search key from redis.', error);
@ -75,32 +87,46 @@ subredditRoutes.get('/r/:subreddit/search', (req, res, next) => {
if (json) {
console.log('Got search key from redis.');
(async () => {
let processed_json = await processSearchResults(
json,
false,
after,
before,
req.cookies
);
return res.render('search', {
json: processed_json,
no_query: false,
q: q,
restrict_sr: restrict_sr,
nsfw: nsfw,
subreddit: subreddit,
sortby: sortby,
past: past,
user_preferences: req.cookies,
instance_config: config,
});
if (api_req) {
return handleTedditApiSubredditSearch(
json,
req,
res,
'redis',
api_type,
api_target,
subreddit,
q,
api_mode
);
} else {
let processed_json = await processSearchResults(
json,
false,
after,
before,
req.cookies
);
return res.render('search', {
json: processed_json,
no_query: false,
q: q,
restrict_sr: restrict_sr,
nsfw: nsfw,
subreddit: subreddit,
sortby: sortby,
past: past,
user_preferences: req.cookies,
instance_config: config,
});
}
})();
} else {
let url = '';
if (config.use_reddit_oauth)
url = `https://oauth.reddit.com/r/${subreddit}/search?api_type=json&q=${q}&restrict_sr=${restrict_sr}&include_over_18=${nsfw}&sort=${sortby}&t=${past}${count}${d}`;
url = `https://oauth.reddit.com/r/${subreddit}/search?api_type=json&q=${q}&restrict_sr=${restrict_sr}&include_over_18=${nsfw}&sort=${sortby}&t=${past}${count}${d}&raw_json=${raw_json}`;
else
url = `https://reddit.com/r/${subreddit}/search.json?api_type=json&q=${q}&restrict_sr=${restrict_sr}&include_over_18=${nsfw}&sort=${sortby}&t=${past}${count}${d}`;
url = `https://reddit.com/r/${subreddit}/search.json?api_type=json&q=${q}&restrict_sr=${restrict_sr}&include_over_18=${nsfw}&sort=${sortby}&t=${past}${count}${d}&raw_json=${raw_json}`;
fetch(encodeURI(url), redditApiGETHeaders())
.then((result) => {
if (result.status === 200) {
@ -137,25 +163,39 @@ subredditRoutes.get('/r/:subreddit/search', (req, res, next) => {
} else {
console.log('Fetched search results from Reddit.');
(async () => {
let processed_json = await processSearchResults(
json,
true,
after,
before,
req.cookies
);
return res.render('search', {
no_query: false,
json: processed_json,
q: q,
restrict_sr: restrict_sr,
nsfw: nsfw,
subreddit: subreddit,
sortby: sortby,
past: past,
user_preferences: req.cookies,
instance_config: config,
});
if (api_req) {
return handleTedditApiSubredditSearch(
json,
req,
res,
'from_online',
api_type,
api_target,
subreddit,
q,
api_mode
);
} else {
let processed_json = await processSearchResults(
json,
true,
after,
before,
req.cookies
);
return res.render('search', {
no_query: false,
json: processed_json,
q: q,
restrict_sr: restrict_sr,
nsfw: nsfw,
subreddit: subreddit,
sortby: sortby,
past: past,
user_preferences: req.cookies,
instance_config: config,
});
}
})();
}
}
@ -182,6 +222,107 @@ subredditRoutes.get('/r/:subreddit/search', (req, res, next) => {
});
});
subredditRoutes.get('/r/:subreddit/about', (req, res, next) => {
let subreddit = req.params.subreddit;
let api_type = req.query.type;
let api_target = req.query.target;
let api_mode = req.query.mode;
if (!req.query.hasOwnProperty('api')) {
console.log(`This route is only available via the API.`, req.originalUrl);
return res.redirect(`/r/${subreddit}`);
}
let raw_json = req.query.raw_json == '1' ? 1 : 0;
let key = `about:${subreddit.toLowerCase()}:raw_json:${raw_json}`;
redis.get(key, (error, json) => {
if (error) {
console.error(`Error getting the about key from redis.`, error);
return res.render('frontpage', {
json: null,
user_preferences: req.cookies,
instance_config: config,
});
}
if (json) {
console.log(`Got about key from redis.`);
(async () => {
return handleTedditApiSubredditAbout(
json,
res,
'redis',
api_target
);
})();
} else {
let url = '';
if (config.use_reddit_oauth)
url = `https://oauth.reddit.com/r/${subreddit}/about.json?api_type=json&raw_json=${raw_json}`;
else
url = `https://reddit.com/r/${subreddit}/about.json?api_type=json&raw_json=${raw_json}`;
fetch(encodeURI(url), redditApiGETHeaders())
.then((result) => {
if (result.status === 200) {
result.json().then((json) => {
redis.setex(
key,
config.setexs.subreddit,
JSON.stringify(json),
(error) => {
if (error) {
console.error(
`Error setting the about key to redis.`,
error
);
return res.render('subreddit', {
json: null,
user_preferences: req.cookies,
instance_config: config,
});
} else {
console.log(
`Fetched the JSON from reddit.com/r/${subreddit}/about.`
);
(async () => {
return handleTedditApiSubredditAbout(
json,
res,
'from_online',
api_target
);
})();
}
}
);
});
} else {
if (result.status === 404) {
console.log('404 Subreddit not found');
} 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 JSON file from reddit.com/r/${subreddit}/about.`,
error
);
});
}
});
});
subredditRoutes.get(
'/r/:subreddit/wiki/:page?/:sub_page?',
(req, res, next) => {
@ -605,6 +746,14 @@ subredditRoutes.get(
let viewing_comment = false;
let comment_ids = req.query.comment_ids;
let context = parseInt(req.query.context);
let api_req = req.query.api;
let api_type = req.query.type;
let api_target = req.query.target;
if (req.query.hasOwnProperty('api')) api_req = true;
else api_req = false;
let raw_json = api_req && req.query.raw_json == '1' ? 1 : 0;
if (req.params.comment_id) {
comment_id = `${req.params.comment_id}/`;
@ -637,7 +786,7 @@ subredditRoutes.get(
let comments_url = `/r/${subreddit}/comments/${id}/${snippet}/${comment_id}`;
let post_url = `/r/${subreddit}/comments/${id}/${snippet}/`;
let comments_key = `${comments_url}:sort:${sortby}`;
let comments_key = `${comments_url}:sort:${sortby}:raw_json:${raw_json}`;
redis.get(comments_key, (error, json) => {
if (error) {
@ -654,57 +803,68 @@ subredditRoutes.get(
if (json) {
console.log(`Got ${comments_url} key from redis.`);
(async () => {
let parsed = false;
let more_comments = null;
if (comment_ids) {
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`;
more_comments = await processMoreComments(
fetch,
redis,
post_url,
comment_ids,
id
if (api_req) {
return handleTedditApiPost(
json,
req,
res,
'redis',
api_type,
api_target
);
} else {
let parsed = false;
let more_comments = null;
if (comment_ids) {
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`;
more_comments = await processMoreComments(
fetch,
redis,
post_url,
comment_ids,
id
);
if (more_comments === false) {
return res.redirect(post_url);
} else {
json = JSON.parse(json);
json[1].data.children = more_comments;
parsed = true;
if (more_comments === false) {
return res.redirect(post_url);
} else {
json = JSON.parse(json);
json[1].data.children = more_comments;
parsed = true;
}
}
}
let processed_json = await processJsonPost(json, parsed, req.cookies);
let finalized_json = await finalizeJsonPost(
processed_json,
id,
post_url,
more_comments,
viewing_comment,
req.cookies
);
return res.render('post', {
post: finalized_json.post_data,
comments: finalized_json.comments,
viewing_comment: viewing_comment,
post_url: post_url,
subreddit: subreddit,
sortby: sortby,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_videos_muted: config.videos_muted,
post_media_max_heights: config.post_media_max_heights,
redis_key: comments_key,
instance_config: config,
});
let processed_json = await processJsonPost(json, parsed, req.cookies);
let finalized_json = await finalizeJsonPost(
processed_json,
id,
post_url,
more_comments,
viewing_comment,
req.cookies
);
return res.render('post', {
post: finalized_json.post_data,
comments: finalized_json.comments,
viewing_comment: viewing_comment,
post_url: post_url,
subreddit: subreddit,
sortby: sortby,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_videos_muted: config.videos_muted,
post_media_max_heights: config.post_media_max_heights,
redis_key: comments_key,
instance_config: config,
});
}
})();
} else {
let url = '';
if (config.use_reddit_oauth)
url = `https://oauth.reddit.com${comments_url}?api_type=json&sort=${sortby}&context=${context}`;
url = `https://oauth.reddit.com${comments_url}?api_type=json&sort=${sortby}&context=${context}&raw_json=${raw_json}`;
else
url = `https://reddit.com${comments_url}.json?api_type=json&sort=${sortby}&context=${context}`;
url = `https://reddit.com${comments_url}.json?api_type=json&sort=${sortby}&context=${context}&raw_json=${raw_json}`;
fetch(encodeURI(url), redditApiGETHeaders())
.then((result) => {
@ -730,51 +890,62 @@ subredditRoutes.get(
`Fetched the JSON from reddit.com${comments_url}.`
);
(async () => {
let more_comments = null;
if (comment_ids) {
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`;
more_comments = await processMoreComments(
fetch,
redis,
post_url,
comment_ids,
id
if (api_req) {
return handleTedditApiPost(
json,
req,
res,
'from_online',
api_type,
api_target
);
} else {
let more_comments = null;
if (comment_ids) {
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`;
more_comments = await processMoreComments(
fetch,
redis,
post_url,
comment_ids,
id
);
if (more_comments === false) {
return res.redirect(post_url);
} else {
json[1].data.children = more_comments;
if (more_comments === false) {
return res.redirect(post_url);
} else {
json[1].data.children = more_comments;
}
}
}
let processed_json = await processJsonPost(
json,
true,
req.cookies
);
let finalized_json = await finalizeJsonPost(
processed_json,
id,
post_url,
more_comments,
viewing_comment,
req.cookies
);
return res.render('post', {
post: finalized_json.post_data,
comments: finalized_json.comments,
viewing_comment: viewing_comment,
post_url: post_url,
subreddit: subreddit,
sortby: sortby,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_videos_muted: config.videos_muted,
post_media_max_heights: config.post_media_max_heights,
redis_key: comments_key,
instance_config: config,
});
let processed_json = await processJsonPost(
json,
true,
req.cookies
);
let finalized_json = await finalizeJsonPost(
processed_json,
id,
post_url,
more_comments,
viewing_comment,
req.cookies
);
return res.render('post', {
post: finalized_json.post_data,
comments: finalized_json.comments,
viewing_comment: viewing_comment,
post_url: post_url,
subreddit: subreddit,
sortby: sortby,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_videos_muted: config.videos_muted,
post_media_max_heights: config.post_media_max_heights,
redis_key: comments_key,
instance_config: config,
});
}
})();
}
}
@ -839,6 +1010,14 @@ subredditRoutes.get('/subreddits/:sort?', (req, res, next) => {
let before = req.query.before;
let sortby = req.params.sort;
let searching = false;
let api_req = req.query.api;
let api_type = req.query.type;
let api_target = req.query.target;
if (req.query.hasOwnProperty('api')) api_req = true;
else api_req = false;
let raw_json = api_req && req.query.raw_json == '1' ? 1 : 0;
if (!after) {
after = '';
@ -860,12 +1039,12 @@ subredditRoutes.get('/subreddits/:sort?', (req, res, next) => {
sortby = '';
}
let key = `subreddits:sort:${sortby}${d}`;
let key = `subreddits:sort:${sortby}${d}:raw_json:${raw_json}`;
if (sortby === 'search') {
if (typeof q == 'undefined' || q == '') return res.redirect('/subreddits');
key = `subreddits:search:q:${q}:nsfw:${nsfw}${d}`;
key = `subreddits:search:q:${q}:nsfw:${nsfw}${d}:raw_json:${raw_json}`;
searching = true;
}
@ -881,48 +1060,60 @@ subredditRoutes.get('/subreddits/:sort?', (req, res, next) => {
if (json) {
console.log(`Got subreddits key from redis.`);
(async () => {
let processed_json = await processJsonSubredditsExplore(
json,
'redis',
null,
req.cookies
);
if (!processed_json.error) {
return res.render('subreddits_explore', {
json: processed_json,
sortby: sortby,
after: after,
before: before,
q: q,
nsfw: nsfw,
searching: searching,
subreddits_front: !before && !after ? true : false,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_config: config,
});
if (api_req) {
return handleTedditApiSubredditsExplore(
json,
req,
res,
'redis',
api_type,
api_target,
q
);
} else {
return res.render('subreddits_explore', {
json: null,
error: true,
data: processed_json,
user_preferences: req.cookies,
instance_config: config,
});
let processed_json = await processJsonSubredditsExplore(
json,
'redis',
null,
req.cookies
);
if (!processed_json.error) {
return res.render('subreddits_explore', {
json: processed_json,
sortby: sortby,
after: after,
before: before,
q: q,
nsfw: nsfw,
searching: searching,
subreddits_front: !before && !after ? true : false,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_config: config,
});
} else {
return res.render('subreddits_explore', {
json: null,
error: true,
data: processed_json,
user_preferences: req.cookies,
instance_config: config,
});
}
}
})();
} else {
let url = '';
if (config.use_reddit_oauth) {
if (!searching)
url = `https://oauth.reddit.com/subreddits/${sortby}?api_type=json&count=25&g=GLOBAL&t=${d}`;
url = `https://oauth.reddit.com/subreddits/${sortby}?api_type=json&count=25&g=GLOBAL&t=${d}&raw_json=${raw_json}`;
else
url = `https://oauth.reddit.com/subreddits/search?api_type=json&q=${q}&include_over_18=${nsfw}${d}`;
url = `https://oauth.reddit.com/subreddits/search?api_type=json&q=${q}&include_over_18=${nsfw}${d}&raw_json=${raw_json}`;
} else {
if (!searching)
url = `https://reddit.com/subreddits/${sortby}.json?api_type=json&count=25&g=GLOBAL&t=${d}`;
url = `https://reddit.com/subreddits/${sortby}.json?api_type=json&count=25&g=GLOBAL&t=${d}&raw_json=${raw_json}`;
else
url = `https://reddit.com/subreddits/search.json?api_type=json&q=${q}&include_over_18=${nsfw}${d}`;
url = `https://reddit.com/subreddits/search.json?api_type=json&q=${q}&include_over_18=${nsfw}${d}&raw_json=${raw_json}`;
}
fetch(encodeURI(url), redditApiGETHeaders())
@ -946,25 +1137,37 @@ subredditRoutes.get('/subreddits/:sort?', (req, res, next) => {
} else {
console.log(`Fetched the JSON from reddit.com/subreddits.`);
(async () => {
let processed_json = await processJsonSubredditsExplore(
json,
'from_online',
null,
req.cookies
);
return res.render('subreddits_explore', {
json: processed_json,
sortby: sortby,
after: after,
before: before,
q: q,
nsfw: nsfw,
searching: searching,
subreddits_front: !before && !after ? true : false,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_config: config,
});
if (api_req) {
return handleTedditApiSubredditsExplore(
json,
req,
res,
'from_online',
api_type,
api_target,
q
);
} else {
let processed_json = await processJsonSubredditsExplore(
json,
'from_online',
null,
req.cookies
);
return res.render('subreddits_explore', {
json: processed_json,
sortby: sortby,
after: after,
before: before,
q: q,
nsfw: nsfw,
searching: searching,
subreddits_front: !before && !after ? true : false,
user_preferences: req.cookies,
instance_nsfw_enabled: config.nsfw_enabled,
instance_config: config,
});
}
})();
}
});