mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Refactoring
This commit is contained in:
parent
ced8bd78bb
commit
887cc8fddf
14
src/helpers/asyncForEach.js
Normal file
14
src/helpers/asyncForEach.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Provide a way to iterate for each element in an array while waiting for async functions to finish
|
||||
*
|
||||
* @param array
|
||||
* @param callback
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function asyncForEach (array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array)
|
||||
}
|
||||
}
|
||||
|
||||
export default asyncForEach
|
||||
124
src/middleware/nodes/locations.js
Normal file
124
src/middleware/nodes/locations.js
Normal file
@ -0,0 +1,124 @@
|
||||
|
||||
import request from 'request'
|
||||
import { UserInputError } from 'apollo-server'
|
||||
import isEmpty from 'lodash/isEmpty'
|
||||
import asyncForEach from '../../helpers/asyncForEach'
|
||||
|
||||
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'
|
||||
]
|
||||
|
||||
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,
|
||||
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 query = '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.type = $type'
|
||||
|
||||
if (data.lat && data.lng) {
|
||||
query += ', l.lat = $lat, l.lng = $lng'
|
||||
}
|
||||
query += ' RETURN l.id'
|
||||
|
||||
await session.run(query, data)
|
||||
}
|
||||
|
||||
const createOrUpdateLocations = async (userId, locationName, driver) => {
|
||||
if (isEmpty(locationName)) {
|
||||
return
|
||||
}
|
||||
const mapboxToken = process.env.MAPBOX_TOKEN
|
||||
const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=${locales.join(',')}`)
|
||||
|
||||
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()
|
||||
await createLocation(session, data)
|
||||
|
||||
let parent = data
|
||||
|
||||
if (data.context) {
|
||||
await asyncForEach(data.context, async ctx => {
|
||||
await createLocation(session, ctx)
|
||||
|
||||
await session.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
|
||||
})
|
||||
}
|
||||
// delete all current locations from user
|
||||
await session.run('MATCH (u:User {id: $userId})-[r:IS_IN]->(l:Location) DETACH DELETE r', {
|
||||
userId: userId
|
||||
})
|
||||
// connect user with location
|
||||
await session.run('MATCH (u:User {id: $userId}), (l:Location {id: $locationId}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id', {
|
||||
userId: userId,
|
||||
locationId: data.id
|
||||
})
|
||||
session.close()
|
||||
}
|
||||
|
||||
export default createOrUpdateLocations
|
||||
@ -1,5 +1,5 @@
|
||||
import bcrypt from 'bcryptjs'
|
||||
import walkRecursive from './helpers/walkRecursive'
|
||||
import walkRecursive from '../helpers/walkRecursive'
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
|
||||
@ -1,136 +1,4 @@
|
||||
import request from 'request'
|
||||
import { UserInputError } from 'apollo-server'
|
||||
import isEmpty from 'lodash/isEmpty'
|
||||
|
||||
const asyncForEach = async (array, callback) => {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array)
|
||||
}
|
||||
}
|
||||
|
||||
const fetch = url => {
|
||||
return new Promise((resolve, reject) => {
|
||||
request(url, function (error, response, body) {
|
||||
if (error) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(JSON.parse(body))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const createOrUpdateLocations = async (userId, locationName, driver) => {
|
||||
if (isEmpty(locationName)) {
|
||||
return
|
||||
}
|
||||
const mapboxToken = process.env.MAPBOX_TOKEN
|
||||
const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=en,de,fr,nl,it,es,pt,pl`)
|
||||
|
||||
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) {
|
||||
throw new UserInputError('locationName is invalid')
|
||||
}
|
||||
|
||||
const session = driver.session()
|
||||
await session.run(
|
||||
'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.type = $type, ' +
|
||||
'l.lat = $lat, ' +
|
||||
'l.lng = $lng ' +
|
||||
'RETURN l.id', {
|
||||
id: data.id,
|
||||
nameEN: data.text_en,
|
||||
nameDE: data.text_de,
|
||||
nameFR: data.text_fr,
|
||||
nameNL: data.text_nl,
|
||||
nameIT: data.text_it,
|
||||
nameES: data.text_es,
|
||||
namePT: data.text_pt,
|
||||
namePL: data.text_pl,
|
||||
type: data.place_type[0].toLowerCase(),
|
||||
lat: data.center[0],
|
||||
lng: data.center[1]
|
||||
}
|
||||
)
|
||||
|
||||
let parent = data
|
||||
|
||||
if (data.context) {
|
||||
await asyncForEach(data.context, async ctx => {
|
||||
const type = ctx.id.split('.')[0].toLowerCase()
|
||||
await session.run(
|
||||
'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.type = $type, ' +
|
||||
'l.shortCode = $shortCode ' +
|
||||
'RETURN l.id', {
|
||||
id: ctx.id,
|
||||
nameEN: ctx.text_en,
|
||||
nameDE: ctx.text_de,
|
||||
nameFR: ctx.text_fr,
|
||||
nameNL: ctx.text_nl,
|
||||
nameIT: ctx.text_it,
|
||||
nameES: ctx.text_es,
|
||||
namePT: ctx.text_pt,
|
||||
namePL: ctx.text_pl,
|
||||
type: type,
|
||||
shortCode: ctx.short_code
|
||||
}
|
||||
)
|
||||
await session.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
|
||||
})
|
||||
}
|
||||
// delete all current locations from user
|
||||
await session.run('MATCH (u:User {id: $userId})-[r:IS_IN]->(l:Location) DETACH DELETE r', {
|
||||
userId: userId
|
||||
})
|
||||
// connect user with location
|
||||
await session.run('MATCH (u:User {id: $userId}), (l:Location {id: $locationId}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id', {
|
||||
userId: userId,
|
||||
locationId: data.id
|
||||
})
|
||||
session.close()
|
||||
}
|
||||
import createOrUpdateLocations from './nodes/locations'
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import walkRecursive from './helpers/walkRecursive'
|
||||
import walkRecursive from '../helpers/walkRecursive'
|
||||
// import { getByDot, setByDot, getItems, replaceItems } from 'feathers-hooks-common'
|
||||
import sanitizeHtml from 'sanitize-html'
|
||||
// import { isEmpty, intersection } from 'lodash'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import gql from 'graphql-tag'
|
||||
import helper from '../seed-helpers'
|
||||
import asyncForEach from '../../helpers/asyncForEach'
|
||||
|
||||
const seed = {
|
||||
Badge: require('./badges.js').default,
|
||||
@ -22,7 +22,7 @@ let data = {}
|
||||
|
||||
export default async function (client) {
|
||||
// iterate through seeds
|
||||
await helper.asyncForEach(Object.keys(seed), async key => {
|
||||
await asyncForEach(Object.keys(seed), async key => {
|
||||
const mutations = seed[key]
|
||||
try {
|
||||
const res = await client
|
||||
|
||||
@ -46,7 +46,7 @@ export default {
|
||||
let randomIds = _.shuffle(ids)
|
||||
return items[randomIds.pop()]
|
||||
},
|
||||
randomItems: (items, key = '_id', min = 1, max = 1) => {
|
||||
randomItems: (items, key = 'id', min = 1, max = 1) => {
|
||||
let randomIds = _.shuffle(_.keys(items))
|
||||
let res = []
|
||||
|
||||
@ -54,7 +54,7 @@ export default {
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
let r = items[randomIds.pop()][key]
|
||||
if (key === '_id') {
|
||||
if (key === 'id') {
|
||||
r = r.toString()
|
||||
}
|
||||
res.push(r)
|
||||
@ -117,22 +117,10 @@ export default {
|
||||
mapIdsByKey: (items, values, key) => {
|
||||
let res = []
|
||||
values.forEach(value => {
|
||||
res.push(_.find(items, [key, value])._id.toString())
|
||||
res.push(_.find(items, [key, value]).id.toString())
|
||||
})
|
||||
return res
|
||||
},
|
||||
/**
|
||||
* Provide a way to iterate for each element in an array while waiting for async functions to finish
|
||||
*
|
||||
* @param array
|
||||
* @param callback
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
asyncForEach: async (array, callback) => {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array)
|
||||
}
|
||||
},
|
||||
genInviteCode: () => {
|
||||
const chars = '23456789abcdefghkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ'
|
||||
let code = ''
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user