mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
- write tests for userMiddleware - checks the functionality of nodes/locations middleware - refactor to not allow users to update to remove their name debatable whether we want that or not, but we do not allow users to create accounts with no name, so we should be consistent, before we were using neode to validate this, but we have are removing neode from production code, so we must validate ourselves - collate UpdateUser mutations to one
154 lines
3.9 KiB
JavaScript
154 lines
3.9 KiB
JavaScript
import request from 'request'
|
|
import { UserInputError } from 'apollo-server'
|
|
import isEmpty from 'lodash/isEmpty'
|
|
import Debug from 'debug'
|
|
import asyncForEach from '../../helpers/asyncForEach'
|
|
import CONFIG from './../../config'
|
|
|
|
const debug = Debug('human-connection:location')
|
|
|
|
const fetch = url => {
|
|
return new Promise((resolve, reject) => {
|
|
request(url, function(error, response, body) {
|
|
if (error) {
|
|
reject(error)
|
|
} else {
|
|
resolve(JSON.parse(body))
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const locales = ['en', 'de', 'fr', 'nl', 'it', 'es', 'pt', 'pl', 'ru']
|
|
|
|
const createLocation = async (session, mapboxData) => {
|
|
const data = {
|
|
id: mapboxData.id,
|
|
nameEN: mapboxData.text_en,
|
|
nameDE: mapboxData.text_de,
|
|
nameFR: mapboxData.text_fr,
|
|
nameNL: mapboxData.text_nl,
|
|
nameIT: mapboxData.text_it,
|
|
nameES: mapboxData.text_es,
|
|
namePT: mapboxData.text_pt,
|
|
namePL: mapboxData.text_pl,
|
|
nameRU: mapboxData.text_ru,
|
|
type: mapboxData.id.split('.')[0].toLowerCase(),
|
|
lat: mapboxData.center && mapboxData.center.length ? mapboxData.center[0] : null,
|
|
lng: mapboxData.center && mapboxData.center.length ? mapboxData.center[1] : null,
|
|
}
|
|
|
|
let mutation =
|
|
'MERGE (l:Location {id: $id}) ' +
|
|
'SET l.name = $nameEN, ' +
|
|
'l.nameEN = $nameEN, ' +
|
|
'l.nameDE = $nameDE, ' +
|
|
'l.nameFR = $nameFR, ' +
|
|
'l.nameNL = $nameNL, ' +
|
|
'l.nameIT = $nameIT, ' +
|
|
'l.nameES = $nameES, ' +
|
|
'l.namePT = $namePT, ' +
|
|
'l.namePL = $namePL, ' +
|
|
'l.nameRU = $nameRU, ' +
|
|
'l.type = $type'
|
|
|
|
if (data.lat && data.lng) {
|
|
mutation += ', l.lat = $lat, l.lng = $lng'
|
|
}
|
|
mutation += ' RETURN l.id'
|
|
|
|
try {
|
|
await session.writeTransaction(transaction => {
|
|
return transaction.run(mutation, data)
|
|
})
|
|
} finally {
|
|
session.close()
|
|
}
|
|
}
|
|
|
|
const createOrUpdateLocations = async (userId, locationName, driver) => {
|
|
if (isEmpty(locationName)) {
|
|
return
|
|
}
|
|
const res = await fetch(
|
|
`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(
|
|
locationName,
|
|
)}.json?access_token=${CONFIG.MAPBOX_TOKEN}&types=region,place,country&language=${locales.join(
|
|
',',
|
|
)}`,
|
|
)
|
|
|
|
debug(res)
|
|
|
|
if (!res || !res.features || !res.features[0]) {
|
|
throw new UserInputError('locationName is invalid')
|
|
}
|
|
|
|
let data
|
|
|
|
res.features.forEach(item => {
|
|
if (item.matching_place_name === locationName) {
|
|
data = item
|
|
}
|
|
})
|
|
if (!data) {
|
|
data = res.features[0]
|
|
}
|
|
|
|
if (!data || !data.place_type || !data.place_type.length) {
|
|
throw new UserInputError('locationName is invalid')
|
|
}
|
|
|
|
const session = driver.session()
|
|
if (data.place_type.length > 1) {
|
|
data.id = 'region.' + data.id.split('.')[1]
|
|
}
|
|
await createLocation(session, data)
|
|
|
|
let parent = data
|
|
|
|
if (data.context) {
|
|
await asyncForEach(data.context, async ctx => {
|
|
await createLocation(session, ctx)
|
|
try {
|
|
await session.writeTransaction(transaction => {
|
|
return transaction.run(
|
|
`
|
|
MATCH (parent:Location {id: $parentId}), (child:Location {id: $childId})
|
|
MERGE (child)<-[:IS_IN]-(parent)
|
|
RETURN child.id, parent.id
|
|
`,
|
|
{
|
|
parentId: parent.id,
|
|
childId: ctx.id,
|
|
},
|
|
)
|
|
})
|
|
parent = ctx
|
|
} finally {
|
|
session.close()
|
|
}
|
|
})
|
|
}
|
|
// delete all current locations from user and add new location
|
|
try {
|
|
await session.writeTransaction(transaction => {
|
|
return transaction.run(
|
|
`
|
|
MATCH (user:User {id: $userId})-[relationship:IS_IN]->(location:Location)
|
|
DETACH DELETE relationship
|
|
WITH user
|
|
MATCH (location:Location {id: $locationId})
|
|
MERGE (user)-[:IS_IN]->(location)
|
|
RETURN location.id, user.id
|
|
`,
|
|
{ userId: userId, locationId: data.id },
|
|
)
|
|
})
|
|
} finally {
|
|
session.close()
|
|
}
|
|
}
|
|
|
|
export default createOrUpdateLocations
|