diff --git a/config.js.template b/config.js.template
index 5329de6..b9cd00e 100644
--- a/config.js.template
+++ b/config.js.template
@@ -2,6 +2,7 @@ const config = {
domain: process.env.DOMAIN || '127.0.0.1', // Or for example 'teddit.net'
reddit_app_id: process.env.REDDIT_APP_ID || 'H6-HjZ5pUPjaFQ', // You should obtain your own Reddit app ID. For testing purposes it's okay to use this project's default app ID. Create your Reddit app here: https://old.reddit.com/prefs/apps/. Make sure to create an "installed app" type of app.
cert_dir: process.env.CERT_DIR || '', // For example '/home/teddit/letsencrypt/live/teddit.net', if you are using https. No trailing slash.
+ api_enabled: process.env.API_ENABLED !== "true" || true, // Teddit API feature. Might increase loads significantly on your instance.
video_enabled: process.env.VIDEO_ENABLED !== "true" || true,
redis_enabled: process.env.REDIS_ENABLED !== "true" || true, // If disabled, does not cache Reddit API calls
redis_host: process.env.REDIS_HOST || '127.0.0.1',
diff --git a/inc/teddit_api/handleSubreddit.js b/inc/teddit_api/handleSubreddit.js
new file mode 100644
index 0000000..c78329f
--- /dev/null
+++ b/inc/teddit_api/handleSubreddit.js
@@ -0,0 +1,137 @@
+module.exports = function() {
+ const config = require('../../config')
+ this.handleTedditApiSubreddit = async (json, req, res, from, api_type, api_target, subreddit) => {
+ 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))
+ }
+
+ let _json = json // Keep the original json
+ if(from === 'redis')
+ json = JSON.parse(json)
+
+ if(api_type === 'rss') {
+ let protocol = (config.https_enabled ? 'https' : 'http')
+ let items = ''
+ for(var i = 0; i < json.data.children.length; i++) {
+ let link = json.data.children[i].data
+ let thumbnail = ''
+ 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}`
+ }
+ }
+ }
+
+ link.permalink = `${protocol}://${config.domain}${link.permalink}`
+
+ if(is_self_link)
+ link.url = link.permalink
+
+ items += `
+ -
+ ${link.title}
+ ${link.author}
+ ${link.created}
+ ${link.domain}
+ ${link.id}
+ ${thumbnail}
+ ${link.permalink}
+ ${link.url}
+ ${link.num_comments}
+ ${link.ups}
+ ${link.stickied}
+ ${is_self_link}
+
+ `
+ }
+
+ let r_subreddit = '/r/' + subreddit
+ let title = r_subreddit
+ let link = `${protocol}://${config.domain}${r_subreddit}`
+ if(subreddit === '/') {
+ r_subreddit = 'frontpage'
+ title = 'teddit frontpage'
+ link = `${protocol}://${config.domain}`
+ }
+
+ let xml_output =
+ `
+
+
+
+ ${title}
+ ${link}
+ Subreddit feed for: ${r_subreddit}
+ ${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 processJsonSubreddit(_json, from)
+
+ let protocol = (config.https_enabled ? '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
+
+ 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}`
+ }
+ }
+ }
+
+ return res.end(JSON.stringify(processed_json))
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 391f41f..8b04503 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "teddit",
- "version": "0.0.3",
+ "version": "0.0.5",
"description": "A free and open source alternative Reddit front-end focused on privacy.",
"homepage": "https://teddit.net",
"bugs": {
diff --git a/routes.js b/routes.js
index 6504f8e..c49a319 100644
--- a/routes.js
+++ b/routes.js
@@ -8,6 +8,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
let processUser = require('./inc/processJsonUser.js')();
let processSearches = require('./inc/processSearchResults.js')();
let processSidebar = require('./inc/processSubredditSidebar.js')();
+ let tedditApiSubreddit = require('./inc/teddit_api/handleSubreddit.js')();
app.get('/about', (req, res, next) => {
return res.render('about', { user_preferences: req.cookies })
@@ -59,6 +60,10 @@ module.exports = (app, redis, fetch, RedditAPI) => {
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 d = `&after=${after}`
if(before) {
d = `&before=${before}`
@@ -88,6 +93,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
}
}
+ if(req.query.hasOwnProperty('api'))
+ api_req = true
+ else
+ api_req = false
+
let key = `/after:${after}:before:${before}:sort:${sortby}:past:${past}`
redis.get(key, (error, json) => {
if(error) {
@@ -97,13 +107,17 @@ module.exports = (app, redis, fetch, RedditAPI) => {
if(json) {
console.log('Got frontpage key from redis.');
(async () => {
- let processed_json = await processJsonSubreddit(json, 'redis')
- return res.render('index', {
- json: processed_json,
- sortby: sortby,
- past: past,
- user_preferences: req.cookies
- })
+ if(api_req) {
+ return handleTedditApiSubreddit(json, req, res, 'redis', api_type, api_target, '/')
+ } else {
+ let processed_json = await processJsonSubreddit(json, 'redis')
+ return res.render('index', {
+ json: processed_json,
+ sortby: sortby,
+ past: past,
+ user_preferences: req.cookies
+ })
+ }
})()
} else {
fetch(encodeURI(`https://oauth.reddit.com/${sortby}?api_type=json&g=GLOBAL&t=${past}${d}`), redditApiGETHeaders())
@@ -118,13 +132,17 @@ module.exports = (app, redis, fetch, RedditAPI) => {
} else {
console.log('Fetched the frontpage from reddit API.');
(async () => {
- let processed_json = await processJsonSubreddit(json, 'from_online')
- return res.render('index', {
- json: processed_json,
- sortby: sortby,
- past: past,
- user_preferences: req.cookies
- })
+ if(api_req) {
+ return handleTedditApiSubreddit(json, req, res, 'from_online', api_type, api_target, '/')
+ } else {
+ let processed_json = await processJsonSubreddit(json, 'from_online')
+ return res.render('index', {
+ json: processed_json,
+ sortby: sortby,
+ past: past,
+ user_preferences: req.cookies
+ })
+ }
})()
}
})
@@ -313,6 +331,15 @@ module.exports = (app, redis, fetch, RedditAPI) => {
let past = req.query.t
let before = req.query.before
let after = req.query.after
+ 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 d = `&after=${after}`
if(before) {
d = `&before=${before}`
@@ -351,25 +378,29 @@ module.exports = (app, redis, fetch, RedditAPI) => {
if(json) {
console.log(`Got /r/${subreddit} key from redis.`);
(async () => {
- let processed_json = await processJsonSubreddit(json, 'redis')
- let sidebar_data = await processSubredditSidebar(subreddit, redis, fetch, RedditAPI)
- if(!processed_json.error) {
- return res.render('subreddit', {
- json: processed_json,
- subreddit: subreddit,
- sidebar_data: sidebar_data,
- subreddit_front: (!before && !after) ? true : false,
- sortby: sortby,
- past: past,
- user_preferences: req.cookies
- })
+ if(api_req) {
+ return handleTedditApiSubreddit(json, req, res, 'redis', api_type, api_target, subreddit)
} else {
- return res.render('subreddit', {
- json: null,
- error: true,
- data: processed_json,
- user_preferences: req.cookies
- })
+ let processed_json = await processJsonSubreddit(json, 'redis')
+ let sidebar_data = await processSubredditSidebar(subreddit, redis, fetch, RedditAPI)
+ if(!processed_json.error) {
+ return res.render('subreddit', {
+ json: processed_json,
+ subreddit: subreddit,
+ sidebar_data: sidebar_data,
+ subreddit_front: (!before && !after) ? true : false,
+ sortby: sortby,
+ past: past,
+ user_preferences: req.cookies
+ })
+ } else {
+ return res.render('subreddit', {
+ json: null,
+ error: true,
+ data: processed_json,
+ user_preferences: req.cookies
+ })
+ }
}
})()
} else {
@@ -385,17 +416,21 @@ module.exports = (app, redis, fetch, RedditAPI) => {
} else {
console.log(`Fetched the JSON from reddit.com/r/${subreddit}.`);
(async () => {
- let processed_json = await processJsonSubreddit(json, 'from_online')
- let sidebar_data = await processSubredditSidebar(subreddit, redis, fetch, RedditAPI)
- return res.render('subreddit', {
- json: processed_json,
- subreddit: subreddit,
- sidebar_data: sidebar_data,
- subreddit_front: (!before && !after) ? true : false,
- sortby: sortby,
- past: past,
- user_preferences: req.cookies
- })
+ if(api_req) {
+ return handleTedditApiSubreddit(json, req, res, 'from_online', api_type, api_target, subreddit)
+ } else {
+ let processed_json = await processJsonSubreddit(json, 'from_online')
+ let sidebar_data = await processSubredditSidebar(subreddit, redis, fetch, RedditAPI)
+ return res.render('subreddit', {
+ json: processed_json,
+ subreddit: subreddit,
+ sidebar_data: sidebar_data,
+ subreddit_front: (!before && !after) ? true : false,
+ sortby: sortby,
+ past: past,
+ user_preferences: req.cookies
+ })
+ }
})()
}
})
diff --git a/views/about.pug b/views/about.pug
index 981c4e9..027cfe4 100644
--- a/views/about.pug
+++ b/views/about.pug
@@ -24,4 +24,4 @@ html
.bottom
a(href="https://en.wikipedia.org/wiki/Piratbyr%C3%A5n#Kopimi", target="_blank")
img(src="kopimi.gif")
- p.version v.0.0.3
+ p.version v.0.0.5