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

Commit bbcf5df

Browse files
author
Maxime Vaillancourt
committed
initial commit
0 parents  commit bbcf5df

File tree

10 files changed

+426
-0
lines changed

10 files changed

+426
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/node_modules
2+
npm-debug.log
3+
.DS_Store
4+
/*.env

app.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
var express = require('express');
2+
var path = require('path');
3+
var favicon = require('serve-favicon');
4+
var logger = require('morgan');
5+
var session = require('express-session');
6+
var cookieParser = require('cookie-parser');
7+
var bodyParser = require('body-parser');
8+
var flash = require("express-flash");
9+
var Promise = require("bluebird")
10+
11+
var index = require('./routes/index');
12+
var users = require('./routes/users');
13+
14+
var app = express();
15+
var sessionStore = new session.MemoryStore;
16+
app.locals.moment = require('moment');
17+
18+
// view engine setup
19+
app.set('views', path.join(__dirname, 'views'));
20+
app.set('view engine', 'pug');
21+
22+
// uncomment after placing your favicon in /public
23+
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
24+
app.use(cookieParser('secret'));
25+
app.use(session({
26+
cookie: { maxAge: 60000 },
27+
store: sessionStore,
28+
saveUninitialized: true,
29+
resave: 'true',
30+
secret: 'secret'
31+
}));
32+
app.use(logger('dev'));
33+
app.use(bodyParser.json());
34+
app.use(bodyParser.urlencoded({ extended: false }));
35+
app.use(cookieParser('secret'));
36+
app.use(express.static(path.join(__dirname, 'public')));
37+
app.use(flash());
38+
39+
app.use('/', index);
40+
app.use('/users', users);
41+
42+
// catch 404 and forward to error handler
43+
app.use(function(req, res, next) {
44+
var err = new Error('Not Found');
45+
err.status = 404;
46+
next(err);
47+
});
48+
49+
// error handler
50+
app.use(function(err, req, res, next) {
51+
// set locals, only providing error in development
52+
res.locals.message = err.message;
53+
res.locals.error = req.app.get('env') === 'development' ? err : {};
54+
55+
// render the error page
56+
res.status(err.status || 500);
57+
res.render('error');
58+
});
59+
60+
module.exports = app;

bin/www

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Module dependencies.
5+
*/
6+
7+
var app = require('../app');
8+
var debug = require('debug')('json-feed-reader:server');
9+
var http = require('http');
10+
11+
/**
12+
* Get port from environment and store in Express.
13+
*/
14+
15+
var port = normalizePort(process.env.PORT || '3000');
16+
app.set('port', port);
17+
18+
/**
19+
* Create HTTP server.
20+
*/
21+
22+
var server = http.createServer(app);
23+
24+
/**
25+
* Listen on provided port, on all network interfaces.
26+
*/
27+
28+
server.listen(port);
29+
server.on('error', onError);
30+
server.on('listening', onListening);
31+
32+
/**
33+
* Normalize a port into a number, string, or false.
34+
*/
35+
36+
function normalizePort(val) {
37+
var port = parseInt(val, 10);
38+
39+
if (isNaN(port)) {
40+
// named pipe
41+
return val;
42+
}
43+
44+
if (port >= 0) {
45+
// port number
46+
return port;
47+
}
48+
49+
return false;
50+
}
51+
52+
/**
53+
* Event listener for HTTP server "error" event.
54+
*/
55+
56+
function onError(error) {
57+
if (error.syscall !== 'listen') {
58+
throw error;
59+
}
60+
61+
var bind = typeof port === 'string'
62+
? 'Pipe ' + port
63+
: 'Port ' + port;
64+
65+
// handle specific listen errors with friendly messages
66+
switch (error.code) {
67+
case 'EACCES':
68+
console.error(bind + ' requires elevated privileges');
69+
process.exit(1);
70+
break;
71+
case 'EADDRINUSE':
72+
console.error(bind + ' is already in use');
73+
process.exit(1);
74+
break;
75+
default:
76+
throw error;
77+
}
78+
}
79+
80+
/**
81+
* Event listener for HTTP server "listening" event.
82+
*/
83+
84+
function onListening() {
85+
var addr = server.address();
86+
var bind = typeof addr === 'string'
87+
? 'pipe ' + addr
88+
: 'port ' + addr.port;
89+
debug('Listening on ' + bind);
90+
}

