add '/subreddits' feature for searching and exploring subreddits
This commit is contained in:
parent
9dea345a03
commit
3e01937247
|
@ -38,7 +38,11 @@ const config = {
|
||||||
searches: 600,
|
searches: 600,
|
||||||
sidebar: 60 * 60 * 24 * 7, // 7 days
|
sidebar: 60 * 60 * 24 * 7, // 7 days
|
||||||
shorts: 60 * 60 * 24 * 31,
|
shorts: 60 * 60 * 24 * 31,
|
||||||
wikis: 60* 60 * 24 * 7
|
wikis: 60* 60 * 24 * 7,
|
||||||
|
subreddits_explore: {
|
||||||
|
front: 60 * 60 * 24 * 1,
|
||||||
|
new_page: 60
|
||||||
|
},
|
||||||
},
|
},
|
||||||
convert_urls: {
|
convert_urls: {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
module.exports = function() {
|
||||||
|
const config = require('../config');
|
||||||
|
this.processJsonSubredditsExplore = (json, from, subreddit_front, user_preferences) => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
(async () => {
|
||||||
|
if(from === 'redis') {
|
||||||
|
json = JSON.parse(json)
|
||||||
|
}
|
||||||
|
if(json.error) {
|
||||||
|
resolve({ error: true, error_data: json })
|
||||||
|
} else {
|
||||||
|
let before = json.data.before
|
||||||
|
let after = json.data.after
|
||||||
|
|
||||||
|
let ret = {
|
||||||
|
info: {
|
||||||
|
before: before,
|
||||||
|
after: after
|
||||||
|
},
|
||||||
|
links: []
|
||||||
|
}
|
||||||
|
|
||||||
|
let children_len = json.data.children.length
|
||||||
|
|
||||||
|
for(var i = 0; i < children_len; i++) {
|
||||||
|
let data = json.data.children[i].data
|
||||||
|
|
||||||
|
if(data.over_18)
|
||||||
|
if((config.nsfw_enabled === false && user_preferences.nsfw_enabled != 'true') || user_preferences.nsfw_enabled === 'false')
|
||||||
|
continue
|
||||||
|
|
||||||
|
let obj = {
|
||||||
|
created: data.created_utc,
|
||||||
|
id: data.id,
|
||||||
|
over_18: data.over_18,
|
||||||
|
display_name: data.display_name,
|
||||||
|
display_name_prefixed: data.display_name_prefixed,
|
||||||
|
public_description: data.public_description,
|
||||||
|
url: data.url,
|
||||||
|
subscribers: data.subscribers,
|
||||||
|
over_18: data.over18,
|
||||||
|
title: data.title,
|
||||||
|
subreddit_front: subreddit_front,
|
||||||
|
}
|
||||||
|
ret.links.push(obj)
|
||||||
|
}
|
||||||
|
resolve(ret)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
144
routes.js
144
routes.js
|
@ -10,6 +10,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||||
let processAbout = require('./inc/processSubredditAbout.js')();
|
let processAbout = require('./inc/processSubredditAbout.js')();
|
||||||
let tedditApiSubreddit = require('./inc/teddit_api/handleSubreddit.js')();
|
let tedditApiSubreddit = require('./inc/teddit_api/handleSubreddit.js')();
|
||||||
let tedditApiUser = require('./inc/teddit_api/handleUser.js')();
|
let tedditApiUser = require('./inc/teddit_api/handleUser.js')();
|
||||||
|
let processSubredditsExplore = require('./inc/processSubredditsExplore.js')();
|
||||||
|
|
||||||
app.get('/about', (req, res, next) => {
|
app.get('/about', (req, res, next) => {
|
||||||
return res.render('about', { user_preferences: req.cookies })
|
return res.render('about', { user_preferences: req.cookies })
|
||||||
|
@ -31,6 +32,141 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||||
app.get('/privacy', (req, res, next) => {
|
app.get('/privacy', (req, res, next) => {
|
||||||
return res.render('privacypolicy', { user_preferences: req.cookies })
|
return res.render('privacypolicy', { user_preferences: req.cookies })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.get('/subreddits/:sort?', (req, res, next) => {
|
||||||
|
let q = req.query.q
|
||||||
|
let nsfw = req.query.nsfw
|
||||||
|
let after = req.query.after
|
||||||
|
let before = req.query.before
|
||||||
|
let sortby = req.params.sort
|
||||||
|
let searching = false
|
||||||
|
|
||||||
|
if(!after) {
|
||||||
|
after = ''
|
||||||
|
}
|
||||||
|
if(!before) {
|
||||||
|
before = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
let d = `&after=${after}`
|
||||||
|
if(before) {
|
||||||
|
d = `&before=${before}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nsfw !== 'on') {
|
||||||
|
nsfw = 'off'
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sortby) {
|
||||||
|
sortby = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
let key = `subreddits:sort:${sortby}${d}`
|
||||||
|
|
||||||
|
if(sortby === 'search') {
|
||||||
|
if(typeof(q) == 'undefined' || q == '')
|
||||||
|
return res.redirect('/subreddits')
|
||||||
|
|
||||||
|
key = `subreddits:search:q:${q}:nsfw:${nsfw}${d}`
|
||||||
|
searching = true
|
||||||
|
}
|
||||||
|
|
||||||
|
redis.get(key, (error, json) => {
|
||||||
|
if(error) {
|
||||||
|
console.error(`Error getting the subreddits key from redis.`, error)
|
||||||
|
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||||
|
}
|
||||||
|
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
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return res.render('subreddits_explore', {
|
||||||
|
json: null,
|
||||||
|
error: true,
|
||||||
|
data: processed_json,
|
||||||
|
user_preferences: req.cookies
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
} 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}`
|
||||||
|
else
|
||||||
|
url = `https://oauth.reddit.com/subreddits/search?api_type=json&q=${q}&include_over_18=${nsfw}${d}`
|
||||||
|
} else {
|
||||||
|
if(!searching)
|
||||||
|
url = `https://reddit.com/subreddits/${sortby}.json?api_type=json&count=25&g=GLOBAL&t=${d}`
|
||||||
|
else
|
||||||
|
url = `https://reddit.com/subreddits/search.json?api_type=json&q=${q}&include_over_18=${nsfw}${d}`
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(encodeURI(url), redditApiGETHeaders())
|
||||||
|
.then(result => {
|
||||||
|
if(result.status === 200) {
|
||||||
|
result.json()
|
||||||
|
.then(json => {
|
||||||
|
let ex = config.setexs.subreddits_explore.front
|
||||||
|
if(sortby === 'new')
|
||||||
|
ex = config.setexs.subreddits_explore.new_page
|
||||||
|
redis.setex(key, ex, JSON.stringify(json), (error) => {
|
||||||
|
if(error) {
|
||||||
|
console.error(`Error setting the subreddits key to redis.`, error)
|
||||||
|
return res.render('subreddits_explore', { json: null, user_preferences: req.cookies })
|
||||||
|
} 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
|
||||||
|
})
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if(result.status === 404) {
|
||||||
|
console.log('404 – Subreddits 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('index', {
|
||||||
|
json: null,
|
||||||
|
http_status_code: result.status,
|
||||||
|
user_preferences: req.cookies
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error(`Error fetching the JSON file from reddit.com/subreddits.`, error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
app.get('/subscribe/:subreddit', (req, res, next) => {
|
app.get('/subscribe/:subreddit', (req, res, next) => {
|
||||||
let subreddit = req.params.subreddit
|
let subreddit = req.params.subreddit
|
||||||
|
@ -47,11 +183,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||||
subbed.push(subreddit)
|
subbed.push(subreddit)
|
||||||
|
|
||||||
res.cookie('subbed_subreddits', subbed, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true })
|
res.cookie('subbed_subreddits', subbed, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true })
|
||||||
|
|
||||||
if(!back)
|
if(!back)
|
||||||
return res.redirect('/r/' + subreddit)
|
return res.redirect('/r/' + subreddit)
|
||||||
else {
|
else {
|
||||||
back = back.replace(/,/g, '+')
|
back = back.replace(/,/g, '+').replace(/§1/g, '&')
|
||||||
return res.redirect(back)
|
return res.redirect(back)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -105,7 +241,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||||
if(!back)
|
if(!back)
|
||||||
return res.redirect('/r/' + subreddit)
|
return res.redirect('/r/' + subreddit)
|
||||||
else {
|
else {
|
||||||
back = back.replace(/,/g, '+')
|
back = back.replace(/,/g, '+').replace(/§1/g, '&')
|
||||||
return res.redirect(back)
|
return res.redirect(back)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -577,7 +713,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(`Error fetching the JSON file from reddit.com/r/${subreddit}.`, error)
|
console.error(`Error fetching the JSON file from reddit.com/r/random.`, error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -555,6 +555,32 @@ footer a {
|
||||||
border-left: 1px solid #dcdcdc;
|
border-left: 1px solid #dcdcdc;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
.infobar {
|
||||||
|
background-color: #f6e69f;
|
||||||
|
margin: 5px 305px 5px 11px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
float: left;
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
.infobar.blue {
|
||||||
|
background: #eff8ff;
|
||||||
|
border: 1px solid #93abc2;
|
||||||
|
}
|
||||||
|
.infobar.explore {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.explore#links .link {
|
||||||
|
padding-left: 10%;
|
||||||
|
}
|
||||||
|
.explore#links .link .sub-button {
|
||||||
|
float: left;
|
||||||
|
margin: 7px 0px;
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
.explore#links .link .content {
|
||||||
|
float: left;
|
||||||
|
width: calc(100% - 120px);
|
||||||
|
}
|
||||||
|
|
||||||
/* POST */
|
/* POST */
|
||||||
#post {
|
#post {
|
||||||
|
@ -564,17 +590,6 @@ footer a {
|
||||||
float: left;
|
float: left;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
#post .infobar {
|
|
||||||
background-color: #f6e69f;
|
|
||||||
margin: 5px 305px 5px 11px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
float: left;
|
|
||||||
width: calc(100% - 50px);
|
|
||||||
}
|
|
||||||
#post .infobar.blue {
|
|
||||||
background: #eff8ff;
|
|
||||||
border: 1px solid #93abc2;
|
|
||||||
}
|
|
||||||
#post header {
|
#post header {
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
|
@ -1020,6 +1035,11 @@ a.sub-to-subreddit.gray {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
#search.explore {
|
||||||
|
width: calc(100% - 60px);
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
#search form {
|
#search form {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
@ -1431,5 +1451,15 @@ code {
|
||||||
}
|
}
|
||||||
a.sub-to-subreddit {
|
a.sub-to-subreddit {
|
||||||
padding: 8px 10px 8px 10px;
|
padding: 8px 10px 8px 10px;
|
||||||
|
}
|
||||||
|
.explore#links .link {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
.explore#links .link .sub-button {
|
||||||
|
margin: 7px 0px;
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
.explore#links .link .entry {
|
||||||
|
width: calc(100% - 20px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
doctype html
|
||||||
|
html
|
||||||
|
head
|
||||||
|
title subreddits - explore
|
||||||
|
include includes/head.pug
|
||||||
|
body(class=""+ user_preferences.theme +"")
|
||||||
|
include includes/topbar.pug
|
||||||
|
if json === null
|
||||||
|
h1 Error occured
|
||||||
|
p Error: #{JSON.stringify(json.error_data)}
|
||||||
|
else
|
||||||
|
header
|
||||||
|
a(href="/", class="main")
|
||||||
|
h1 teddit
|
||||||
|
.bottom
|
||||||
|
a(href="/subreddits", class="subreddit")
|
||||||
|
h2 subreddits - explore
|
||||||
|
ul.tabmenu
|
||||||
|
li(class=!sortby || sortby == 'hot' ? 'active' : '')
|
||||||
|
a(href="/subreddits") popular
|
||||||
|
li(class=sortby === 'new' ? 'active' : '')
|
||||||
|
a(href="/subreddits/new") new
|
||||||
|
#search.explore
|
||||||
|
form(action="/subreddits/search", method="GET")
|
||||||
|
div
|
||||||
|
label(for="q") search subreddits
|
||||||
|
input(type="text", name="q", id="q", value="" + (q ? q : '') + "", placeholder="search")
|
||||||
|
div
|
||||||
|
label(for="nsfw") include NSFW results
|
||||||
|
if nsfw === 'on'
|
||||||
|
input(type="checkbox", name="nsfw", id="nsfw", checked="checked")
|
||||||
|
else
|
||||||
|
input(type="checkbox", name="nsfw", id="nsfw")
|
||||||
|
input(type="submit", value="search")
|
||||||
|
#links.sr.explore
|
||||||
|
if json.links.length === 0
|
||||||
|
p nothing here
|
||||||
|
else
|
||||||
|
.infobar.explore
|
||||||
|
p click the <code>subscribe</code> or unsubscribe buttons to choose which subreddits appear on the home feed.
|
||||||
|
each link in json.links
|
||||||
|
.link
|
||||||
|
.entry
|
||||||
|
-
|
||||||
|
let subbed_to_this_subreddit = false
|
||||||
|
let subbed = []
|
||||||
|
if(user_preferences.subbed_subreddits && Array.isArray(user_preferences.subbed_subreddits))
|
||||||
|
subbed = user_preferences.subbed_subreddits
|
||||||
|
for(let i = 0; i < subbed.length; i++) {
|
||||||
|
if(subbed[i].toLowerCase() === link.display_name.toLowerCase())
|
||||||
|
subbed_to_this_subreddit = true
|
||||||
|
}
|
||||||
|
.sub-button
|
||||||
|
if subbed_to_this_subreddit
|
||||||
|
if !searching
|
||||||
|
a(href="/unsubscribe/" + link.display_name + "?b=/subreddits/" + sortby + "?after=" + after + "§1before=" + before + "", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe
|
||||||
|
else
|
||||||
|
a(href="/unsubscribe/" + link.display_name + "?b=/subreddits/search?q=" + q + "§1nsfw=" + nsfw + "§1after=" + after + "§1before=" + before + "", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe
|
||||||
|
else
|
||||||
|
if !searching
|
||||||
|
a(href="/subscribe/" + link.display_name + "?b=/subreddits/" + sortby + "?after=" + after + "§1before=" + before + "", class="sub-to-subreddit", title="subscriptions are saved in your browser's cookies") subscribe
|
||||||
|
else
|
||||||
|
a(href="/subscribe/" + link.display_name + "?b=/subreddits/search?q=" + q + "§1nsfw=" + nsfw + "§1after=" + after + "§1before=" + before + "", class="sub-to-subreddit", title="subscriptions are saved in your browser's cookies") subscribe
|
||||||
|
.content
|
||||||
|
.title
|
||||||
|
a(href="" + link.url + "", rel="noopener noreferrer")
|
||||||
|
h2 #{link.display_name_prefixed}: #{cleanTitle(link.title)}
|
||||||
|
.description
|
||||||
|
p #{cleanTitle(link.public_description)}
|
||||||
|
.meta
|
||||||
|
p.subscribers #{kFormatter(link.subscribers)} subscribers,
|
||||||
|
p.submitted created
|
||||||
|
span(title="" + toUTCString(link.created) + "") #{timeDifference(link.created)}
|
||||||
|
.links
|
||||||
|
if link.over_18
|
||||||
|
span.tag.nsfw NSFW
|
||||||
|
if json.info.before || json.info.after
|
||||||
|
.view-more-links
|
||||||
|
if json.info.before && !subreddits_front
|
||||||
|
a(href="/subreddits/" + sortby + "?before=" + json.info.before + "&nsfw=" + nsfw + "&q=" + (q ? q : '') + "") ‹ prev
|
||||||
|
if json.info.after
|
||||||
|
a(href="/subreddits/" + sortby + "?after=" + json.info.after + "&nsfw=" + nsfw + "&q=" + (q ? q : '') + "") next ›
|
||||||
|
#sidebar
|
||||||
|
.content
|
||||||
|
if user_preferences.subbed_subreddits && Array.isArray(user_preferences.subbed_subreddits)
|
||||||
|
p your subscribed subreddits
|
||||||
|
ul.subreddit-listing
|
||||||
|
each subreddit in user_preferences.subbed_subreddits
|
||||||
|
li
|
||||||
|
if !searching
|
||||||
|
a(href="/unsubscribe/" + subreddit + "?b=/subreddits/" + sortby + "?after=" + after + "§1before=" + before + "", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe
|
||||||
|
a(href="/r/" + subreddit) #{subreddit}
|
||||||
|
else
|
||||||
|
a(href="/unsubscribe/" + subreddit + "?b=/subreddits/search?q=" + q + "§1nsfw=" + nsfw + "§1after=" + after + "§1before=" + before + "", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe
|
||||||
|
a(href="/r/" + subreddit) #{subreddit}
|
||||||
|
include includes/footer.pug
|
Loading…
Reference in New Issue