Skip to content

Commit

Permalink
water-fountains#147 remove deprecatd byCoords
Browse files Browse the repository at this point in the history
moreover:
- also use the eslint plugin `unused-imports`
  • Loading branch information
robstoll committed Dec 20, 2021
1 parent de728a0 commit 81aecf3
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 148 deletions.
10 changes: 8 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
es2020: true,
},

plugins: ['@typescript-eslint', 'file-progress'],
plugins: ['@typescript-eslint', 'unused-imports', 'file-progress'],

// global rules for all file types
rules: {
Expand Down Expand Up @@ -39,9 +39,15 @@ module.exports = {
],

rules: {
'no-unused-vars': 'off', // same as "@typescript-eslint/no-unused-vars": "off",
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{ vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/explicit-module-boundary-types': 'error',

'@typescript-eslint/explicit-module-boundary-types': 'error',
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/ban-tslint-comment': 'error',
'@typescript-eslint/consistent-type-definitions': 'error',
Expand Down
15 changes: 15 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"eslint": "^7.28.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-file-progress": "^1.1.1",
"eslint-plugin-unused-imports": "^2.0.0",
"prettier": "^2.3.1",
"shelljs": "^0.8.4",
"ts-loader": "^8.3.0",
Expand Down
213 changes: 94 additions & 119 deletions server/api/controllers/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,24 @@
* and the profit contribution agreement available at https://www.my-d.org/ProfitContributionAgreement
*/

import OsmService from '../services/osm.service';
import WikidataService from '../services/wikidata.service';
import l from '../../common/logger';
import generateLocationData from '../services/generateLocationData.service';
import { locations } from '../../../config/locations';
import { fountain_property_metadata } from '../../../config/fountain.properties';
import NodeCache from 'node-cache';
import { conflate } from '../services/conflate.data.service';
import applyImpliedPropertiesOsm from '../services/applyImplied.service';
import {
essenceOf,
defaultCollectionEnhancement,
fillInMissingWikidataFountains,
fillWikipediaSummary,
} from '../services/processing.service';
import { updateCacheWithFountain } from '../services/database.service';
import { essenceOf, fillWikipediaSummary } from '../services/processing.service';
import { extractProcessingErrors } from './processing-errors.controller';
import { getImageInfo, getImgsOfCat } from '../services/wikimedia.service';
import { getCatExtract, getImgClaims } from '../services/claims.wm';
import { isBlacklisted } from '../services/categories.wm';
import haversine from 'haversine';
import _ from 'lodash';
import {
MAX_IMG_SHOWN_IN_GALLERY,
LAZY_ARTIST_NAME_LOADING_i41db, //,CACHE_FOR_HRS_i45db
} from '../../common/constants';
import sharedConstants from './../../common/shared-constants';
import { Request, Response } from 'express';
import { getSingleBooleanQueryParam, getSingleNumberQueryParam, getSingleStringQueryParam } from './utils';
import { getSingleBooleanQueryParam, getSingleStringQueryParam } from './utils';
import { Fountain, FountainCollection, GalleryValue, isDatabase } from '../../common/typealias';
import { hasWikiCommonsCategories } from '../../common/wikimedia-types';
import { ImageLike } from '../../../config/text2img';
Expand Down Expand Up @@ -88,30 +77,15 @@ export class Controller {
// Function to return detailed fountain information
// When requesting detailed information for a single fountain, there are two types of queries
getSingle(req: Request, res: Response): void {
// const start = new Date();
// let what: string;
const queryType = getSingleStringQueryParam(req, 'queryType');
const refresh = getSingleBooleanQueryParam(req, 'refresh', /* isOptional = */ true);

if (queryType === 'byCoords') {
const city = getSingleStringQueryParam(req, 'city');
l.info(`controller.js getSingle byCoords: refresh: ${refresh} , city: ` + city);

// byCoords will return the nearest fountain to the given coordinates.
// The databases are queried and fountains are reprocessed for this
reprocessFountainAtCoords(req, res, city);
// what = 'reprocessFountainAtCoords';
} else if (queryType === 'byId') {
l.info(`controller.js getSingle by: refresh: ${refresh}`);
// byId will look into the fountain cache and return the fountain with the given identifier
byId(req, res, req.query.idval?.toString() ?? '');
// what = 'byId';
if (queryType === 'byId') {
l.info(`controller.js getSingle byId: refresh: ${refresh}`);
byId(req, res);
} else {
res.status(400).send('only byCoords and byId supported');
res.status(400).send('only byId supported');
}
// const end = new Date();
// const elapse = (end - start)/1000;
//l.info('controller.js getSingle: '+what+' finished after '+elapse.toFixed(1)+' secs');
}

// Function to return all fountain information for a location.
Expand All @@ -120,7 +94,7 @@ export class Controller {
const city = getSingleStringQueryParam(req, 'city');
const refresh = getSingleBooleanQueryParam(req, 'refresh', /* isOptional = */ true);

// if a refresh is requested or if no data is in the cache, then reprocessess the fountains
// if a refresh is requested or if no data is in the cache, then reprocesses the fountains
if (refresh || cityCache.keys().indexOf(city) === -1) {
l.info(`controller.js byLocation: refresh: ${refresh} , city: ` + city);
generateLocationData(city)
Expand Down Expand Up @@ -249,12 +223,14 @@ function sendJson(resp: Response, obj: Record<string, any> | undefined, dbg: str
/**
* Function to respond to request by returning the fountain as defined by the provided identifier
*/
function byId(req: Request, res: Response, dbg: string): Promise<Fountain | undefined> {
function byId(req: Request, res: Response): Promise<Fountain | undefined> {
const city = getSingleStringQueryParam(req, 'city');
const database = getSingleStringQueryParam(req, 'database');
if (!isDatabase(database)) {
return new Promise((_, reject) => reject('unsupported database given: ' + database));
}
const idval = getSingleStringQueryParam(req, 'idval');
const dbg = idval;

let name = 'unkNamById';
// l.info('controller.js byId: '+cityS+' '+dbg);
Expand All @@ -274,9 +250,7 @@ function byId(req: Request, res: Response, dbg: string): Promise<Fountain | unde
fountainCollection = cityCache.get<FountainCollection>(city);
}
if (fountainCollection !== undefined) {
const fountain = fountainCollection.features.find(
f => f.properties['id_' + database]?.value === req.query.idval
);
const fountain = fountainCollection.features.find(f => f.properties['id_' + database]?.value === idval);
const imgMetaPromises: Promise<any>[] = [];
let lazyAdded = 0;
const gl = -1;
Expand Down Expand Up @@ -558,88 +532,89 @@ function byId(req: Request, res: Response, dbg: string): Promise<Fountain | unde
* - lng: longitude of search location
* - radius: radius in which to search for fountains
*/
function reprocessFountainAtCoords(req: Request, res: Response, dbg: string): void {
const lat = getSingleNumberQueryParam(req, 'lat');
const lng = getSingleNumberQueryParam(req, 'lng');
const radius = getSingleNumberQueryParam(req, 'radius');

l.info(
`controller.js reprocessFountainAtCoords: all fountains near lat:${lat}, lng: ${lng}, radius: ${radius} ` + dbg
);

// OSM promise
const osmPromise = OsmService
// Get data from OSM within given radius
.byCenter(lat, lng, radius)
// Process OSM data to apply implied properties
.then(r => applyImpliedPropertiesOsm(r))
.catch(e => {
l.error(`controller.js reprocessFountainAtCoords: Error collecting OSM data: ${JSON.stringify(e)} `);
// TODO @ralfhauser, this is an ugly side effect, this does nost stop the program but implies return void
// hence I changed it because we already catch errors in Promise.all
// res.status(500).send(e.stack);
throw e;
});

const wikidataPromise = WikidataService
// Fetch all wikidata items within radius
.idsByCenter(lat, lng, radius, dbg)
// Fetch detailed information for fountains based on wikidata ids
.then(r => WikidataService.byIds(r, dbg))
.catch(e => {
l.error(`Error collecting Wikidata data: ${e}`);
// TODO @ralfhauser, same same as above
// res.status(500).send(e.stack);
throw e;
});
const debugAll = true;
// When both OSM and Wikidata data have been collected, continue with joint processing
Promise.all([osmPromise, wikidataPromise])

// Get any missing wikidata fountains for #212 (fountains not fetched from Wikidata because not listed as fountains, but referenced by fountains of OSM)
.then(r => fillInMissingWikidataFountains(r[0], r[1], dbg))

// Conflate osm and wikidata fountains together
.then(r =>
conflate(
{
osm: r.osm,
wikidata: r.wikidata,
},
dbg,
debugAll
)
)

// return only the fountain that is closest to the coordinates of the query
.then(r => {
const distances = _.map(r, f => {
// compute distance to center for each fountain
return haversine(f.geometry.coordinates, [lng, lat], {
unit: 'meter',
format: '[lon,lat]',
});
});
// return closest
const closest = r[_.indexOf(distances, _.min(distances))];
return [closest];
})

// fetch more information about fountains (Artist information, gallery, etc.)
//TOOD @ralfhauser, the last parameter for debugAll was missing undefined is falsy hence I used false
.then(r => defaultCollectionEnhancement(r, dbg, false))

// Update cache with newly processed fountain
.then(r => {
const city = getSingleStringQueryParam(req, 'city');
const closest = updateCacheWithFountain(cityCache, r[0], city);
sendJson(res, closest, 'after updateCacheWithFountain');
})
.catch(e => {
l.error(`Error collecting data: ${e.stack}`);
res.status(500).send(e.stack);
});
}
//TODO #150 re-use part of the logic for id refresh
// function reprocessFountainAtCoords(req: Request, res: Response, dbg: string): void {
// const lat = getSingleNumberQueryParam(req, 'lat');
// const lng = getSingleNumberQueryParam(req, 'lng');
// const radius = getSingleNumberQueryParam(req, 'radius');

// l.info(
// `controller.js reprocessFountainAtCoords: all fountains near lat:${lat}, lng: ${lng}, radius: ${radius} ` + dbg
// );

// // OSM promise
// const osmPromise = OsmService
// // Get data from OSM within given radius
// .byCenter(lat, lng, radius)
// // Process OSM data to apply implied properties
// .then(r => applyImpliedPropertiesOsm(r))
// .catch(e => {
// l.error(`controller.js reprocessFountainAtCoords: Error collecting OSM data: ${JSON.stringify(e)} `);
// // TODO @ralfhauser, this is an ugly side effect, this does nost stop the program but implies return void
// // hence I changed it because we already catch errors in Promise.all
// // res.status(500).send(e.stack);
// throw e;
// });

// const wikidataPromise = WikidataService
// // Fetch all wikidata items within radius
// .idsByCenter(lat, lng, radius, dbg)
// // Fetch detailed information for fountains based on wikidata ids
// .then(r => WikidataService.byIds(r, dbg))
// .catch(e => {
// l.error(`Error collecting Wikidata data: ${e}`);
// // TODO @ralfhauser, same same as above
// // res.status(500).send(e.stack);
// throw e;
// });
// const debugAll = true;
// // When both OSM and Wikidata data have been collected, continue with joint processing
// Promise.all([osmPromise, wikidataPromise])

// // Get any missing wikidata fountains for #212 (fountains not fetched from Wikidata because not listed as fountains, but referenced by fountains of OSM)
// .then(r => fillInMissingWikidataFountains(r[0], r[1], dbg))

// // Conflate osm and wikidata fountains together
// .then(r =>
// conflate(
// {
// osm: r.osm,
// wikidata: r.wikidata,
// },
// dbg,
// debugAll
// )
// )

// // return only the fountain that is closest to the coordinates of the query
// .then(r => {
// const distances = _.map(r, f => {
// // compute distance to center for each fountain
// return haversine(f.geometry.coordinates, [lng, lat], {
// unit: 'meter',
// format: '[lon,lat]',
// });
// });
// // return closest
// const closest = r[_.indexOf(distances, _.min(distances))];
// return [closest];
// })

// // fetch more information about fountains (Artist information, gallery, etc.)
// //TOOD @ralfhauser, the last parameter for debugAll was missing undefined is falsy hence I used false
// .then(r => defaultCollectionEnhancement(r, dbg, false))

// // Update cache with newly processed fountain
// .then(r => {
// const city = getSingleStringQueryParam(req, 'city');
// const closest = updateCacheWithFountain(cityCache, r[0], city);
// sendJson(res, closest, 'after updateCacheWithFountain');
// })
// .catch(e => {
// l.error(`Error collecting data: ${e.stack}`);
// res.status(500).send(e.stack);
// });
// }

export function generateLocationDataAndCache(key: string, cityCache: NodeCache): Promise<FountainCollection | void> {
// trigger a reprocessing of the location's data, based on the key.
Expand Down
2 changes: 1 addition & 1 deletion server/api/controllers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ function getSingleQueryParam<T>(req: Request, paramName: string, isOptional: boo
// looks like we sometimes get numbers or booleans and not string even though query[x] does not include it in its type signature
if (typeof v === type) return v as unknown as T;
else if (v === undefined && isOptional) return undefined;
else throw Error(`${paramName} is not a single parameter, was ${JSON.stringify(v)} ${typeof v}`);
else throw Error(`${paramName} is not a single parameter, was ${JSON.stringify(v)} with type ${typeof v}`);
}
8 changes: 4 additions & 4 deletions server/common/build.info.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// this file is automatically generated by git.version.js script
const buildInfo = {
version: '',
revision: 'c6dfade',
branch: 'develop',
commit_time: '2021-10-27 08:30:58 +0000',
build_time: 'Fri Dec 17 2021 23:35:27 GMT+0100 (Central European Standard Time)',
revision: 'de728a0',
branch: '#147-remove-deprecated-byCoords',
commit_time: '2021-12-17 23:49:37 +0100',
build_time: 'Mon Dec 20 2021 08:44:55 GMT+0100 (Central European Standard Time)',
};
export default buildInfo;
Loading

0 comments on commit 81aecf3

Please sign in to comment.