|
1 |
| -var Express = require('express'); |
2 |
| -var gplay = require('google-play-scraper'); |
3 |
| -var url = require('url'); |
4 |
| -var path = require('path'); |
5 |
| -var qs = require('querystring'); |
6 |
| -var _ = require('lodash') |
| 1 | +'use strict'; |
7 | 2 |
|
8 |
| -var app = Express(); |
9 |
| -app.enable('trust proxy'); |
10 |
| -var router = Express.Router(); |
| 3 | +const Express = require('express'); |
| 4 | +const gplay = require('google-play-scraper'); |
| 5 | +const url = require('url'); |
| 6 | +const path = require('path'); |
| 7 | +const qs = require('querystring'); |
| 8 | +const _ = require('lodash'); |
| 9 | + |
| 10 | +const router = Express.Router(); |
11 | 11 |
|
12 | 12 | /* Index */
|
13 |
| -router.get('/', function(req, res) { |
14 |
| - res.json({ |
15 |
| - apps: buildUrl(req, 'apps'), |
16 |
| - developers: buildUrl(req, 'developers') |
17 |
| - }); |
| 13 | +router.get('/', function (req, res) { |
| 14 | + res.json({ |
| 15 | + apps: buildUrl(req, 'apps'), |
| 16 | + developers: buildUrl(req, 'developers') |
| 17 | + }); |
18 | 18 | });
|
19 | 19 |
|
20 | 20 | /* App search */
|
21 |
| -router.get('/apps/', function(req, res, done) { |
22 |
| - if (!req.query.q) { |
23 |
| - return done(); |
24 |
| - } |
| 21 | +router.get('/apps/', function (req, res, done) { |
| 22 | + if (!req.query.q) { |
| 23 | + return done(); |
| 24 | + } |
25 | 25 |
|
26 |
| - var opts = _.assign({term: req.query.q}, req.query); |
| 26 | + const opts = _.assign({term: req.query.q}, req.query); |
27 | 27 |
|
28 |
| - gplay.search(opts).each(cleanUrls(req)).then(toList) |
29 |
| - .then(res.json.bind(res), error(res)); |
| 28 | + gplay.search(opts) |
| 29 | + .then((apps) => apps.map(cleanUrls(req))) |
| 30 | + .then(toList) |
| 31 | + .then(res.json.bind(res), error(res)); |
30 | 32 | });
|
31 | 33 |
|
32 | 34 | /* Search suggest */
|
33 |
| -router.get('/apps/', function(req, res, done) { |
34 |
| - if (!req.query.suggest) { |
35 |
| - return done(); |
36 |
| - } |
| 35 | +router.get('/apps/', function (req, res, done) { |
| 36 | + if (!req.query.suggest) { |
| 37 | + return done(); |
| 38 | + } |
| 39 | + |
| 40 | + function toJSON (term) { |
| 41 | + return { |
| 42 | + term, |
| 43 | + url: buildUrl(req, '/apps/') + '?' + qs.stringify({q: term}) |
| 44 | + }; |
| 45 | + } |
37 | 46 |
|
38 |
| - gplay.suggest(req.query.suggest).map(function(term){ |
39 |
| - return { |
40 |
| - term: term, |
41 |
| - url: buildUrl(req, '/apps/') + '?' + qs.stringify({q: term}) |
42 |
| - }; |
43 |
| - }).then(toList).then(res.json.bind(res), error(res)); |
| 47 | + gplay.suggest(req.query.suggest) |
| 48 | + .then((terms) => terms.map(toJSON)) |
| 49 | + .then(toList) |
| 50 | + .then(res.json.bind(res), error(res)); |
44 | 51 | });
|
45 | 52 |
|
46 | 53 | /* App list */
|
47 |
| -router.get('/apps/', function(req, res) { |
48 |
| - |
49 |
| - function paginate(apps) { |
50 |
| - var num = parseInt(req.query.num || '60'); |
51 |
| - var start = parseInt(req.query.start || '0'); |
52 |
| - |
53 |
| - if (start - num >= 0) { |
54 |
| - req.query.start = start - num; |
55 |
| - apps.prev = buildUrl(req, '/apps/') + '?' + qs.stringify(req.query); |
56 |
| - } |
57 |
| - |
58 |
| - if (start + num <= 500) { |
59 |
| - req.query.start = start + num; |
60 |
| - apps.next = buildUrl(req, '/apps/') + '?' + qs.stringify(req.query); |
61 |
| - } |
| 54 | +router.get('/apps/', function (req, res) { |
| 55 | + function paginate (apps) { |
| 56 | + const num = parseInt(req.query.num || '60'); |
| 57 | + const start = parseInt(req.query.start || '0'); |
| 58 | + |
| 59 | + if (start - num >= 0) { |
| 60 | + req.query.start = start - num; |
| 61 | + apps.prev = buildUrl(req, '/apps/') + '?' + qs.stringify(req.query); |
| 62 | + } |
62 | 63 |
|
63 |
| - return apps; |
| 64 | + if (start + num <= 500) { |
| 65 | + req.query.start = start + num; |
| 66 | + apps.next = buildUrl(req, '/apps/') + '?' + qs.stringify(req.query); |
64 | 67 | }
|
65 | 68 |
|
66 |
| - gplay.list(_.clone(req.query)).each(cleanUrls(req)) |
67 |
| - .then(toList).then(paginate) |
68 |
| - .then(res.json.bind(res), error(res)); |
| 69 | + return apps; |
| 70 | + } |
| 71 | + |
| 72 | + gplay.list(_.clone(req.query)) |
| 73 | + .then((apps) => apps.map(cleanUrls(req))) |
| 74 | + .then(toList).then(paginate) |
| 75 | + .then(res.json.bind(res), error(res)); |
69 | 76 | });
|
70 | 77 |
|
71 | 78 | /* App detail*/
|
72 |
| -router.get('/apps/:appId', function(req, res) { |
73 |
| - var opts = _.assign({appId: req.params.appId}, req.query); |
74 |
| - gplay.app(opts).then(cleanUrls(req)) |
75 |
| - .then(res.json.bind(res), error(res)); |
| 79 | +router.get('/apps/:appId', function (req, res) { |
| 80 | + const opts = _.assign({appId: req.params.appId}, req.query); |
| 81 | + gplay.app(opts) |
| 82 | + .then(cleanUrls(req)) |
| 83 | + .then(res.json.bind(res), error(res)); |
76 | 84 | });
|
77 | 85 |
|
78 | 86 | /* Similar apps */
|
79 |
| -router.get('/apps/:appId/similar', function(req, res) { |
80 |
| - var opts = _.assign({appId: req.params.appId}, req.query); |
81 |
| - gplay.similar(opts).each(cleanUrls(req)).then(toList) |
82 |
| - .then(res.json.bind(res), error(res)); |
| 87 | +router.get('/apps/:appId/similar', function (req, res) { |
| 88 | + const opts = _.assign({appId: req.params.appId}, req.query); |
| 89 | + gplay.similar(opts) |
| 90 | + .then((apps) => apps.map(cleanUrls(req))) |
| 91 | + .then(toList) |
| 92 | + .then(res.json.bind(res), error(res)); |
83 | 93 | });
|
84 | 94 |
|
85 | 95 | /* App reviews */
|
86 |
| -router.get('/apps/:appId/reviews', function(req, res) { |
87 |
| - |
88 |
| - function paginate(apps) { |
89 |
| - var page = parseInt(req.query.page || '0'); |
90 |
| - |
91 |
| - var subpath = '/apps/' + req.params.appId + '/reviews/'; |
92 |
| - if (page > 0) { |
93 |
| - req.query.page = page - 1; |
94 |
| - apps.prev = buildUrl(req, subpath) + '?' + qs.stringify(req.query); |
95 |
| - } |
96 |
| - |
97 |
| - if (apps.results.length) { |
98 |
| - req.query.page = page + 1; |
99 |
| - apps.next = buildUrl(req, subpath) + '?' + qs.stringify(req.query); |
100 |
| - } |
| 96 | +router.get('/apps/:appId/reviews', function (req, res) { |
| 97 | + function paginate (apps) { |
| 98 | + const page = parseInt(req.query.page || '0'); |
| 99 | + |
| 100 | + const subpath = '/apps/' + req.params.appId + '/reviews/'; |
| 101 | + if (page > 0) { |
| 102 | + req.query.page = page - 1; |
| 103 | + apps.prev = buildUrl(req, subpath) + '?' + qs.stringify(req.query); |
| 104 | + } |
101 | 105 |
|
102 |
| - return apps; |
| 106 | + if (apps.results.length) { |
| 107 | + req.query.page = page + 1; |
| 108 | + apps.next = buildUrl(req, subpath) + '?' + qs.stringify(req.query); |
103 | 109 | }
|
104 | 110 |
|
105 |
| - var opts = _.assign({appId: req.params.appId}, req.query); |
106 |
| - gplay.reviews(opts).then(toList).then(paginate) |
107 |
| - .then(res.json.bind(res), error(res)); |
| 111 | + return apps; |
| 112 | + } |
| 113 | + |
| 114 | + const opts = _.assign({appId: req.params.appId}, req.query); |
| 115 | + gplay.reviews(opts) |
| 116 | + .then(toList) |
| 117 | + .then(paginate) |
| 118 | + .then(res.json.bind(res), error(res)); |
108 | 119 | });
|
109 | 120 |
|
110 | 121 | /* Apps by developer */
|
111 |
| -router.get('/developers/:devId/', function(req, res) { |
112 |
| - var opts = _.assign({devId: req.params.devId}, req.query); |
113 |
| - gplay.developer(opts).each(cleanUrls(req)).then(toList) |
114 |
| - .then(res.json.bind(res), error(res)); |
| 122 | +// FIXME this should instead be a dev detail endpoint, with name and app list |
| 123 | +// apps should then link to this |
| 124 | +router.get('/developers/:devId/', function (req, res) { |
| 125 | + const opts = _.assign({devId: req.params.devId}, req.query); |
| 126 | + gplay.developer(opts) |
| 127 | + .then((apps) => apps.map(cleanUrls(req))) |
| 128 | + .then(toList) |
| 129 | + .then(res.json.bind(res), error(res)); |
115 | 130 | });
|
116 | 131 |
|
117 | 132 | /* Developer list (not supported) */
|
118 |
| -router.get('/developers/', function(req, res) { |
119 |
| - res.status(400).json({ |
120 |
| - message: 'Please specify a developer id.', |
121 |
| - example: buildUrl(req, '/developers/DxCo Games') |
122 |
| - }); |
| 133 | +router.get('/developers/', function (req, res) { |
| 134 | + res.status(400).json({ |
| 135 | + message: 'Please specify a developer id.', |
| 136 | + example: buildUrl(req, '/developers/DxCo Games') |
| 137 | + }); |
123 | 138 | });
|
124 | 139 |
|
125 |
| -app.use('/gps-api', router); |
126 |
| -module.exports = app; |
127 |
| - |
128 |
| -function error(res) { |
129 |
| - return function(e) { |
130 |
| - res.status(400).json({message: e.message}); |
131 |
| - }; |
| 140 | +function error (res) { |
| 141 | + return function (e) { |
| 142 | + res.status(400).json({message: e.message}); |
| 143 | + }; |
132 | 144 | }
|
133 | 145 |
|
134 |
| -function toList(apps) { |
135 |
| - return {results: apps}; |
| 146 | +function toList (apps) { |
| 147 | + return {results: apps}; |
136 | 148 | }
|
137 | 149 |
|
138 |
| -function cleanUrls(req) { |
139 |
| - return function (app) { |
140 |
| - app.playstoreUrl = app.url; |
141 |
| - app.url = buildUrl(req, 'apps/' + app.appId); |
142 |
| - app.similar = buildUrl(req, 'apps/' + app.appId + '/similar'); |
143 |
| - app.reviews = buildUrl(req, 'apps/' + app.appId + '/reviews'); |
144 |
| - return app; |
145 |
| - }; |
| 150 | +function cleanUrls (req) { |
| 151 | + return function (app) { |
| 152 | + app.playstoreUrl = app.url; |
| 153 | + app.url = buildUrl(req, 'apps/' + app.appId); |
| 154 | + app.similar = buildUrl(req, 'apps/' + app.appId + '/similar'); |
| 155 | + app.reviews = buildUrl(req, 'apps/' + app.appId + '/reviews'); |
| 156 | + return app; |
| 157 | + }; |
146 | 158 | }
|
147 | 159 |
|
148 |
| -function buildUrl(req, subpath) { |
149 |
| - var basePath = req.originalUrl; //full url |
150 |
| - var routerPath = req.baseUrl; |
151 |
| - basePath = basePath.split(routerPath)[0]; //drops the api subpath |
152 |
| - |
153 |
| - return url.format({ |
154 |
| - protocol: req.protocol, |
155 |
| - host: req.get('host'), |
156 |
| - pathname: path.join(basePath, routerPath, subpath, '/') |
157 |
| - }); |
| 160 | +// FIXME whipe this |
| 161 | +function buildUrl (req, subpath) { |
| 162 | + let basePath = req.originalUrl; // full url |
| 163 | + const routerPath = req.baseUrl; |
| 164 | + basePath = basePath.split(routerPath)[0]; // drops the api subpath |
| 165 | + |
| 166 | + return url.format({ |
| 167 | + protocol: req.protocol, |
| 168 | + host: req.get('host'), |
| 169 | + pathname: path.join(basePath, routerPath, subpath, '/') |
| 170 | + }); |
158 | 171 | }
|
| 172 | + |
| 173 | +module.exports = router; |
0 commit comments