Skip to content
This repository was archived by the owner on Oct 5, 2022. It is now read-only.

Commit 6db1db7

Browse files
author
Maxime Vaillancourt
committed
refactoring + added rss/atom support
1 parent 3c97c07 commit 6db1db7

File tree

16 files changed

+462
-343
lines changed

16 files changed

+462
-343
lines changed

app.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/*---------------------------------------------------------------------
2+
Dependencies
3+
---------------------------------------------------------------------*/
14
var express = require('express');
25
var path = require('path');
36
var favicon = require('serve-favicon');
@@ -9,11 +12,10 @@ var flash = require("express-flash");
912
var Promise = require("bluebird");
1013
var compression = require('compression');
1114

12-
var index = require('./routes/index');
13-
var users = require('./routes/users');
14-
15+
/*---------------------------------------------------------------------
16+
App Setup
17+
---------------------------------------------------------------------*/
1518
var app = express();
16-
app.use(compression())
1719

1820
var sessionStore = new session.MemoryStore;
1921
app.locals.moment = require('moment');
@@ -22,8 +24,11 @@ app.locals.moment = require('moment');
2224
app.set('views', path.join(__dirname, 'views'));
2325
app.set('view engine', 'pug');
2426

25-
// uncomment after placing your favicon in /public
27+
/*---------------------------------------------------------------------
28+
Middleware
29+
---------------------------------------------------------------------*/
2630
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
31+
app.use(compression())
2732
app.use(cookieParser('secret'));
2833
app.use(session({
2934
cookie: { maxAge: 60000 },
@@ -39,9 +44,15 @@ app.use(cookieParser('secret'));
3944
app.use(express.static(path.join(__dirname, 'public')));
4045
app.use(flash());
4146

42-
app.use('/', index);
43-
app.use('/users', users);
47+
/*---------------------------------------------------------------------
48+
Routes
49+
---------------------------------------------------------------------*/
50+
app.use('/', require('./routes/index'));
51+
app.use('/feed', require('./routes/feed'));
4452

53+
/*---------------------------------------------------------------------
54+
Error handlers
55+
---------------------------------------------------------------------*/
4556
// catch 404 and forward to error handler
4657
app.use(function(req, res, next) {
4758
var err = new Error('Not Found');
@@ -60,4 +71,7 @@ app.use(function(err, req, res, next) {
6071
res.render('error');
6172
});
6273

74+
/*---------------------------------------------------------------------
75+
Exports
76+
---------------------------------------------------------------------*/
6377
module.exports = app;

helpers/utils.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module.exports.shuffleArray = function(array) {
2+
var currentIndex = array.length, temporaryValue, randomIndex;
3+
4+
// While there remain elements to shuffle...
5+
while (0 !== currentIndex) {
6+
7+
// Pick a remaining element...
8+
randomIndex = Math.floor(Math.random() * currentIndex);
9+
currentIndex -= 1;
10+
11+
// And swap it with the current element.
12+
temporaryValue = array[currentIndex];
13+
array[currentIndex] = array[randomIndex];
14+
array[randomIndex] = temporaryValue;
15+
}
16+
17+
return array;
18+
}
19+
20+
module.exports.mimeTypes = [
21+
{ mimetype: "application/rss+xml", feedtype: "xml" },
22+
{ mimetype: "application/rdf+xml", feedtype: "xml" },
23+
{ mimetype: "application/atom+xml", feedtype: "xml" },
24+
{ mimetype: "application/xml", feedtype: "xml" },
25+
{ mimetype: "text/xml", feedtype: "xml" },
26+
{ mimetype: "application/json", feedtype: "json" },
27+
]
28+
29+
module.exports.showcasedFeedsUrls = [
30+
"https://jsonfeed.org/feed.json",
31+
"https://daringfireball.net/feeds/json",
32+
"http://inessential.com/feed.json",
33+
"http://phish.net/feed.json",
34+
"https://www.stuartbreckenridge.com/feed.json",
35+
"https://applefocus.com/feed.json",
36+
"http://www.downes.ca/news/OLDaily.json",
37+
"https://www.raymondcamden.com/jsonfeed/index.json",
38+
"https://longstride.net/feed.json",
39+
"https://ryanmo.co/feed.json",
40+
"http://troz.net/feed.json",
41+
"https://www.jordanmerrick.com/feed.json",
42+
"http://gaddgict.com/feed/json",
43+
"https://colterreed.com/feed/json",
44+
]

public/css/bootswatch.min.css

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/css/font-awesome-4.7.0.min.css

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/css/styles.css

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
body{
2+
border-top:5px solid #18bc9c;
3+
padding-top:1em
4+
}
5+
6+
img {
7+
border-radius: 5px;
8+
max-width:100%;
9+
}
10+
11+
footer{
12+
padding:20px 0;
13+
}
14+
15+
.panel-showcase{
16+
color: #2c3e50;
17+
}
18+
19+
.panel-featured-here{
20+
background: #18bc9c !important;
21+
color: white;
22+
}
23+
24+
.alert a{
25+
color: white;
26+
text-decoration:underline;
27+
}
28+
29+
/*--------------------------------------------------------------
30+
Taken from https://www.bootply.com/BM2lKItrFw
31+
--------------------------------------------------------------*/
32+
*, *:before, *:after {
33+
box-sizing: border-box !important;
34+
}
35+
36+
.row-showcase {
37+
-moz-column-width: 18em;
38+
-webkit-column-width: 18em;
39+
-moz-column-gap: 1em;
40+
-webkit-column-gap:1em;
41+
}
42+
43+
.item-showcase {
44+
display: inline-block;
45+
padding: .25rem;
46+
width: 100%;
47+
}
48+
/*------------------------------------------------------------*/

public/js/bootstrap-3.3.7.min.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/js/jquery-3.2.1.min.js

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/stylesheets/styles.css

Lines changed: 0 additions & 34 deletions
This file was deleted.

routes/feed.js

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*---------------------------------------------------------------------
2+
Dependencies
3+
---------------------------------------------------------------------*/
4+
var express = require('express');
5+
var router = express.Router();
6+
var request = require("request");
7+
var utils = require("../helpers/utils")
8+
9+
/*---------------------------------------------------------------------
10+
Feed Display GET
11+
---------------------------------------------------------------------*/
12+
router.get('/',
13+
14+
function ajaxRequest(req, res, next) {
15+
16+
// user has typed in something
17+
if(req.query.url){
18+
request(req.query.url.trim(), function(err, requestResponse, rawData) {
19+
20+
// we have a response!
21+
if(requestResponse && requestResponse.headers){
22+
23+
var feedType = null
24+
25+
// check what mimetype we have
26+
utils.mimeTypes.forEach(function(m){
27+
if (requestResponse.headers["content-type"].indexOf(m.mimetype) > -1){
28+
feedType = m.feedtype;
29+
}
30+
})
31+
32+
33+
if(feedType == "json"){
34+
35+
var parsedJson;
36+
37+
res.locals.feedType = "json"
38+
39+
try {
40+
parsedJson = JSON.parse(rawData);
41+
} catch(e) {
42+
req.flash("error", "Error while parsing the JSON feed.")
43+
return res.redirect("/");
44+
}
45+
var parsedJson = JSON.parse(rawData);
46+
if(parsedJson.hasOwnProperty('err')){
47+
req.flash("error", "There was an error while preparing the feed to be displayed.")
48+
return res.redirect("/");
49+
}
50+
else{
51+
// feed is ready to be displayed!
52+
res.locals.data = parsedJson;
53+
return next();
54+
}
55+
}
56+
57+
else if(feedType == "xml"){
58+
59+
res.locals.feedType = "xml"
60+
61+
// we need convert the rss/atom feed to json first
62+
request("https://feed2json.org/convert?url="+encodeURIComponent(req.query.url.trim()), function(err, converterRequestResponse, converterRawData) {
63+
64+
// we have a response from feed2json!
65+
if(converterRequestResponse && converterRequestResponse.headers){
66+
67+
var convertedFeedType = null
68+
69+
// check what mimetype we have
70+
utils.mimeTypes.forEach(function(m){
71+
if (converterRequestResponse.headers["content-type"].indexOf(m.mimetype) > -1){
72+
convertedFeedType = m.feedtype;
73+
}
74+
})
75+
76+
if(convertedFeedType == "json"){
77+
var parsedConvertedJson;
78+
79+
try {
80+
parsedConvertedJson = JSON.parse(converterRawData);
81+
} catch(e) {
82+
req.flash("error", "Error while parsing the converted feed.")
83+
return res.redirect("/");
84+
}
85+
86+
if(parsedConvertedJson.hasOwnProperty('err')){
87+
req.flash("error", "There was an error while preparing the feed to be displayed.")
88+
return res.redirect("/");
89+
}
90+
else{
91+
// feed is ready to be displayed!
92+
res.locals.data = parsedConvertedJson;
93+
return next();
94+
}
95+
}
96+
else{
97+
// converted data is not json
98+
req.flash("error", "Error while converting the feed to JSON. Please try again.")
99+
return res.redirect("/");
100+
}
101+
}
102+
else{
103+
// bad response from converter
104+
req.flash("error", "Invalid response from the feed converter. Please try again.")
105+
return res.redirect("/");
106+
}
107+
});
108+
}
109+
else{
110+
// not json, nor xml or atom
111+
req.flash("error", "Unexpected MIME type. Please make sure you are entering a JSON, RSS, or Atom feed URL.")
112+
return res.redirect("/");
113+
}
114+
}
115+
116+
else{
117+
// we don't have a valid response
118+
req.flash("error", "Invalid response from this URL. Please try again.")
119+
return res.redirect("/");
120+
}
121+
});
122+
}
123+
124+
// no user input
125+
else{
126+
return res.redirect("/");
127+
}
128+
},
129+
130+
function render(req, res, next) {
131+
return res.render("feed")
132+
}
133+
134+
);
135+
136+
/*---------------------------------------------------------------------
137+
Exports
138+
---------------------------------------------------------------------*/
139+
module.exports = router;

0 commit comments

Comments
 (0)