Initial commit
This commit is contained in:
commit
2ce34b0dc8
4 changed files with 189 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules/
|
||||
package-lock.json
|
13
README.md
Normal file
13
README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Cleaner plugin for Gancio
|
||||
|
||||
This is a plugin for gancio that cleans past eventsd, this is a beta release.
|
||||
|
||||
## Configuration
|
||||
|
||||
Once the plugin is installed, navigate to your instance plugins tab of the admin interface. Enable the plugin and add the required data.
|
||||
|
||||
|
||||
## Try it
|
||||
|
||||
1. Restart your gancio instance and look at the logs for any message saying that this plugin has been loaded.
|
||||
|
161
index.js
Normal file
161
index.js
Normal file
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* Clean past events from gancio
|
||||
*/
|
||||
|
||||
const path = require('path')
|
||||
const fs = require('fs/promises')
|
||||
const config = require('../../config')
|
||||
const notifier = require('../../../gancio_source/server/notifier')
|
||||
const { Op } = require('sequelize')
|
||||
const { Event, Resource, Tag, Place, Notification, APUser, EventNotification, Message, User } = require('../../../gancio_source/server/api/models/models')
|
||||
|
||||
|
||||
const plugin = {
|
||||
configuration: {
|
||||
name: 'Cleaner',
|
||||
author: 'snt',
|
||||
url: 'https://git.criptomart.net/snt/gancio',
|
||||
description: 'Cleans events from a specified time before now, this is a beta release of this plugin.',
|
||||
settings: {
|
||||
refresh_time: {
|
||||
type: 'NUMBER',
|
||||
hint: 'Search for past events each n hours',
|
||||
required: true,
|
||||
description: '1 hour?'
|
||||
},
|
||||
deadline_time: {
|
||||
type: 'NUMBER',
|
||||
hint: 'Clean all events non recurrent with end time n hours ago.',
|
||||
required: true,
|
||||
description: '720 hours? events ended after this number of hours ago will be deleted.'
|
||||
},
|
||||
events_number: {
|
||||
type: 'NUMBER',
|
||||
hint: 'Limit the number of events to be deleted each call.',
|
||||
required: true,
|
||||
description: '4? Do not set too much, it can overload notifications.'
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
gancio: null, // { helpers, log, settings }
|
||||
log: null,
|
||||
settings: null,
|
||||
db: null,
|
||||
interval: null,
|
||||
ETag: null,
|
||||
|
||||
load(gancio, settings) {
|
||||
plugin.gancio = gancio // contains all gancio settings, including all plugins settings
|
||||
plugin.log = gancio.log // just the logger
|
||||
plugin.db = gancio.db
|
||||
plugin.settings = settings // this plugin settings
|
||||
|
||||
plugin.apiBaseUrl = gancio.settings.baseurl + '/api'
|
||||
|
||||
// TODO: could use the TaskManager?
|
||||
plugin.interval = setInterval(this._tick, settings.refresh_time*1000*60*60)
|
||||
plugin.log.debug("[Cleaner Plugin] loaded with params: refresh: %s -- deadline: %s -- number: %s", settings.refresh_time, settings.deadline_time, settings.events_number)
|
||||
// this._tick()
|
||||
},
|
||||
|
||||
unload () {
|
||||
plugin.log.debug('[Cleaner Plugin] Clear interval an unload plugin')
|
||||
clearInterval(plugin.interval)
|
||||
},
|
||||
|
||||
onTest () {
|
||||
plugin._tick()
|
||||
},
|
||||
|
||||
async _tick () {
|
||||
// Avoid running multiple ticks at the same time which could cause race conditions on the database
|
||||
if (plugin._isTickRunning) {
|
||||
plugin.log.warn('[Cleaner Plugin] _tick already in progress, skipping')
|
||||
return
|
||||
}
|
||||
plugin.log.debug('[Cleaner Plugin] _tick started, locking it')
|
||||
plugin._isTickRunning = true
|
||||
|
||||
try {
|
||||
if (!plugin.settings?.refresh_time) {
|
||||
plugin.log.debug('[Cleaner Plugin] refresh time not set, default to 1 hour')
|
||||
plugin.settings.refresh_time = 1
|
||||
plugin.interval = setInterval(this._tick, settings.refresh_time*1000*60*60)
|
||||
}
|
||||
if (!plugin.settings?.deadline_time) {
|
||||
plugin.log.debug('[Cleaner Plugin] deadline time not set, default to 4 weeks')
|
||||
plugin.settings.deadline_time = 720
|
||||
}
|
||||
if (!plugin.settings?.events_number) {
|
||||
plugin.log.debug('[Cleaner Plugin] events cleared not set, default to 1')
|
||||
plugin.settings.events_number = 1
|
||||
}
|
||||
try {
|
||||
plugin.log.debug(`[Cleaner Plugin] Begin searching`)
|
||||
const now = Math.floor(Date.now())
|
||||
const cut_datetime = now - plugin.settings?.deadline_time*60*60*1000
|
||||
const date_obj = new Date(cut_datetime)
|
||||
plugin.log.debug("now %s -- deadline %s", now, cut_datetime)
|
||||
plugin.log.info("[Cleaner Plugin] Removing old events before " + date_obj)
|
||||
events = await plugin.db.models.event.findAll({
|
||||
where: {
|
||||
recurrent: null,
|
||||
start_datetime: { [Op.lt]: cut_datetime/1000 },
|
||||
[Op.or]: [ {end_datetime: { [Op.lt]: cut_datetime/1000 } }, { end_datetime: null } ]
|
||||
},
|
||||
order: [['end_datetime', 'ASC']],
|
||||
include: [{ model: Event, as:'child' }],
|
||||
limit: plugin.settings.events_number,
|
||||
})
|
||||
|
||||
plugin.log.warn("[Cleaner Plugin] Found %s past events and related resources.", events.length)
|
||||
|
||||
if (!events.length) { return }
|
||||
|
||||
for (e of events) {
|
||||
end_date = new Date(e.end_datetime * 1000)
|
||||
start_date = new Date(e.start_datetime * 1000)
|
||||
plugin.log.info("[Cleaner Plugin] Cleaning: " + e.title + " - Rec: " + e.recurrent + " - From: " + start_date + " - To: " + end_date + " - place: " + e.placeId)
|
||||
plugin.log.debug("[Cleaner Plugin] %s", JSON.stringify(e, null, "\t"))
|
||||
if (e.media && e.media.length && !e.recurrent && !e.parentId) {
|
||||
try {
|
||||
const old_path = path.join(config.upload_path, e.media[0].url)
|
||||
const old_thumb_path = path.join(config.upload_path, 'thumb', e.media[0].url)
|
||||
await fs.unlink(old_thumb_path)
|
||||
await fs.unlink(old_path)
|
||||
plugin.log.debug("[Cleaner Plugin] removing file: " + old_path)
|
||||
} catch (excep) {
|
||||
plugin.log.error("[Cleaner Plugin] error removing file %s", excep.toString())
|
||||
}
|
||||
}
|
||||
try {
|
||||
// notify local events before destroying notifications
|
||||
if (!e.ap_id) {
|
||||
await notifier.notifyEvent("Delete", e.id)
|
||||
}
|
||||
// remove related resources
|
||||
await Resource.destroy({ where: { eventId: e.id }})
|
||||
// remove notifications
|
||||
await EventNotification.destroy({ where: { eventId: e.id }})
|
||||
// remove event
|
||||
await e.destroy()
|
||||
} catch (excep) {
|
||||
console.error(excep)
|
||||
plugin.log.error("[Cleaner Plugin] error destroying %s", excep.toString() )
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
plugin.log.error(`[Cleaner Plugin] Error: ${String(e)}`)
|
||||
}
|
||||
} catch (e) {
|
||||
plugin.log.error(`[Cleaner Plugin] Uncaught error in _tick: ${String(e)}`)
|
||||
} finally {
|
||||
plugin.log.debug('[Cleaner Plugin] _tick finished, unlocking it')
|
||||
plugin._isTickRunning = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = plugin
|
13
package.json
Normal file
13
package.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "gancio-plugin-cleaner",
|
||||
"version": "0.1.0",
|
||||
"description": "Cleaner plugin for Gancio",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"sequelize": "^6.37.7"
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue