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,
|
||||
sidebar: 60 * 60 * 24 * 7, // 7 days
|
||||
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: {
|
||||
/**
|
||||
|
|
|
@ -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 tedditApiSubreddit = require('./inc/teddit_api/handleSubreddit.js')();
|
||||
let tedditApiUser = require('./inc/teddit_api/handleUser.js')();
|
||||
let processSubredditsExplore = require('./inc/processSubredditsExplore.js')();
|
||||
|
||||
app.get('/about', (req, res, next) => {
|
||||
return res.render('about', { user_preferences: req.cookies })
|
||||
|
@ -31,6 +32,141 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
|||
app.get('/privacy', (req, res, next) => {
|
||||
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) => {
|
||||
let subreddit = req.params.subreddit
|
||||
|
@ -47,11 +183,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
|||
subbed.push(subreddit)
|
||||
|
||||
res.cookie('subbed_subreddits', subbed, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true })
|
||||
|
||||
|
||||
if(!back)
|
||||
return res.redirect('/r/' + subreddit)
|
||||
else {
|
||||
back = back.replace(/,/g, '+')
|
||||
back = back.replace(/,/g, '+').replace(/§1/g, '&')
|
||||
return res.redirect(back)
|
||||
}
|
||||
})
|
||||
|
@ -105,7 +241,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
|||
if(!back)
|
||||
return res.redirect('/r/' + subreddit)
|
||||
else {
|
||||
back = back.replace(/,/g, '+')
|
||||
back = back.replace(/,/g, '+').replace(/§1/g, '&')
|
||||
return res.redirect(back)
|
||||
}
|
||||
})
|
||||
|
@ -577,7 +713,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
|||
})
|
||||
}
|
||||
}).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;
|
||||
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 {
|
||||
|
@ -564,17 +590,6 @@ footer a {
|
|||
float: left;
|
||||
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 {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
@ -1020,6 +1035,11 @@ a.sub-to-subreddit.gray {
|
|||
margin-left: 20px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
#search.explore {
|
||||
width: calc(100% - 60px);
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
#search form {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
@ -1431,5 +1451,15 @@ code {
|
|||
}
|
||||
a.sub-to-subreddit {
|
||||
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