Skip to content
This repository was archived by the owner on Feb 13, 2018. It is now read-only.

Commit a9ee861

Browse files
add morgan, travis, tests, eslint
1 parent 91150d0 commit a9ee861

16 files changed

+250
-136
lines changed

.cfignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
node_modules
2+
.env
3+
coverage
24
uploads/*
35
!uploads/README.md

.eslintignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
coverage
2+
public/js/vendors
3+
public/js/components

.eslintrc

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"rules": {
3+
"no-console": 0,
4+
"func-names": 0,
5+
"vars-on-top": 0,
6+
"no-else-return": 0,
7+
"consistent-return": 0,
8+
"no-process-exit": 0
9+
},
10+
"globals": {
11+
"casper": false,
12+
"describe": true,
13+
"it": true
14+
},
15+
"env": {
16+
"node": true,
17+
"jquery": true,
18+
"browser": true
19+
},
20+
"extends": "eslint-config-airbnb-es5",
21+
}

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
node_modules
22
uploads/*
33
!uploads/README.md
4-
VCAP_SERVICES.json
5-
run.sh
4+
coverage
5+
.env

.travis.yml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
language: node_js
2+
sudo: true
3+
node_js: stable
4+
script:
5+
- npm run lint
6+
- npm test
7+
env:
8+
global:
9+
- CF_APP=document-conversion-demo
10+
- CF_API=https://api.ng.bluemix.net
11+
- CF_ORGANIZATION=WatsonPlatformServices
12+
- CF_SPACE=demos
13+
- secure: "1ArUhDyjOH/g7MdGNRCDrDintTMPk1bihDB7ZjTv9p+nxQS090r8VtnkeQgo+yzaK8HHLiG14LFiaWK6eIVf6HnlgyeX3Hh7KsF/rnb0w7TPbPvYpolmDHyLB7FdWtLVVTZPVUpxkiJID6PEh/ENSnC1GWDGpIn9LlyElmVt5sMZAXqs77XJNT0ogxHz1OjZB7UqWwsEPrNmdPEPGkRloxcDdM3m19VCmwL/WoI1a1T9r48L7p8IeM5bQ+olIWnNzoboOw2O+gEUzzHeE8ufXp9eWSju6fO8JCPkNLsGMpVwR8aIoFvOcZPE5W7UfzAeQkYwuayDndqg+lFZd32+tFMr8e6OT590B1fI8Ut9F4cRkGG5ivV16/SJJKrWRp0vRiGZ/N7yCbW+YE2OcsxquXDt5VqRPqW+nAjMCw7ADxq5C3zBMxQK9ST1p0pTVJLLrIq0QUjfYhTEjYufeWaxLXgVdyXE6QLm1Z2REjXLBzUs8Wc1AkJbbhfJ03RJvj39A3dlNgy8F5UbC3AVAQ817xaRPcho4LakfDulTvUooIL0j5ROh81Q/d/DDlnrs4ymlsGqNmJ7ZfMxvtXDesFyy+ZlqmxxRTA8NOpzBMSHP4GZ9oq+HMudPyVVaZexSewouBXj6bOG0uNG8iWa8YCKDnlxiNAmCEEodcLlb+XEhVQ="
14+
- secure: "bFhB3yakclo4ebxm63JN2BBAptN/UI/OrIBMqeK0a6AufHekbwJWxPjtt3yqruKnop1aLfkTi8MF8C8eQOp8NZ8oVRBzjGmv3h+cTFD9cgcig7Ut0660/TwABIJv8rRMTaOy3CxsRKAVFjMnFFx6YWbKu1+T+5EUfjIiXALzEVOfAr67Y1aR6ACApS9GlUJ2PDErdQVcm6JJ81h/TLLOmmnUoTGv/5O+OUUxzwwLeW+f5jMVgoIUfN9+z1SWzPkBdZhHT91KeihPl1GgBeonBWpCQMGbCuEbB97K0BrbExvZXjqcs4avJr/u2SIOP9NFcw69O59ey5LTBNhW3PcMDDtGFiQ5fjCjP9ldWSnBXYcVd3V9FatX/KnHOE8GtXzCVZt3W3cMnL0s/9wfhfkBuuZscKE8hbKbcMXe9Xtc1Qik8hefCmCWek3utFtW2mLklVo9Y3Ec+p7h7cq7k1LI6zCxHolAGXBu2fXoF6ErJKW1Y8WB4b6EJnpb+XUUgBmw8yZDVDdTKONYDg+EgEqUYB4kzSbvfgH6i8A9nb6rSY3qJUJoj+q5h/EBAxtFz4YEb6QVrT3gkE8acnYRgAKTukX5t5uwO1B7svBaWjZvxfaTBx0GSQmTMNXThgM62ExKEEfkZr5i9Dgu83pGXBEyGS9T+p6gHziE8bZfvU9SWK8="
15+
before_deploy: npm install -g cf-blue-green
16+
deploy:
17+
provider: script
18+
script:
19+
- cf-blue-green-travis
20+
on:
21+
branch: master
22+
repo: watson-developer-cloud/document-conversion-nodejs
23+
skip_cleanup: true
24+
notifications:
25+
email: false

app.js

+25-26
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616

1717
'use strict';
1818

19-
var express = require('express'),
20-
app = express(),
21-
watson = require('watson-developer-cloud'),
22-
fs = require('fs');
19+
var express = require('express');
20+
var app = express();
21+
var watson = require('watson-developer-cloud');
22+
var fs = require('fs');
23+
var path = require('path');
24+
2325
// Bootstrap application settings
2426
require('./config/express')(app);
2527

@@ -31,19 +33,17 @@ var credentials = {
3133
version: 'v1'
3234
};
3335

34-
var document_conversion = watson.document_conversion(credentials);
36+
var documentConversion = watson.document_conversion(credentials);
3537

3638
var types = {
3739
'ANSWER_UNITS': '.json',
3840
'NORMALIZED_HTML': '.html',
3941
'NORMALIZED_TEXT': '.txt'
4042
};
4143

42-
var samples = ['sampleHTML.html','samplePDF.pdf','sampleWORD.docx'];
43-
44-
45-
var uploadFolder = __dirname + '/uploads/';
46-
var sampleFolder = __dirname + '/public/data/';
44+
var samples = ['sampleHTML.html', 'samplePDF.pdf', 'sampleWORD.docx'];
45+
var uploadFolder = path.join(__dirname, 'uploads/');
46+
var sampleFolder = path.join(__dirname, 'public/data/');
4747

4848
/**
4949
* Returns the file path to a previously uploaded file or a sample file
@@ -54,28 +54,31 @@ function getFilePath(filename) {
5454
if (samples.indexOf(filename) !== -1) {
5555
return sampleFolder + filename;
5656
} else {
57-
if (fs.readdirSync(uploadFolder).indexOf(filename) !== -1)
57+
console.log(uploadFolder);
58+
if (fs.readdirSync(uploadFolder).indexOf(filename) !== -1) {
5859
return uploadFolder + filename;
59-
else
60-
return null;
60+
}
61+
return null;
6162
}
6263
}
6364

6465
app.get('/', function(req, res) {
65-
res.render('index', { ct: req._csrfToken });
66+
res.render('index');
6667
});
6768

6869
/*
6970
* Uploads a file
7071
*/
7172
app.post('/files', app.upload.single('document'), function(req, res, next) {
72-
if (!req.file && !req.file.path) {
73+
if (!req.file && !req.file.path) {
7374
return next({
7475
error: 'Missing required parameter: file',
7576
code: 400
7677
});
7778
}
78-
res.json({ id: req.file.filename });
79+
res.json({
80+
id: req.file.filename
81+
});
7982
});
8083

8184
/*
@@ -84,33 +87,31 @@ app.post('/files', app.upload.single('document'), function(req, res, next) {
8487
app.get('/api/convert', function(req, res, next) {
8588
var file = getFilePath(req.query.document_id);
8689
var params = {
87-
conversion_target : req.query.conversion_target,
90+
conversion_target: req.query.conversion_target,
8891
file: file ? fs.createReadStream(file) : null
8992
};
9093

91-
document_conversion.convert(params, function(err, data) {
94+
documentConversion.convert(params, function(err, data) {
9295
if (err) {
9396
return next(err);
9497
}
9598
var type = types[req.query.conversion_target];
9699
res.type(type);
97100
if (req.query.download) {
98-
res.setHeader('content-disposition','attachment; filename=output-' + Date.now() + '.' + type);
101+
res.setHeader('content-disposition', 'attachment; filename=output-' + Date.now() + '.' + type);
99102
}
100103
res.send(data);
101104
});
102105
});
103106

104-
105107
/*
106108
* Returns an uploaded file from the service
107109
*/
108110
app.get('/files/:id', function(req, res) {
109111
var file = getFilePath(req.params.id);
110-
fs.createReadStream(file)
111-
.on('response', function(response) {
112+
fs.createReadStream(file).on('response', function(response) {
112113
if (req.query.download) {
113-
response.headers['content-disposition'] = 'attachment; filename=' + req.params.id;
114+
response.headers['content-disposition'] = 'attachment; filename=' + req.params.id;
114115
}
115116
})
116117
.pipe(res);
@@ -119,6 +120,4 @@ app.get('/files/:id', function(req, res) {
119120
// error-handler settings
120121
require('./config/error-handler')(app);
121122

122-
var port = process.env.VCAP_APP_PORT || 3000;
123-
app.listen(port);
124-
console.log('listening at:', port);
123+
module.exports = app;

config/error-handler.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
/* eslint no-unused-vars: "off" */
1617

1718
'use strict';
1819

19-
module.exports = function (app) {
20-
20+
module.exports = function(app) {
2121
// catch 404 and forward to error handler
2222
app.use(function(req, res, next) {
2323
var err = new Error('Not Found');
@@ -32,10 +32,6 @@ module.exports = function (app) {
3232
code: err.code || 500,
3333
error: err.error || err.message
3434
};
35-
36-
console.log('error:', error);
37-
3835
res.status(error.code).json(error);
3936
});
40-
4137
};

config/express.js

+20-13
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,48 @@
1717
'use strict';
1818

1919
// Module dependencies
20-
var express = require('express'),
21-
bodyParser = require('body-parser'),
22-
multer = require('multer'),
23-
findRemoveSync = require('find-remove');
20+
var express = require('express');
21+
var bodyParser = require('body-parser');
22+
var multer = require('multer');
23+
var findRemoveSync = require('find-remove');
24+
var path = require('path');
25+
var morgan = require('morgan');
2426

25-
module.exports = function (app) {
27+
module.exports = function(app) {
2628
app.enable('trust proxy');
2729
app.set('view engine', 'ejs');
2830

29-
// Only loaded when SECURE_EXPRESS is `true`
30-
if (process.env.SECURE_EXPRESS)
31+
// Only loaded when running in Bluemix
32+
if (process.env.VCAP_APPLICATION) {
3133
require('./security')(app);
34+
}
3235

3336
// Configure Express
3437
app.use(bodyParser.urlencoded({ extended: true, limit: '1mb' }));
3538
app.use(bodyParser.json({ limit: '1mb' }));
36-
app.use(express.static(__dirname + '/../public'));
39+
app.use(express.static(path.join(__dirname, '..', 'public')));
40+
app.use(morgan('dev'));
3741

3842
// Setup the upload mechanism
3943
var storage = multer.diskStorage({
40-
destination: function (req, file, cb) {
44+
destination: function(req, file, cb) {
4145
cb(null, './uploads/');
4246
},
43-
filename: function (req, file, cb) {
47+
filename: function(req, file, cb) {
4448
cb(null, Date.now() + '-' + file.originalname);
4549
}
4650
});
4751

48-
var upload = multer({ storage: storage });
52+
var upload = multer({
53+
storage: storage
54+
});
4955
app.upload = upload;
5056

5157
// Remove files older than 1 hour every hour.
5258
setInterval(function() {
53-
var removed = findRemoveSync(__dirname + '/../uploads', {age: {seconds: 3600}});
54-
if (removed.length > 0)
59+
var removed = findRemoveSync(path.join(__dirname, '..', 'uploads'), { age: { seconds: 3600 } });
60+
if (removed.length > 0) {
5561
console.log('removed:', removed);
62+
}
5663
}, 3600000);
5764
};

config/security.js

+19-11
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717
'use strict';
1818

1919
// security.js
20-
var secure = require('express-secure-only'),
21-
csrf = require('csurf'),
22-
cookieParser = require('cookie-parser'),
23-
rateLimit = require('express-rate-limit'),
24-
helmet = require('helmet');
25-
26-
module.exports = function (app) {
20+
var secure = require('express-secure-only');
21+
var csrf = require('csurf');
22+
var cookieParser = require('cookie-parser');
23+
var rateLimit = require('express-rate-limit');
24+
var helmet = require('helmet');
2725

26+
module.exports = function(app) {
2827
// 1. redirects http to https
2928
app.use(secure());
3029

@@ -37,7 +36,9 @@ module.exports = function (app) {
3736
app.use(cookieParser(secret));
3837

3938
// 4. csrf
40-
var csrfProtection = csrf({ cookie: true });
39+
var csrfProtection = csrf({
40+
cookie: true
41+
});
4142
app.get('/', csrfProtection, function(req, res, next) {
4243
req._csrfToken = req.csrfToken();
4344
next();
@@ -49,12 +50,19 @@ module.exports = function (app) {
4950
delayMs: 0,
5051
max: 5,
5152
message: JSON.stringify({
52-
error:'Too many requests, please try again in 30 seconds.',
53+
error: 'Too many requests, please try again in 30 seconds.',
5354
code: 429
54-
}),
55+
})
5556
});
5657

57-
5858
// 3. rate limiting.
5959
app.use('/api/', csrfProtection, limiter);
60+
61+
app.get('/*', csrfProtection, function(req, res, next) {
62+
res.locals = {
63+
ga: process.env.GOOGLE_ANALYTICS,
64+
ct: req.csrfToken()
65+
};
66+
next();
67+
});
6068
};

manifest.yml

+2-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ applications:
66
- services:
77
- document-conversion-service
88
name: document-conversion-demo
9-
command: node app.js
9+
command: npm start
1010
path: .
11-
memory: 512M
12-
env:
13-
NODE_ENV: production
14-
SECURE_EXPRESS: 1
11+
memory: 512M

0 commit comments

Comments
 (0)