diff --git a/inc/processJsonPost.js b/inc/processJsonPost.js
index d57711d..f54efa1 100644
--- a/inc/processJsonPost.js
+++ b/inc/processJsonPost.js
@@ -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,98 @@ async function finalizeJsonPost(
return { post_data: post_data, comments: comments_html };
}
+async function getPostItem(post_json, req) {
+ let protocol = config.https_enabled || config.api_force_https ? 'https' : 'http';
+ 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 = ``;
+ }
+
+ let append_desc_html = `
[link] [comments]`;
+
+ return `
+ -
+ ${post_json.title}
+ ${post_json.author}
+ ${post_json.created}
+ ${new Date(
+ post_json.created_utc * 1000
+ ).toGMTString()}
+ ${post_json.domain}
+ ${post_json.id}
+ ${thumbnail}
+ ${enclosure}
+ ${post_json.permalink}
+ ${post_json.url}
+
+ ${post_json.num_comments}
+ ${post_json.ups}
+ ${post_json.stickied}
+ ${is_self_link}
+
+ `;
+}
+
module.exports = {
processReplies,
processJsonPost,
finalizeJsonPost,
+ getPostItem
};
diff --git a/inc/teddit_api/handlePost.js b/inc/teddit_api/handlePost.js
new file mode 100644
index 0000000..ea74cd5
--- /dev/null
+++ b/inc/teddit_api/handlePost.js
@@ -0,0 +1,88 @@
+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');
+ let _json = json; // Keep the original json
+ 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);
+
+ 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 += `
+ -
+ ${title}
+ ${comment.author}
+ ${comment.created}
+ ${new Date(
+ comment.created_utc * 1000
+ ).toGMTString()}
+ ${comment.id}
+ ${comment.permalink}
+
+ ${comment.ups}
+
+ `;
+ }
+ }
+
+ let xml_output = `
+
+
+
+ ${post.title}
+ ${post.url}
+ ${items}
+
+ `;
+ 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));
+ }
+ }
+ };
+};
diff --git a/routes/subreddit.js b/routes/subreddit.js
index 5891d35..68143fe 100644
--- a/routes/subreddit.js
+++ b/routes/subreddit.js
@@ -10,6 +10,7 @@ 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');
@@ -605,6 +606,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 +646,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 +663,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 +750,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,
+ });
+ }
})();
}
}