package.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "json-feed-reader",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"start": "nodemon ./bin/www"
7+
},
8+
"dependencies": {
9+
"async": "^2.4.0",
10+
"body-parser": "~1.16.0",
11+
"cookie-parser": "~1.4.3",
12+
"debug": "~2.6.0",
13+
"express": "~4.14.1",
14+
"express-flash": "0.0.2",
15+
"express-session": "^1.15.2",
16+
"moment": "^2.18.1",
17+
"morgan": "~1.7.0",
18+
"pug": "~2.0.0-beta10",
19+
"request": "^2.81.0",
20+
"serve-favicon": "~2.3.2"
21+
},
22+
"engines": {
23+
"node": "6.2.0"
24+
}
25+
}

public/stylesheets/styles.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
img {
2+
border-radius: 5px;
3+
}

routes/index.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
var express = require('express');
2+
var router = express.Router();
3+
var request = require("request");
4+
var async = require("async")
5+
6+
/* GET home page. */
7+
router.get('/',
8+
9+
function ajaxRequest(req, res, next) {
10+
11+
req.validFeed = false;
12+
13+
if(req.query.feed_url){
14+
request(req.query.feed_url, function(err, requestResponse, rawData) {
15+
16+
if(requestResponse && requestResponse.headers && requestResponse.headers["content-type"].indexOf("application/json") > -1){
17+
var data = JSON.parse(rawData);
18+
res.locals.data = data;
19+
req.validFeed = true
20+
}
21+
else{
22+
req.flash("error", "Invalid JSON feed.")
23+
}
24+
});
25+
}
26+
27+
if(!req.validFeed){
28+
var showcaseFeedUrls = [
29+
//"https://jsonfeed.org/feed.json",
30+
"https://daringfireball.net/feeds/json",
31+
"http://inessential.com/feed.json"
32+
]
33+
34+
res.locals.showcaseFeeds = []
35+
36+
var calls = [];
37+
38+
showcaseFeedUrls.forEach(function(url){
39+
calls.push(function(callback) {
40+
request(url, function(err, requestResponse, rawData) {
41+
42+
if(requestResponse && requestResponse.headers && requestResponse.headers["content-type"].indexOf("application/json") > -1){
43+
var data = JSON.parse(rawData);
44+
res.locals.showcaseFeeds.push(data);
45+
callback();
46+
}
47+
else{
48+
callback(err)
49+
}
50+
51+
});
52+
}
53+
)});
54+
55+
async.parallel(calls, function(err, result) {
56+
if(err){
57+
req.flash("error", "Invalid JSON feed.")
58+
}
59+
return next();
60+
});
61+
}
62+
},
63+
64+
function render(req, res, next) {
65+
return res.render("index")
66+
}
67+
68+
);
69+
70+
module.exports = router;

routes/users.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var express = require('express');
2+
var router = express.Router();
3+
4+
/* GET users listing. */
5+
router.get('/', function(req, res, next) {
6+
res.send('respond with a resource');
7+
});
8+
9+
module.exports = router;

views/error.pug

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extends layout
2+
3+
block content
4+
h1= message
5+
h2= error.status
6+
pre #{error.stack}

views/index.pug

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
extends layout
2+
3+
block content
4+
if data
5+
.row
6+
.col-sm-3
7+
a(href=data.home_page_url)
8+
img(style="width:60px;" src=data.favicon)
9+
hr
10+
p
11+
a(href=data.home_page_url)
12+
b=data.title
13+
p= data.description
14+
p
15+
em
16+
| A feed by
17+
= data.author.name
18+
hr
19+
.col-sm-9
20+
if data.items
21+
for i in data.items
22+
h1(style="margin-top:0;")= i.title
23+
p
24+
| Posted on
25+
= moment(i.createTime).format("YYYY-MM-DD")
26+
p!= i.content_html
27+
hr
28+
else
29+
h1(style="margin-top:0;") Welcome to JSON Feed Viewer!
30+
p.lead Browse through the showcased JSON feeds below, or type in a JSON feed URL above.
31+
hr
32+
if showcaseFeeds
33+
.row
34+
for showcaseFeed in showcaseFeeds
35+
.col-sm-6.col-md-4.col-lg-3
36+
div.panel.panel-default
37+
.panel-body
38+
a(href="/?feed_url="+encodeURIComponent(showcaseFeed.feed_url))
39+
img(style="max-width:60px;" src=showcaseFeed.favicon)
40+
h3
41+
a(href="/?feed_url="+encodeURIComponent(showcaseFeed.feed_url))
42+
b=showcaseFeed.title
43+
p= showcaseFeed.description
44+
if showcaseFeed.author && showcaseFeed.author.name
45+
p
46+
em
47+
| A feed by
48+
= showcaseFeed.author.name
49+
a(href="/?feed_url="+encodeURIComponent(showcaseFeed.feed_url))
50+
.btn.btn-success.btn-sm Read feed

0 commit comments

Comments
 (0)