Lint spacing
This commit is contained in:
parent
4fc4d314fd
commit
2d8b62fb84
@ -31,14 +31,14 @@ function queryBuildingsAtPoint(lng, lat) {
|
|||||||
)
|
)
|
||||||
`,
|
`,
|
||||||
[lng, lat]
|
[lng, lat]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function queryBuildingsByReference(key, id) {
|
function queryBuildingsByReference(key, id) {
|
||||||
if (key === 'toid'){
|
if (key === 'toid') {
|
||||||
return db.manyOrNone(
|
return db.manyOrNone(
|
||||||
`SELECT
|
`SELECT
|
||||||
*
|
*
|
||||||
@ -48,7 +48,7 @@ function queryBuildingsByReference(key, id) {
|
|||||||
ref_toid = $1
|
ref_toid = $1
|
||||||
`,
|
`,
|
||||||
[id]
|
[id]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@ -65,19 +65,19 @@ function queryBuildingsByReference(key, id) {
|
|||||||
p.uprn = $1
|
p.uprn = $1
|
||||||
`,
|
`,
|
||||||
[id]
|
[id]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return {error: 'Key must be UPRN or TOID'};
|
return { error: 'Key must be UPRN or TOID' };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBuildingById(id) {
|
function getBuildingById(id) {
|
||||||
return db.one(
|
return db.one(
|
||||||
"SELECT * FROM buildings WHERE building_id = $1",
|
"SELECT * FROM buildings WHERE building_id = $1",
|
||||||
[id]
|
[id]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@ -89,7 +89,7 @@ function getBuildingLikeById(building_id, user_id) {
|
|||||||
[building_id, user_id]
|
[building_id, user_id]
|
||||||
).then(res => {
|
).then(res => {
|
||||||
return res && res.like
|
return res && res.like
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@ -99,7 +99,7 @@ function getBuildingUPRNsById(id) {
|
|||||||
return db.any(
|
return db.any(
|
||||||
"SELECT uprn, parent_uprn FROM building_properties WHERE building_id = $1",
|
"SELECT uprn, parent_uprn FROM building_properties WHERE building_id = $1",
|
||||||
[id]
|
[id]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@ -160,10 +160,9 @@ function saveBuilding(building_id, building, user_id) {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
// TODO report transaction error as 'Need to re-fetch building before update'
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return {error: error};
|
return { error: error };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +174,7 @@ function likeBuilding(building_id, user_id) {
|
|||||||
// - insert changeset
|
// - insert changeset
|
||||||
// - update building to latest state
|
// - update building to latest state
|
||||||
// commit or rollback (serializable - could be more compact?)
|
// commit or rollback (serializable - could be more compact?)
|
||||||
return db.tx({serializable}, t => {
|
return db.tx({ serializable }, t => {
|
||||||
return t.none(
|
return t.none(
|
||||||
"INSERT INTO building_user_likes ( building_id, user_id ) VALUES ($1, $2);",
|
"INSERT INTO building_user_likes ( building_id, user_id ) VALUES ($1, $2);",
|
||||||
[building_id, user_id]
|
[building_id, user_id]
|
||||||
@ -191,7 +190,7 @@ function likeBuilding(building_id, user_id) {
|
|||||||
$1:json, $2, $3
|
$1:json, $2, $3
|
||||||
) RETURNING log_id
|
) RETURNING log_id
|
||||||
`,
|
`,
|
||||||
[{likes_total: building.likes}, building_id, user_id]
|
[{ likes_total: building.likes }, building_id, user_id]
|
||||||
).then(revision => {
|
).then(revision => {
|
||||||
return t.one(
|
return t.one(
|
||||||
`UPDATE buildings
|
`UPDATE buildings
|
||||||
@ -208,12 +207,11 @@ function likeBuilding(building_id, user_id) {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
// TODO report transaction error as 'Need to re-fetch building before update'
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (error.detail && error.detail.includes("already exists")){
|
if (error.detail && error.detail.includes("already exists")) {
|
||||||
// 'already exists' is thrown if user already liked it
|
// 'already exists' is thrown if user already liked it
|
||||||
return {error: 'It looks like you already like that building!'};
|
return { error: 'It looks like you already like that building!' };
|
||||||
} else {
|
} else {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
@ -228,7 +226,7 @@ function unlikeBuilding(building_id, user_id) {
|
|||||||
// - insert changeset
|
// - insert changeset
|
||||||
// - update building to latest state
|
// - update building to latest state
|
||||||
// commit or rollback (serializable - could be more compact?)
|
// commit or rollback (serializable - could be more compact?)
|
||||||
return db.tx({serializable}, t => {
|
return db.tx({ serializable }, t => {
|
||||||
return t.none(
|
return t.none(
|
||||||
"DELETE FROM building_user_likes WHERE building_id = $1 AND user_id = $2;",
|
"DELETE FROM building_user_likes WHERE building_id = $1 AND user_id = $2;",
|
||||||
[building_id, user_id]
|
[building_id, user_id]
|
||||||
@ -244,7 +242,7 @@ function unlikeBuilding(building_id, user_id) {
|
|||||||
$1:json, $2, $3
|
$1:json, $2, $3
|
||||||
) RETURNING log_id
|
) RETURNING log_id
|
||||||
`,
|
`,
|
||||||
[{likes_total: building.likes}, building_id, user_id]
|
[{ likes_total: building.likes }, building_id, user_id]
|
||||||
).then(revision => {
|
).then(revision => {
|
||||||
return t.one(
|
return t.one(
|
||||||
`UPDATE buildings
|
`UPDATE buildings
|
||||||
@ -261,12 +259,11 @@ function unlikeBuilding(building_id, user_id) {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
// TODO report transaction error as 'Need to re-fetch building before update'
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (error.detail && error.detail.includes("already exists")){
|
if (error.detail && error.detail.includes("already exists")) {
|
||||||
// 'already exists' is thrown if user already liked it
|
// 'already exists' is thrown if user already liked it
|
||||||
return {error: 'It looks like you already like that building!'};
|
return { error: 'It looks like you already like that building!' };
|
||||||
} else {
|
} else {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
@ -331,7 +328,7 @@ const BUILDING_FIELD_WHITELIST = new Set([
|
|||||||
* @param {Set} whitelist
|
* @param {Set} whitelist
|
||||||
* @returns {[object, object]}
|
* @returns {[object, object]}
|
||||||
*/
|
*/
|
||||||
function compare(old_obj, new_obj, whitelist){
|
function compare(old_obj, new_obj, whitelist) {
|
||||||
const reverse_patch = {}
|
const reverse_patch = {}
|
||||||
const forward_patch = {}
|
const forward_patch = {}
|
||||||
for (const [key, value] of Object.entries(new_obj)) {
|
for (const [key, value] of Object.entries(new_obj)) {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
import db from '../db';
|
import db from '../db';
|
||||||
|
|
||||||
function queryLocation(term){
|
function queryLocation(term) {
|
||||||
const max_results = 5;
|
const max_results = 5;
|
||||||
return db.manyOrNone(
|
return db.manyOrNone(
|
||||||
`SELECT
|
`SELECT
|
||||||
|
@ -7,10 +7,10 @@ import db from '../db';
|
|||||||
|
|
||||||
function createUser(user) {
|
function createUser(user) {
|
||||||
if (!user.password || user.password.length < 8) {
|
if (!user.password || user.password.length < 8) {
|
||||||
return Promise.reject({error: 'Password must be at least 8 characters'})
|
return Promise.reject({ error: 'Password must be at least 8 characters' })
|
||||||
}
|
}
|
||||||
if (user.password.length > 70) {
|
if (user.password.length > 70) {
|
||||||
return Promise.reject({error: 'Password must be at most 70 characters'})
|
return Promise.reject({ error: 'Password must be at most 70 characters' })
|
||||||
}
|
}
|
||||||
return db.one(
|
return db.one(
|
||||||
`INSERT
|
`INSERT
|
||||||
@ -26,21 +26,21 @@ function createUser(user) {
|
|||||||
crypt($3, gen_salt('bf'))
|
crypt($3, gen_salt('bf'))
|
||||||
) RETURNING user_id
|
) RETURNING user_id
|
||||||
`, [
|
`, [
|
||||||
user.username,
|
user.username,
|
||||||
user.email,
|
user.email,
|
||||||
user.password
|
user.password
|
||||||
]
|
]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error('Error:', error)
|
console.error('Error:', error)
|
||||||
|
|
||||||
if (error.detail.indexOf('already exists') !== -1){
|
if (error.detail.indexOf('already exists') !== -1) {
|
||||||
if (error.detail.indexOf('username') !== -1){
|
if (error.detail.indexOf('username') !== -1) {
|
||||||
return {error:'Username already registered'};
|
return { error: 'Username already registered' };
|
||||||
} else if (error.detail.indexOf('email') !== -1) {
|
} else if (error.detail.indexOf('email') !== -1) {
|
||||||
return {error: 'Email already registered'};
|
return { error: 'Email already registered' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {error: 'Database error'}
|
return { error: 'Database error' }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,18 +55,18 @@ function authUser(username, password) {
|
|||||||
WHERE
|
WHERE
|
||||||
username = $1
|
username = $1
|
||||||
`, [
|
`, [
|
||||||
username,
|
username,
|
||||||
password
|
password
|
||||||
]
|
]
|
||||||
).then(function(user){
|
).then(function (user) {
|
||||||
if (user && user.auth_ok) {
|
if (user && user.auth_ok) {
|
||||||
return {user_id: user.user_id}
|
return { user_id: user.user_id }
|
||||||
} else {
|
} else {
|
||||||
return {error: 'Username or password not recognised'}
|
return { error: 'Username or password not recognised' }
|
||||||
}
|
}
|
||||||
}).catch(function(err){
|
}).catch(function (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return {error: 'Username or password not recognised'};
|
return { error: 'Username or password not recognised' };
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ function getUserById(user_id) {
|
|||||||
`, [
|
`, [
|
||||||
user_id
|
user_id
|
||||||
]
|
]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error('Error:', error)
|
console.error('Error:', error)
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@ -100,9 +100,9 @@ function getNewUserAPIKey(user_id) {
|
|||||||
`, [
|
`, [
|
||||||
user_id
|
user_id
|
||||||
]
|
]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error('Error:', error)
|
console.error('Error:', error)
|
||||||
return {error: 'Failed to generate new API key.'};
|
return { error: 'Failed to generate new API key.' };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ function authAPIUser(api_key) {
|
|||||||
`, [
|
`, [
|
||||||
api_key
|
api_key
|
||||||
]
|
]
|
||||||
).catch(function(error){
|
).catch(function (error) {
|
||||||
console.error('Error:', error)
|
console.error('Error:', error)
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ function strictParseInt(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function parseBuildingURL(url){
|
function parseBuildingURL(url) {
|
||||||
const re = /\/building\/([^/]+).html/;
|
const re = /\/building\/([^/]+).html/;
|
||||||
const matches = re.exec(url);
|
const matches = re.exec(url);
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ function parseCategoryURL(url) {
|
|||||||
return default_cat
|
return default_cat
|
||||||
}
|
}
|
||||||
const matches = /^\/(view|edit)\/([^/.]+)/.exec(url);
|
const matches = /^\/(view|edit)\/([^/.]+)/.exec(url);
|
||||||
const cat = (matches && matches.length >= 3)? matches[2] : default_cat;
|
const cat = (matches && matches.length >= 3) ? matches[2] : default_cat;
|
||||||
return cat;
|
return cat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import express from 'express';
|
|||||||
import { renderToString } from 'react-dom/server';
|
import { renderToString } from 'react-dom/server';
|
||||||
import serialize from 'serialize-javascript';
|
import serialize from 'serialize-javascript';
|
||||||
|
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
import session from 'express-session';
|
import session from 'express-session';
|
||||||
import pgConnect from 'connect-pg-simple';
|
import pgConnect from 'connect-pg-simple';
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ const sess = {
|
|||||||
name: 'cl.session',
|
name: 'cl.session',
|
||||||
store: new pgSession({
|
store: new pgSession({
|
||||||
pgPromise: db,
|
pgPromise: db,
|
||||||
tableName : 'user_sessions'
|
tableName: 'user_sessions'
|
||||||
}),
|
}),
|
||||||
secret: process.env.APP_COOKIE_SECRET,
|
secret: process.env.APP_COOKIE_SECRET,
|
||||||
saveUninitialized: false,
|
saveUninitialized: false,
|
||||||
@ -78,22 +78,22 @@ function frontendRoute(req, res) {
|
|||||||
|
|
||||||
const user_id = req.session.user_id;
|
const user_id = req.session.user_id;
|
||||||
const building_id = parseBuildingURL(req.url);
|
const building_id = parseBuildingURL(req.url);
|
||||||
const is_building = (typeof(building_id) !== "undefined");
|
const is_building = (typeof (building_id) !== "undefined");
|
||||||
if (is_building && isNaN(building_id)){
|
if (is_building && isNaN(building_id)) {
|
||||||
context.status = 404;
|
context.status = 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
user_id? getUserById(user_id) : undefined,
|
user_id ? getUserById(user_id) : undefined,
|
||||||
is_building? getBuildingById(building_id) : undefined,
|
is_building ? getBuildingById(building_id) : undefined,
|
||||||
is_building? getBuildingUPRNsById(building_id) : undefined,
|
is_building ? getBuildingUPRNsById(building_id) : undefined,
|
||||||
(is_building && user_id)? getBuildingLikeById(building_id, user_id) : false
|
(is_building && user_id) ? getBuildingLikeById(building_id, user_id) : false
|
||||||
]).then(function(values){
|
]).then(function (values) {
|
||||||
const user = values[0];
|
const user = values[0];
|
||||||
const building = values[1];
|
const building = values[1];
|
||||||
const uprns = values[2];
|
const uprns = values[2];
|
||||||
const building_like = values[3];
|
const building_like = values[3];
|
||||||
if (is_building && typeof(building) === "undefined"){
|
if (is_building && typeof (building) === "undefined") {
|
||||||
context.status = 404
|
context.status = 404
|
||||||
}
|
}
|
||||||
data.user = user;
|
data.user = user;
|
||||||
@ -113,7 +113,7 @@ function frontendRoute(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderHTML(context, data, req, res){
|
function renderHTML(context, data, req, res) {
|
||||||
const markup = renderToString(
|
const markup = renderToString(
|
||||||
<StaticRouter context={context} location={req.url}>
|
<StaticRouter context={context} location={req.url}>
|
||||||
<App user={data.user} building={data.building} building_like={data.building_like} />
|
<App user={data.user} building={data.building} building_like={data.building_like} />
|
||||||
@ -124,7 +124,7 @@ function renderHTML(context, data, req, res){
|
|||||||
res.redirect(context.url);
|
res.redirect(context.url);
|
||||||
} else {
|
} else {
|
||||||
res.status(context.status).send(
|
res.status(context.status).send(
|
||||||
`<!doctype html>
|
`<!doctype html>
|
||||||
<html lang="">
|
<html lang="">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
@ -141,15 +141,15 @@ function renderHTML(context, data, req, res){
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
${
|
${
|
||||||
assets.client.css
|
assets.client.css
|
||||||
? `<link rel="stylesheet" href="${assets.client.css}">`
|
? `<link rel="stylesheet" href="${assets.client.css}">`
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
${
|
${
|
||||||
process.env.NODE_ENV === 'production'
|
process.env.NODE_ENV === 'production'
|
||||||
? `<script src="${assets.client.js}" defer></script>`
|
? `<script src="${assets.client.js}" defer></script>`
|
||||||
: `<script src="${assets.client.js}" defer crossorigin></script>`
|
: `<script src="${assets.client.js}" defer crossorigin></script>`
|
||||||
}
|
}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root">${markup}</div>
|
<div id="root">${markup}</div>
|
||||||
@ -169,24 +169,24 @@ server.use('/tiles', tileserver);
|
|||||||
// not implemented - may be useful to GET all buildings, paginated
|
// not implemented - may be useful to GET all buildings, paginated
|
||||||
|
|
||||||
// GET buildings at point
|
// GET buildings at point
|
||||||
server.get('/buildings/locate', function(req, res){
|
server.get('/buildings/locate', function (req, res) {
|
||||||
const { lng, lat } = req.query;
|
const { lng, lat } = req.query;
|
||||||
queryBuildingsAtPoint(lng, lat).then(function(result){
|
queryBuildingsAtPoint(lng, lat).then(function (result) {
|
||||||
res.send(result);
|
res.send(result);
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// GET buildings by reference (UPRN/TOID or other identifier)
|
// GET buildings by reference (UPRN/TOID or other identifier)
|
||||||
server.get('/buildings/reference', function(req, res){
|
server.get('/buildings/reference', function (req, res) {
|
||||||
const { key, id } = req.query;
|
const { key, id } = req.query;
|
||||||
queryBuildingsByReference(key, id).then(function(result){
|
queryBuildingsByReference(key, id).then(function (result) {
|
||||||
res.send(result);
|
res.send(result);
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -194,31 +194,31 @@ server.get('/buildings/reference', function(req, res){
|
|||||||
server.route('/building/:building_id.json')
|
server.route('/building/:building_id.json')
|
||||||
.get(function (req, res) {
|
.get(function (req, res) {
|
||||||
const { building_id } = req.params;
|
const { building_id } = req.params;
|
||||||
getBuildingById(building_id).then(function(result){
|
getBuildingById(building_id).then(function (result) {
|
||||||
res.send(result);
|
res.send(result);
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.post(function (req, res) {
|
.post(function (req, res) {
|
||||||
if (req.session.user_id) {
|
if (req.session.user_id) {
|
||||||
updateBuilding(req, res, req.session.user_id);
|
updateBuilding(req, res, req.session.user_id);
|
||||||
} else if (req.query.api_key) {
|
} else if (req.query.api_key) {
|
||||||
authAPIUser(req.query.api_key)
|
authAPIUser(req.query.api_key)
|
||||||
.then(function(user){
|
.then(function (user) {
|
||||||
updateBuilding(req, res, user.user_id)
|
updateBuilding(req, res, user.user_id)
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
res.send({error: 'Must be logged in'});
|
res.send({ error: 'Must be logged in' });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
res.send({error: 'Must be logged in'});
|
res.send({ error: 'Must be logged in' });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function updateBuilding(req, res, user_id){
|
function updateBuilding(req, res, user_id) {
|
||||||
const { building_id } = req.params;
|
const { building_id } = req.params;
|
||||||
const building = req.body;
|
const building = req.body;
|
||||||
saveBuilding(building_id, building, user_id).then(building => {
|
saveBuilding(building_id, building, user_id).then(building => {
|
||||||
@ -226,72 +226,72 @@ function updateBuilding(req, res, user_id){
|
|||||||
res.send(building)
|
res.send(building)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (typeof(building) === "undefined") {
|
if (typeof (building) === "undefined") {
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.send(building)
|
res.send(building)
|
||||||
}).catch(
|
}).catch(
|
||||||
() => res.send({error:'Database error'})
|
() => res.send({ error: 'Database error' })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET building UPRNs
|
// GET building UPRNs
|
||||||
server.get('/building/:building_id/uprns.json', function (req, res) {
|
server.get('/building/:building_id/uprns.json', function (req, res) {
|
||||||
const { building_id } = req.params;
|
const { building_id } = req.params;
|
||||||
getBuildingUPRNsById(building_id).then(function(result){
|
getBuildingUPRNsById(building_id).then(function (result) {
|
||||||
if (typeof(result) === "undefined") {
|
if (typeof (result) === "undefined") {
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.send({
|
res.send({
|
||||||
uprns: result
|
uprns: result
|
||||||
});
|
});
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// GET/POST like building
|
// GET/POST like building
|
||||||
server.route('/building/:building_id/like.json')
|
server.route('/building/:building_id/like.json')
|
||||||
.get(function(req, res){
|
.get(function (req, res) {
|
||||||
if (!req.session.user_id) {
|
if (!req.session.user_id) {
|
||||||
res.send({like: false}); // not logged in, so cannot have liked
|
res.send({ like: false }); // not logged in, so cannot have liked
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { building_id } = req.params;
|
const { building_id } = req.params;
|
||||||
getBuildingLikeById(building_id, req.session.user_id).then(like => {
|
getBuildingLikeById(building_id, req.session.user_id).then(like => {
|
||||||
if (typeof(like) === "undefined") {
|
if (typeof (like) === "undefined") {
|
||||||
res.send({like: false})
|
res.send({ like: false })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// any value returned means like
|
// any value returned means like
|
||||||
res.send({like: true})
|
res.send({ like: true })
|
||||||
}).catch(
|
}).catch(
|
||||||
() => res.send({error:'Database error'})
|
() => res.send({ error: 'Database error' })
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.post(function(req, res){
|
.post(function (req, res) {
|
||||||
if (!req.session.user_id) {
|
if (!req.session.user_id) {
|
||||||
res.send({error: 'Must be logged in'});
|
res.send({ error: 'Must be logged in' });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { building_id } = req.params;
|
const { building_id } = req.params;
|
||||||
const { like } = req.body;
|
const { like } = req.body;
|
||||||
if (like){
|
if (like) {
|
||||||
likeBuilding(building_id, req.session.user_id).then(building => {
|
likeBuilding(building_id, req.session.user_id).then(building => {
|
||||||
if (building.error) {
|
if (building.error) {
|
||||||
res.send(building)
|
res.send(building)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (typeof(building) === "undefined") {
|
if (typeof (building) === "undefined") {
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.send(building)
|
res.send(building)
|
||||||
}).catch(
|
}).catch(
|
||||||
() => res.send({error:'Database error'})
|
() => res.send({ error: 'Database error' })
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
unlikeBuilding(building_id, req.session.user_id).then(building => {
|
unlikeBuilding(building_id, req.session.user_id).then(building => {
|
||||||
@ -299,113 +299,113 @@ server.route('/building/:building_id/like.json')
|
|||||||
res.send(building)
|
res.send(building)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (typeof(building) === "undefined") {
|
if (typeof (building) === "undefined") {
|
||||||
res.send({error:'Database error'})
|
res.send({ error: 'Database error' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.send(building)
|
res.send(building)
|
||||||
}).catch(
|
}).catch(
|
||||||
() => res.send({error:'Database error'})
|
() => res.send({ error: 'Database error' })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// POST new user
|
// POST new user
|
||||||
server.post('/users', function(req, res){
|
server.post('/users', function (req, res) {
|
||||||
const user = req.body;
|
const user = req.body;
|
||||||
if (req.session.user_id) {
|
if (req.session.user_id) {
|
||||||
res.send({error: 'Already signed in'});
|
res.send({ error: 'Already signed in' });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.email){
|
if (user.email) {
|
||||||
if (user.email != user.confirm_email) {
|
if (user.email != user.confirm_email) {
|
||||||
res.send({error: "Email did not match confirmation."});
|
res.send({ error: "Email did not match confirmation." });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
user.email = null;
|
user.email = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
createUser(user).then(function(result){
|
createUser(user).then(function (result) {
|
||||||
if (result.user_id) {
|
if (result.user_id) {
|
||||||
req.session.user_id = result.user_id;
|
req.session.user_id = result.user_id;
|
||||||
res.send({user_id: result.user_id});
|
res.send({ user_id: result.user_id });
|
||||||
} else {
|
} else {
|
||||||
req.session.user_id = undefined;
|
req.session.user_id = undefined;
|
||||||
res.send({error: result.error});
|
res.send({ error: result.error });
|
||||||
}
|
}
|
||||||
}).catch(function(err){
|
}).catch(function (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
res.send(err)
|
res.send(err)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// POST user auth
|
// POST user auth
|
||||||
server.post('/login', function(req, res){
|
server.post('/login', function (req, res) {
|
||||||
authUser(req.body.username, req.body.password).then(function(user) {
|
authUser(req.body.username, req.body.password).then(function (user) {
|
||||||
if (user.user_id) {
|
if (user.user_id) {
|
||||||
req.session.user_id = user.user_id;
|
req.session.user_id = user.user_id;
|
||||||
} else {
|
} else {
|
||||||
req.session.user_id = undefined;
|
req.session.user_id = undefined;
|
||||||
}
|
}
|
||||||
res.send(user);
|
res.send(user);
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
res.send(error);
|
res.send(error);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// POST user logout
|
// POST user logout
|
||||||
server.post('/logout', function(req, res){
|
server.post('/logout', function (req, res) {
|
||||||
req.session.user_id = undefined;
|
req.session.user_id = undefined;
|
||||||
req.session.destroy(function(err){
|
req.session.destroy(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
res.send({error: 'Failed to end session'})
|
res.send({ error: 'Failed to end session' })
|
||||||
}
|
}
|
||||||
res.send({success: true});
|
res.send({ success: true });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// GET own user info
|
// GET own user info
|
||||||
server.get('/users/me', function(req, res){
|
server.get('/users/me', function (req, res) {
|
||||||
if (!req.session.user_id) {
|
if (!req.session.user_id) {
|
||||||
res.send({error: 'Must be logged in'});
|
res.send({ error: 'Must be logged in' });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserById(req.session.user_id).then(function(user){
|
getUserById(req.session.user_id).then(function (user) {
|
||||||
res.send(user);
|
res.send(user);
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
res.send(error);
|
res.send(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// POST generate API key
|
// POST generate API key
|
||||||
server.post('/api/key', function(req, res){
|
server.post('/api/key', function (req, res) {
|
||||||
if (!req.session.user_id) {
|
if (!req.session.user_id) {
|
||||||
res.send({error: 'Must be logged in'});
|
res.send({ error: 'Must be logged in' });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
getNewUserAPIKey(req.session.user_id).then(function(api_key){
|
getNewUserAPIKey(req.session.user_id).then(function (api_key) {
|
||||||
res.send(api_key);
|
res.send(api_key);
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
res.send(error);
|
res.send(error);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
// GET search
|
// GET search
|
||||||
server.get('/search', function(req, res){
|
server.get('/search', function (req, res) {
|
||||||
const search_term = req.query.q;
|
const search_term = req.query.q;
|
||||||
if (!search_term){
|
if (!search_term) {
|
||||||
res.send({
|
res.send({
|
||||||
error: 'Please provide a search term'
|
error: 'Please provide a search term'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
queryLocation(search_term).then((results) => {
|
queryLocation(search_term).then((results) => {
|
||||||
if (typeof(results) === "undefined") {
|
if (typeof (results) === "undefined") {
|
||||||
res.send({
|
res.send({
|
||||||
error: 'Database error'
|
error: 'Database error'
|
||||||
})
|
})
|
||||||
@ -425,7 +425,7 @@ server.get('/search', function(req, res){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}).catch(function(error){
|
}).catch(function (error) {
|
||||||
res.send(error);
|
res.send(error);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -20,7 +20,7 @@ import fs from 'node-fs';
|
|||||||
|
|
||||||
const CACHE_PATH = process.env.TILECACHE_PATH
|
const CACHE_PATH = process.env.TILECACHE_PATH
|
||||||
|
|
||||||
function get(tileset, z, x, y, cb){
|
function get(tileset, z, x, y, cb) {
|
||||||
if (!should_try_cache(tileset, z)) {
|
if (!should_try_cache(tileset, z)) {
|
||||||
cb(`Skip cache get ${tileset}/${z}/${x}/${y}`, null)
|
cb(`Skip cache get ${tileset}/${z}/${x}/${y}`, null)
|
||||||
return
|
return
|
||||||
@ -30,7 +30,7 @@ function get(tileset, z, x, y, cb){
|
|||||||
fs.readFile(fname, cb)
|
fs.readFile(fname, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
function put(im, tileset, z, x, y, cb){
|
function put(im, tileset, z, x, y, cb) {
|
||||||
if (!should_try_cache(tileset, z)) {
|
if (!should_try_cache(tileset, z)) {
|
||||||
cb(`Skip cache put ${tileset}/${z}/${x}/${y}`)
|
cb(`Skip cache put ${tileset}/${z}/${x}/${y}`)
|
||||||
return
|
return
|
||||||
@ -40,7 +40,7 @@ function put(im, tileset, z, x, y, cb){
|
|||||||
fs.writeFile(fname, im, 'binary', (err) => {
|
fs.writeFile(fname, im, 'binary', (err) => {
|
||||||
if (err && err.code === 'ENOENT') {
|
if (err && err.code === 'ENOENT') {
|
||||||
fs.mkdir(dir, 0o755, true, (err) => {
|
fs.mkdir(dir, 0o755, true, (err) => {
|
||||||
if (err){
|
if (err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else {
|
} else {
|
||||||
fs.writeFile(fname, im, 'binary', cb);
|
fs.writeFile(fname, im, 'binary', cb);
|
||||||
@ -53,11 +53,11 @@ function put(im, tileset, z, x, y, cb){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function should_try_cache(tileset, z) {
|
function should_try_cache(tileset, z) {
|
||||||
if (tileset === 'date_year'){
|
if (tileset === 'date_year') {
|
||||||
// cache high zoom because of front page hits
|
// cache high zoom because of front page hits
|
||||||
return z <= 16
|
return z <= 16
|
||||||
}
|
}
|
||||||
if (tileset === 'base_light' || tileset === 'base_night') {
|
if (tileset === 'base_light' || tileset === 'base_night') {
|
||||||
// cache for higher zoom levels (unlikely to change)
|
// cache for higher zoom levels (unlikely to change)
|
||||||
return z <= 17
|
return z <= 17
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ const DATASOURCE_CONFIG = {
|
|||||||
'password': process.env.PGPASSWORD,
|
'password': process.env.PGPASSWORD,
|
||||||
'port': process.env.PGPORT,
|
'port': process.env.PGPORT,
|
||||||
'geometry_field': 'geometry_geom',
|
'geometry_field': 'geometry_geom',
|
||||||
'extent' : '-20005048.4188,-9039211.13765,19907487.2779,17096598.5401',
|
'extent': '-20005048.4188,-9039211.13765,19907487.2779,17096598.5401',
|
||||||
'srid': 3857,
|
'srid': 3857,
|
||||||
'type': 'postgis'
|
'type': 'postgis'
|
||||||
}
|
}
|
||||||
@ -129,26 +129,26 @@ const mercator = new SphericalMercator({
|
|||||||
size: TILE_SIZE
|
size: TILE_SIZE
|
||||||
});
|
});
|
||||||
|
|
||||||
function get_bbox(z, x, y){
|
function get_bbox(z, x, y) {
|
||||||
return mercator.bbox(x, y, z, false, '900913');
|
return mercator.bbox(x, y, z, false, '900913');
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_xyz(bbox, z){
|
function get_xyz(bbox, z) {
|
||||||
return mercator.xyz(bbox, z, false, '900913')
|
return mercator.xyz(bbox, z, false, '900913')
|
||||||
}
|
}
|
||||||
|
|
||||||
function render_tile(tileset, z, x, y, geometry_id, cb){
|
function render_tile(tileset, z, x, y, geometry_id, cb) {
|
||||||
const bbox = get_bbox(z, x, y)
|
const bbox = get_bbox(z, x, y)
|
||||||
|
|
||||||
const map = new mapnik.Map(TILE_SIZE, TILE_SIZE, PROJ4_STRING);
|
const map = new mapnik.Map(TILE_SIZE, TILE_SIZE, PROJ4_STRING);
|
||||||
map.bufferSize = TILE_BUFFER_SIZE;
|
map.bufferSize = TILE_BUFFER_SIZE;
|
||||||
const layer = new mapnik.Layer('tile', PROJ4_STRING);
|
const layer = new mapnik.Layer('tile', PROJ4_STRING);
|
||||||
|
|
||||||
const table_def = (tileset === 'highlight')?
|
const table_def = (tileset === 'highlight') ?
|
||||||
get_highlight_table_def(geometry_id)
|
get_highlight_table_def(geometry_id)
|
||||||
: MAP_STYLE_TABLE_DEFINITIONS[tileset];
|
: MAP_STYLE_TABLE_DEFINITIONS[tileset];
|
||||||
|
|
||||||
const conf = Object.assign({table: table_def}, DATASOURCE_CONFIG)
|
const conf = Object.assign({ table: table_def }, DATASOURCE_CONFIG)
|
||||||
|
|
||||||
var postgis;
|
var postgis;
|
||||||
try {
|
try {
|
||||||
@ -159,7 +159,7 @@ function render_tile(tileset, z, x, y, geometry_id, cb){
|
|||||||
map.load(
|
map.load(
|
||||||
path.join(__dirname, '..', 'map_styles', 'polygon.xml'),
|
path.join(__dirname, '..', 'map_styles', 'polygon.xml'),
|
||||||
{ strict: true },
|
{ strict: true },
|
||||||
function(err, map){
|
function (err, map) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
map.add_layer(layer)
|
map.add_layer(layer)
|
||||||
@ -171,7 +171,7 @@ function render_tile(tileset, z, x, y, geometry_id, cb){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,17 +48,17 @@ function handle_tile_request(tileset, req, res) {
|
|||||||
const int_x = strictParseInt(x);
|
const int_x = strictParseInt(x);
|
||||||
const int_y = strictParseInt(y);
|
const int_y = strictParseInt(y);
|
||||||
|
|
||||||
if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)){
|
if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)) {
|
||||||
console.error("Missing x or y or z")
|
console.error("Missing x or y or z")
|
||||||
return {error:'Bad parameter'}
|
return { error: 'Bad parameter' }
|
||||||
}
|
}
|
||||||
|
|
||||||
load_tile(tileset, int_z, int_x, int_y).then((im) => {
|
load_tile(tileset, int_z, int_x, int_y).then((im) => {
|
||||||
res.writeHead(200, {'Content-Type': 'image/png'})
|
res.writeHead(200, { 'Content-Type': 'image/png' })
|
||||||
res.end(im)
|
res.end(im)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
res.status(500).send({error: err})
|
res.status(500).send({ error: err })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +158,8 @@ function stitch_tile(tileset, z, x, y) {
|
|||||||
).png().toBuffer()
|
).png().toBuffer()
|
||||||
}).then((buf) => {
|
}).then((buf) => {
|
||||||
return sharp(buf
|
return sharp(buf
|
||||||
).resize(256, 256, {fit: 'inside'}
|
).resize(256, 256, { fit: 'inside' }
|
||||||
).png().toBuffer()
|
).png().toBuffer()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -171,23 +171,23 @@ function handle_highlight_tile_request(req, res) {
|
|||||||
const int_x = strictParseInt(x);
|
const int_x = strictParseInt(x);
|
||||||
const int_y = strictParseInt(y);
|
const int_y = strictParseInt(y);
|
||||||
|
|
||||||
if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)){
|
if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)) {
|
||||||
console.error("Missing x or y or z")
|
console.error("Missing x or y or z")
|
||||||
return {error:'Bad parameter'}
|
return { error: 'Bad parameter' }
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlight layer uses geometry_id to outline a single building
|
// highlight layer uses geometry_id to outline a single building
|
||||||
const { highlight } = req.query
|
const { highlight } = req.query
|
||||||
const geometry_id = strictParseInt(highlight);
|
const geometry_id = strictParseInt(highlight);
|
||||||
if(isNaN(geometry_id)){
|
if (isNaN(geometry_id)) {
|
||||||
res.status(400).send({error:'Bad parameter'})
|
res.status(400).send({ error: 'Bad parameter' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
render_tile('highlight', int_z, int_x, int_y, geometry_id, function(err, im) {
|
render_tile('highlight', int_z, int_x, int_y, geometry_id, function (err, im) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
res.writeHead(200, {'Content-Type': 'image/png'})
|
res.writeHead(200, { 'Content-Type': 'image/png' })
|
||||||
res.end(im)
|
res.end(im)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user