mirror of
https://framagit.org/les/gancio.git
synced 2025-01-31 16:42:22 +01:00
new events fetch methods
This commit is contained in:
parent
e0b3dd8d4a
commit
3a698903f6
2 changed files with 197 additions and 151 deletions
|
@ -1,7 +1,7 @@
|
|||
const crypto = require('crypto')
|
||||
const moment = require('moment-timezone')
|
||||
const { Op } = require('sequelize')
|
||||
const lodash = require('lodash')
|
||||
const _ = require('lodash')
|
||||
const { event: Event, resource: Resource, tag: Tag, place: Place, notification: Notification } = require('../models')
|
||||
const Sequelize = require('sequelize')
|
||||
const exportController = require('./export')
|
||||
|
@ -30,7 +30,7 @@ const eventController = {
|
|||
order: [[Sequelize.literal('weigth'), 'DESC']],
|
||||
attributes: {
|
||||
include: [[Sequelize.fn('count', Sequelize.col('events.placeId')), 'weigth']],
|
||||
exclude: ['weigth', 'createdAt', 'updatedAt']
|
||||
exclude: ['createdAt', 'updatedAt']
|
||||
},
|
||||
include: [{ model: Event, attributes: [] }],
|
||||
group: ['place.id']
|
||||
|
@ -40,11 +40,11 @@ const eventController = {
|
|||
raw: true,
|
||||
order: [['weigth', 'DESC']],
|
||||
attributes: {
|
||||
exclude: ['createdAt', 'updatedAt', 'weigth']
|
||||
exclude: ['createdAt', 'updatedAt']
|
||||
}
|
||||
})
|
||||
|
||||
res.json({ tags: tags.map(t => t.tag), places })
|
||||
res.json({ tags, places })
|
||||
},
|
||||
|
||||
async getNotifications (event, action) {
|
||||
|
@ -59,7 +59,7 @@ const eventController = {
|
|||
if (!filters.tags && !filters.places) { return true }
|
||||
if (!filters.tags.length && !filters.places.length) { return true }
|
||||
if (filters.tags.length) {
|
||||
const m = lodash.intersection(event.tags.map(t => t.tag), filters.tags)
|
||||
const m = _.intersection(event.tags.map(t => t.tag), filters.tags)
|
||||
if (m.length > 0) { return true }
|
||||
}
|
||||
if (filters.places.length) {
|
||||
|
@ -69,7 +69,7 @@ const eventController = {
|
|||
}
|
||||
}
|
||||
|
||||
const notifications = await Notification.findAll({ where: { action }, include: [ Event ] })
|
||||
const notifications = await Notification.findAll({ where: { action }, include: [Event] })
|
||||
|
||||
// get notification that matches with selected event
|
||||
const ret = notifications.filter(notification => match(event, notification.filters))
|
||||
|
@ -197,28 +197,121 @@ const eventController = {
|
|||
res.sendStatus(200)
|
||||
},
|
||||
|
||||
async addRecurrent (start, places, where_tags, limit) {
|
||||
const where = {
|
||||
is_visible: true,
|
||||
recurrent: { [Op.ne]: null }
|
||||
// placeId: places
|
||||
}
|
||||
|
||||
const events = await Event.findAll({
|
||||
where,
|
||||
limit,
|
||||
attributes: {
|
||||
exclude: ['slug', 'likes', 'boost', 'userId', 'is_visible', 'description', 'createdAt', 'updatedAt', 'placeId']
|
||||
},
|
||||
order: ['start_datetime', [Tag, 'weigth', 'DESC']],
|
||||
include: [
|
||||
{ model: Resource, required: false, attributes: ['id'] },
|
||||
{ model: Tag, ...where_tags, attributes: ['tag'], through: { attributes: [] } },
|
||||
{ model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
||||
]
|
||||
})
|
||||
|
||||
debug(`Found ${events.length} recurrent events`)
|
||||
let allEvents = []
|
||||
_.forEach(events, e => {
|
||||
allEvents = allEvents.concat(eventController.createEventsFromRecurrent(e.get(), start))
|
||||
})
|
||||
|
||||
debug(`Created ${allEvents.length} events`)
|
||||
return allEvents
|
||||
},
|
||||
|
||||
// build singular events from a recurrent pattern
|
||||
createEventsFromRecurrent (e, start, dueTo = null) {
|
||||
const events = []
|
||||
const recurrent = JSON.parse(e.recurrent)
|
||||
if (!recurrent.frequency) { return false }
|
||||
if (!dueTo) {
|
||||
dueTo = moment.unix(start).add(2, 'month')
|
||||
}
|
||||
let cursor = moment.unix(start).startOf('week')
|
||||
const start_date = moment.unix(e.start_datetime)
|
||||
const duration = moment.unix(e.end_datetime).diff(start_date, 's')
|
||||
const frequency = recurrent.frequency
|
||||
const days = recurrent.days
|
||||
const type = recurrent.type
|
||||
|
||||
// default frequency is '1d' => each day
|
||||
const toAdd = { n: 1, unit: 'day' }
|
||||
|
||||
// each week or 2 (search for the first specified day)
|
||||
if (frequency === '1w' || frequency === '2w') {
|
||||
cursor.add(days[0] - 1, 'day')
|
||||
if (frequency === '2w') {
|
||||
const nWeeks = cursor.diff(e.start_datetime, 'w') % 2
|
||||
if (!nWeeks) { cursor.add(1, 'week') }
|
||||
}
|
||||
toAdd.n = Number(frequency[0])
|
||||
toAdd.unit = 'week'
|
||||
// cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||
}
|
||||
|
||||
cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||
|
||||
// each month or 2
|
||||
if (frequency === '1m' || frequency === '2m') {
|
||||
// find first match
|
||||
toAdd.n = 1
|
||||
toAdd.unit = 'month'
|
||||
if (type === 'weekday') {
|
||||
|
||||
} else if (type === 'ordinal') {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// add event at specified frequency
|
||||
while (true) {
|
||||
const first_event_of_week = cursor.clone()
|
||||
days.forEach(d => {
|
||||
if (type === 'ordinal') {
|
||||
cursor.date(d)
|
||||
} else {
|
||||
cursor.day(d - 1)
|
||||
}
|
||||
if (cursor.isAfter(dueTo) || cursor.isBefore(start)) { return }
|
||||
e.start_datetime = cursor.unix()
|
||||
e.end_datetime = e.start_datetime + duration
|
||||
events.push(Object.assign({}, e))
|
||||
})
|
||||
if (cursor.isAfter(dueTo)) { break }
|
||||
cursor = first_event_of_week.add(toAdd.n, toAdd.unit)
|
||||
cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||
}
|
||||
|
||||
return events
|
||||
},
|
||||
|
||||
/**
|
||||
* Select events based on params
|
||||
*/
|
||||
async select (req, res) {
|
||||
const start = req.query.start || 0
|
||||
const limit = req.query.limit
|
||||
const show_recurrent = req.query.show_recurrent || false
|
||||
const start = req.query.start || moment().unix()
|
||||
const limit = req.query.limit || 100
|
||||
const show_recurrent = req.query.show_recurrent || true
|
||||
const filter_tags = req.query.tags || ''
|
||||
const filter_places = req.query.places || ''
|
||||
|
||||
let where = {}
|
||||
debug(`select limit:${limit} rec:${show_recurrent} tags:${filter_tags} places:${filter_places}`)
|
||||
let where_tags = {}
|
||||
if (show_recurrent) {
|
||||
where = {
|
||||
[Op.or]: [
|
||||
{ recurrent: { [Op.ne]: null } },
|
||||
{ start_datetime: { [Op.gt]: start }}
|
||||
]
|
||||
}
|
||||
} else {
|
||||
where = {
|
||||
start_datetime: { [Op.gt]: start }
|
||||
}
|
||||
const where = {
|
||||
// confirmed event only
|
||||
is_visible: true,
|
||||
start_datetime: { [Op.gt]: start },
|
||||
recurrent: null
|
||||
}
|
||||
where.is_visible = true
|
||||
|
||||
if (filter_tags) {
|
||||
where_tags = { where: { tag: filter_tags.split(',') } }
|
||||
|
@ -232,139 +325,86 @@ const eventController = {
|
|||
where,
|
||||
limit,
|
||||
attributes: {
|
||||
exclude: ['slug', 'likes', 'boost', 'userId', 'is_visible', 'description', 'createdAt', 'updatedAt', 'placeId'],
|
||||
exclude: ['slug', 'likes', 'boost', 'userId', 'is_visible', 'description', 'createdAt', 'updatedAt', 'placeId']
|
||||
// include: [[Sequelize.fn('COUNT', Sequelize.col('activitypub_id')), 'ressources']]
|
||||
},
|
||||
order: ['start_datetime', [Tag, 'weigth', 'DESC']],
|
||||
include: [
|
||||
{ model: Resource, required: false, attributes: ['id'] },
|
||||
{ model: Tag, ...where_tags, attributes: ['tag'], through: { attributes: [] },},
|
||||
{ model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
||||
],
|
||||
})
|
||||
events = events.map(e => e.get()).map(e => {
|
||||
e.tags = e.tags.map(t => t.tag)
|
||||
return e
|
||||
})
|
||||
|
||||
res.json(events)
|
||||
},
|
||||
async getAll (req, res) {
|
||||
// this is due how v-calendar shows dates
|
||||
const start = moment()
|
||||
.year(req.params.year)
|
||||
.month(req.params.month)
|
||||
.startOf('month')
|
||||
.startOf('week')
|
||||
|
||||
let end = moment()
|
||||
.year(req.params.year)
|
||||
.month(req.params.month)
|
||||
.endOf('month')
|
||||
|
||||
const shownDays = end.diff(start, 'days')
|
||||
if (shownDays <= 35) { end = end.add(1, 'week') }
|
||||
end = end.endOf('week')
|
||||
|
||||
let events = await Event.findAll({
|
||||
where: {
|
||||
// return only confirmed events
|
||||
is_visible: true,
|
||||
[Op.or]: [
|
||||
// return all recurrent events regardless start_datetime
|
||||
{ recurrent: { [Op.ne]: null } },
|
||||
|
||||
// and events in specified range
|
||||
{ start_datetime: { [Op.between]: [start.unix(), end.unix()] } }
|
||||
]
|
||||
},
|
||||
attributes: { exclude: [ 'createdAt', 'updatedAt', 'placeId' ] },
|
||||
order: [[Tag, 'weigth', 'DESC']],
|
||||
include: [
|
||||
{ model: Resource, required: false, attributes: ['id'] },
|
||||
{ model: Tag, required: false },
|
||||
{ model: Tag, ...where_tags, attributes: ['tag'], through: { attributes: [] } },
|
||||
{ model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
||||
]
|
||||
})
|
||||
events = events.map(e => e.get()).map(e => {
|
||||
|
||||
let recurrentEvents = []
|
||||
events = _.map(events, e => e.get())
|
||||
if (show_recurrent) {
|
||||
recurrentEvents = await eventController.addRecurrent(start, where.placeId, where_tags, limit)
|
||||
events = _.concat(events, recurrentEvents)
|
||||
}
|
||||
|
||||
// flat tags
|
||||
events = _(events).map(e => {
|
||||
e.tags = e.tags.map(t => t.tag)
|
||||
return e
|
||||
})
|
||||
|
||||
// build singular events from a recurrent pattern
|
||||
function createEventsFromRecurrent (e, dueTo = null) {
|
||||
const events = []
|
||||
const recurrent = JSON.parse(e.recurrent)
|
||||
if (!recurrent.frequency) { return false }
|
||||
|
||||
let cursor = moment(start).startOf('week')
|
||||
const start_date = moment.unix(e.start_datetime)
|
||||
const duration = moment.unix(e.end_datetime).diff(start_date, 's')
|
||||
const frequency = recurrent.frequency
|
||||
const days = recurrent.days
|
||||
const type = recurrent.type
|
||||
|
||||
// default frequency is '1d' => each day
|
||||
const toAdd = { n: 1, unit: 'day' }
|
||||
|
||||
// each week or 2 (search for the first specified day)
|
||||
if (frequency === '1w' || frequency === '2w') {
|
||||
cursor.add(days[0] - 1, 'day')
|
||||
if (frequency === '2w') {
|
||||
const nWeeks = cursor.diff(e.start_datetime, 'w') % 2
|
||||
if (!nWeeks) { cursor.add(1, 'week') }
|
||||
}
|
||||
toAdd.n = Number(frequency[0])
|
||||
toAdd.unit = 'week'
|
||||
// cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||
}
|
||||
|
||||
cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||
|
||||
// each month or 2
|
||||
if (frequency === '1m' || frequency === '2m') {
|
||||
// find first match
|
||||
toAdd.n = 1
|
||||
toAdd.unit = 'month'
|
||||
if (type === 'weekday') {
|
||||
|
||||
} else if (type === 'ordinal') {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// add event at specified frequency
|
||||
while (true) {
|
||||
const first_event_of_week = cursor.clone()
|
||||
days.forEach(d => {
|
||||
if (type === 'ordinal') {
|
||||
cursor.date(d)
|
||||
} else {
|
||||
cursor.day(d - 1)
|
||||
}
|
||||
if (cursor.isAfter(dueTo) || cursor.isBefore(start)) { return }
|
||||
e.start_datetime = cursor.unix()
|
||||
e.end_datetime = e.start_datetime + duration
|
||||
events.push(Object.assign({}, e))
|
||||
})
|
||||
if (cursor.isAfter(dueTo)) { break }
|
||||
cursor = first_event_of_week.add(toAdd.n, toAdd.unit)
|
||||
cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||
}
|
||||
|
||||
return events
|
||||
}
|
||||
|
||||
let allEvents = events.filter(e => !e.recurrent || e.recurrent.length === 0)
|
||||
events.filter(e => e.recurrent && e.recurrent.length).forEach(e => {
|
||||
const events = createEventsFromRecurrent(e, end)
|
||||
if (events) { allEvents = allEvents.concat(events) }
|
||||
})
|
||||
|
||||
// allEvents.sort((a,b) => a.start_datetime-b.start_datetime)
|
||||
res.json(allEvents.sort((a, b) => a.start_datetime - b.start_datetime))
|
||||
res.json(events.sort((a, b) => a.start_datetime - b.start_datetime))
|
||||
// res.json(recurrentEvents)
|
||||
}
|
||||
|
||||
// async getAll (req, res) {
|
||||
// // this is due how v-calendar shows dates
|
||||
// const start = moment()
|
||||
// .year(req.params.year)
|
||||
// .month(req.params.month)
|
||||
// .startOf('month')
|
||||
// .startOf('week')
|
||||
|
||||
// let end = moment()
|
||||
// .year(req.params.year)
|
||||
// .month(req.params.month)
|
||||
// .endOf('month')
|
||||
|
||||
// const shownDays = end.diff(start, 'days')
|
||||
// if (shownDays <= 35) { end = end.add(1, 'week') }
|
||||
// end = end.endOf('week')
|
||||
|
||||
// let events = await Event.findAll({
|
||||
// where: {
|
||||
// // return only confirmed events
|
||||
// is_visible: true,
|
||||
// [Op.or]: [
|
||||
// // return all recurrent events regardless start_datetime
|
||||
// { recurrent: { [Op.ne]: null } },
|
||||
|
||||
// // and events in specified range
|
||||
// { start_datetime: { [Op.between]: [start.unix(), end.unix()] } }
|
||||
// ]
|
||||
// },
|
||||
// attributes: { exclude: ['createdAt', 'updatedAt', 'placeId'] },
|
||||
// order: [[Tag, 'weigth', 'DESC']],
|
||||
// include: [
|
||||
// { model: Resource, required: false, attributes: ['id'] },
|
||||
// { model: Tag, required: false },
|
||||
// { model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
||||
// ]
|
||||
// })
|
||||
// events = events.map(e => e.get()).map(e => {
|
||||
// e.tags = e.tags.map(t => t.tag)
|
||||
// return e
|
||||
// })
|
||||
|
||||
// let allEvents = events.filter(e => !e.recurrent || e.recurrent.length === 0)
|
||||
// events.filter(e => e.recurrent && e.recurrent.length).forEach(e => {
|
||||
// const events = createEventsFromRecurrent(e, end)
|
||||
// if (events) { allEvents = allEvents.concat(events) }
|
||||
// })
|
||||
|
||||
// // allEvents.sort((a,b) => a.start_datetime-b.start_datetime)
|
||||
// res.json(allEvents.sort((a, b) => a.start_datetime - b.start_datetime))
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
module.exports = eventController
|
||||
|
|
|
@ -36,6 +36,9 @@ export const getters = {
|
|||
const search_for_tags = !!state.filters.tags.length
|
||||
const search_for_places = !!state.filters.places.length
|
||||
|
||||
const search_place_ids = state.filters.places.map(p => p.id)
|
||||
const search_tags_tags = state.filters.tags.map(t => t.id)
|
||||
|
||||
return state.events.filter(e => {
|
||||
// filter past events
|
||||
if (!state.filters.show_past_events && e.past) { return false }
|
||||
|
@ -44,13 +47,13 @@ export const getters = {
|
|||
if (!state.filters.show_recurrent_events && e.recurrent) { return false }
|
||||
|
||||
if (search_for_places) {
|
||||
if (find(state.filters.places, p => p.id === e.place.id)) {
|
||||
if (search_place_ids.includes(e.place.id)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (search_for_tags) {
|
||||
const common_tags = intersection(e.tags, state.filters.tags)
|
||||
const common_tags = intersection(e.tags, search_tags_tags)
|
||||
if (common_tags.length > 0) { return true }
|
||||
}
|
||||
|
||||
|
@ -158,7 +161,11 @@ export const actions = {
|
|||
commit('setSettings', settings)
|
||||
|
||||
const start_datetime = moment().startOf('month').startOf('week').unix()
|
||||
const events = await this.$axios.$get(`/event?start=${start_datetime}`)
|
||||
let query = `start=${start_datetime}`
|
||||
if (settings.recurrent_event_visible) {
|
||||
query += '&show_recurrent'
|
||||
}
|
||||
const events = await this.$axios.$get(`/event?${query}`)
|
||||
commit('setEvents', events)
|
||||
|
||||
const { tags, places } = await this.$axios.$get('/event/meta')
|
||||
|
@ -167,16 +174,15 @@ export const actions = {
|
|||
// apply settings
|
||||
commit('showRecurrentEvents', settings.allow_recurrent_event && settings.recurrent_event_visible)
|
||||
},
|
||||
async updateEvents ({ commit, state }, page) {
|
||||
const month = moment().month()
|
||||
const year = moment().year()
|
||||
commit('setPast', page.year < year || (page.year === year && page.month <= month))
|
||||
// const events = await this.$axios.$get(`/event/${page.month - 1}/${page.year}`)
|
||||
const start_datetime = moment().year(page.year).month(page.month - 1).unix()
|
||||
async updateEvents ({ commit }, page) {
|
||||
const [month, year] = [moment().month(), moment().year()]
|
||||
const in_past = page.year < year || (page.year === year && page.month <= month)
|
||||
// commit('setPast', in_past)
|
||||
const start_datetime = moment().year(page.year).month(page.month - 1).startOf('month').startOf('week').unix()
|
||||
const query = `start=${start_datetime}`
|
||||
|
||||
const events = await this.$axios.$get(`/event?${query}`)
|
||||
commit('setEvents', events)
|
||||
commit('showPastEvents', in_past)
|
||||
},
|
||||
async updateMeta ({ commit }) {
|
||||
const { tags, places } = await this.$axios.$get('/event/meta')
|
||||
|
|
Loading…
Reference in a new issue