You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
9.3 KiB
JavaScript
213 lines
9.3 KiB
JavaScript
5 years ago
|
const config = require('../config')
|
||
|
|
||
|
const express = require('../node_modules/express')
|
||
|
const bodyParser = require('../node_modules/body-parser')
|
||
|
// MCD API
|
||
|
const rqt = require('../node_modules/rqt')
|
||
|
const MCDSession = new rqt.Session({
|
||
|
host: config.mcdEndpointLegacy,
|
||
|
headers: config.mcdHeadersLegacy,
|
||
|
})
|
||
|
const querystring = require('../node_modules/querystring')
|
||
|
|
||
|
const microService = express()
|
||
|
microService.use(bodyParser.json(true))
|
||
|
// MongoDB
|
||
|
const { mongoose, Models } = require('../database')
|
||
|
|
||
|
const ortSuche = (query) => {
|
||
|
return rqt('https://nominatim.openstreetmap.org/search?format=json&q=' + encodeURIComponent(query + ', Deutschland'))
|
||
|
}
|
||
|
const ortSucheGoogle = async (query) => {
|
||
|
return rqt.jqt('https://maps.googleapis.com/maps/api/place/textsearch/json?' + querystring.stringify({
|
||
|
key: config.storeFinder.googlePlacesKey,
|
||
|
query: query,
|
||
|
}))
|
||
|
}
|
||
|
|
||
|
microService
|
||
|
.post('/fillialsuche', async (req, res) => {
|
||
|
let lon, lat, searchfield, place_id
|
||
|
let correlationQuery = {}
|
||
|
|
||
|
if (!!req.body.query) {
|
||
|
let query = req.body.query.toString()
|
||
|
console.log('Searching with Query')
|
||
|
if (await Models.GoogleCacheResult.count({ query }) === 0) {
|
||
|
let orte = await ortSucheGoogle(query)
|
||
|
orte = orte.results
|
||
|
if (orte.length > 0) {
|
||
|
/*orte = orte.sort((a,b) => {
|
||
|
a = a.importance * (a.type === 'city' ? 2 : 1)
|
||
|
b = b.importance * (b.type === 'city' ? 2 : 1)
|
||
|
return a > b
|
||
|
})*/
|
||
|
const ort = orte[0]
|
||
|
lon = parseFloat(ort.geometry.location.lng)
|
||
|
lat = parseFloat(ort.geometry.location.lat)
|
||
|
searchfield = ort.name
|
||
|
place_id = ort.place_id
|
||
|
correlationQuery = {
|
||
|
place_id: ort.place_id,
|
||
|
longitude: lon,
|
||
|
latitude: lat,
|
||
|
}
|
||
|
await Models.GoogleCacheResult.create({
|
||
|
query,
|
||
|
name: searchfield,
|
||
|
place_id: place_id,
|
||
|
longitude: lon,
|
||
|
latitude: lat,
|
||
|
})
|
||
|
console.log('Google Result', lon, lat, searchfield, place_id)
|
||
|
} else {
|
||
|
console.log('Keine Orte von #1 gefunden')
|
||
|
return res.status(400).json('Keine Orte gefunden')
|
||
|
}
|
||
|
} else {
|
||
|
let cachedResult = await Models.GoogleCacheResult.findOne({ query })
|
||
|
lon = cachedResult.longitude
|
||
|
lat = cachedResult.latitude
|
||
|
searchfield = cachedResult.name
|
||
|
place_id = cachedResult.place_id
|
||
|
correlationQuery = {
|
||
|
place_id: place_id,
|
||
|
longitude: lon,
|
||
|
latitude: lat,
|
||
|
}
|
||
|
console.log('Cache Result', lon, lat, searchfield, place_id)
|
||
|
|
||
|
}
|
||
|
} else if (!!req.body.lat) {
|
||
|
console.log('Searching with Location', req.body)
|
||
|
lon = parseFloat(req.body.lon)
|
||
|
lat = parseFloat(req.body.lat)
|
||
|
correlationQuery = {
|
||
|
longitude: parseInt(lon * 10000) / 10000,
|
||
|
latitude: parseInt(lat * 10000) / 10000,
|
||
|
}
|
||
|
searchfield = ''
|
||
|
place_id = false
|
||
|
} else {
|
||
|
console.log('Invalid Search')
|
||
|
return res.status(400).json(false)
|
||
|
}
|
||
|
|
||
|
let restaurants = []
|
||
|
if (!!correlationQuery) {
|
||
|
let correlationCount = await Models.StoreFinderCorrelation.count(correlationQuery)
|
||
|
console.log('correlationCount', correlationCount)
|
||
|
if (correlationCount === 0) {
|
||
|
console.log('No Correlations found, asking API')
|
||
|
console.time('MCD Search')
|
||
|
const restaurants = await rqt.jqt('https://www.mcdonalds.de/search', {
|
||
|
method: 'POST',
|
||
|
type: 'application/x-www-form-urlencoded; charset=UTF-8',
|
||
|
data: querystring.stringify({
|
||
|
longitude: lon,
|
||
|
latitude: lat,
|
||
|
searchfield: searchfield,
|
||
|
radius: 12, // 12km umkreis suche
|
||
|
coupon: true,
|
||
|
}),
|
||
|
timeout: 6000,
|
||
|
})
|
||
|
.then(($res) => {
|
||
|
if ($res.unfilteredCount === 0) throw 'Keine Restaurants gefunden'
|
||
|
$res.restaurantList = $res.restaurantList.sort((a, b) => a.distance - b.distance)
|
||
|
return $res.restaurantList.map((entry) => {
|
||
|
return entry.restaurant
|
||
|
})
|
||
|
})
|
||
|
.then(async ($res) => {
|
||
|
console.log('retaurants', $res)
|
||
|
let restaurants = []
|
||
|
for (let restaurant of $res) {
|
||
|
let seoCount = await Models.Store.count({ seoURL: restaurant.seoURL })
|
||
|
if (seoCount == 0) {
|
||
|
let ecpStore = await MCDSession.jqt('/v3/restaurant/location?' + querystring.stringify({
|
||
|
filter: 'search',
|
||
|
query: JSON.stringify({
|
||
|
market: 'DE',
|
||
|
pageSize: 1,
|
||
|
local: 'de-DE',
|
||
|
generalStoreStatusCode: 'OPEN,TEMPCLOSE,RENOVATION',
|
||
|
locationCriteria: {
|
||
|
longitude: lon,
|
||
|
latitude: lat,
|
||
|
distance: 22000
|
||
|
}
|
||
|
}),
|
||
|
}), { method: 'GET', type: 'json', })
|
||
|
if (ecpStore.length === 0) continue; // Skip Restaurants, we dont have the ECPId for
|
||
|
console.log(ecpStore)
|
||
|
ecpStore = ecpStore[0]
|
||
|
if (ecpStore.identifiers.storeIdentifier.filter((a) => a.identifierType == 'ECPID').length == 0) continue
|
||
|
|
||
|
await Models.Store.create({
|
||
|
id: restaurant.id,
|
||
|
externalId: restaurant.externalId,
|
||
|
|
||
|
storeId: ecpStore.id,
|
||
|
storeECPId: ecpStore.identifiers.storeIdentifier.filter((a) => a.identifierType == 'ECPID')[0].identifierValue,
|
||
|
|
||
|
latitude: restaurant.latitude,
|
||
|
longitude: restaurant.longitude,
|
||
|
|
||
|
city: restaurant.city,
|
||
|
postalCode: restaurant.postalCode,
|
||
|
address: restaurant.address,
|
||
|
street: restaurant.street,
|
||
|
phone: restaurant.phone,
|
||
|
seoURL: restaurant.seoURL,
|
||
|
name1: restaurant.name1,
|
||
|
name2: restaurant.name2,
|
||
|
|
||
|
lastRefresh: new Date(),
|
||
|
})
|
||
|
}
|
||
|
let dbRestaurant = await Models.Store.findOne({ seoURL: restaurant.seoURL })
|
||
|
restaurants.push(dbRestaurant)
|
||
|
}
|
||
|
console.timeEnd('MCD Search')
|
||
|
return restaurants
|
||
|
})
|
||
|
.catch(($err) => {
|
||
|
console.timeEnd('MCD Search')
|
||
|
console.error($err)
|
||
|
return false
|
||
|
})
|
||
|
if (!!restaurants) {
|
||
|
for (let restaurant of restaurants) {
|
||
|
if (await Models.StoreFinderCorrelation.count({
|
||
|
...correlationQuery,
|
||
|
store: restaurant._id,
|
||
|
}) === 0) {
|
||
|
await Models.StoreFinderCorrelation.create({
|
||
|
...correlationQuery,
|
||
|
store: restaurant._id,
|
||
|
lastRefresh: new Date(),
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
return res.json(restaurants)
|
||
|
} else {
|
||
|
return res.json(false)
|
||
|
}
|
||
|
} else {
|
||
|
console.time('Correlation Search')
|
||
|
console.log('Correlations found, returning them...')
|
||
|
let restaurantsDB = await Models.StoreFinderCorrelation
|
||
|
.find(correlationQuery)
|
||
|
.select('store')
|
||
|
.populate('store');
|
||
|
restaurants = restaurantsDB.map(corr => corr.store)
|
||
|
console.timeEnd('Correlation Search')
|
||
|
return res.json(restaurants)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return res.json(false)
|
||
|
})
|
||
|
|
||
|
microService.listen(config.storeFinder.port, config.storeFinder.host)
|