more notifications

This commit is contained in:
Vito0912 2025-05-17 17:55:18 +02:00
parent 04ba949182
commit 9e28ee036f
No known key found for this signature in database
GPG Key ID: 29A3D509FE70B237
5 changed files with 99 additions and 39 deletions

View File

@ -3,6 +3,7 @@ const Logger = require('./Logger')
const Database = require('./Database')
const Auth = require('./Auth')
const NotificationManager = require('./managers/NotificationManager')
const { flattenAny } = require('./utils/objectUtils')
/**
* @typedef SocketClient
@ -16,7 +17,7 @@ class SocketAuthority {
constructor() {
this.Server = null
this.socketIoServers = []
this.emittedNotifications = new Set(['item_created', 'item_updated']);
this.emittedNotifications = new Set(['item_added', 'item_updated', 'user_online']);
/** @type {Object.<string, SocketClient>} */
this.clients = {}
@ -110,7 +111,7 @@ class SocketAuthority {
* @param {import('./models/LibraryItem')} libraryItem
*/
libraryItemEmitter(evt, libraryItem) {
void this._fireNotification(evt, libraryItem)
void this._fireNotification(evt, flattenAny(libraryItem.toOldJSONMinified()))
for (const socketId in this.clients) {
if (this.clients[socketId].user?.checkCanAccessLibraryItem(libraryItem)) {
this.clients[socketId].socket.emit(evt, libraryItem.toOldJSONExpanded())
@ -126,7 +127,6 @@ class SocketAuthority {
* @param {import('./models/LibraryItem')[]} libraryItems
*/
libraryItemsEmitter(evt, libraryItems) {
void this._fireNotification(evt, libraryItems)
for (const socketId in this.clients) {
if (this.clients[socketId].user) {
const libraryItemsAccessibleToUser = libraryItems.filter((li) => this.clients[socketId].user.checkCanAccessLibraryItem(li))

View File

@ -90,14 +90,6 @@ class NotificationManager {
this.triggerNotification('onBackupFailed', eventData)
}
/**
* @param
*/
async onItemUpdated(libraryItem) {
console.log('onItemUpdated', libraryItem)
this.triggerNotification('onItemUpdated', libraryItem)
}
onTest() {
this.triggerNotification('onTest')
}
@ -132,7 +124,8 @@ class NotificationManager {
}
await Database.updateSetting(Database.notificationSettings)
//SocketAuthority.emitter('notifications_updated', Database.notificationSettings.toJSON())
// Currently results in circular dependency TODO: Fix this
// SocketAuthority.emitter('notifications_updated', Database.notificationSettings.toJSON())
this.notificationFinished()
}
@ -199,6 +192,9 @@ class NotificationManager {
const eventNameModified = eventName.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
const eventKey = `on${eventNameModified.charAt(0).toUpperCase()}${eventNameModified.slice(1)}`;
console.log(eventData)
console.log(Object.keys(eventData))
if (!Database.notificationSettings.getHasActiveNotificationsForEvent(eventKey)) {
// No logging to prevent console spam
Logger.debug(`[NotificationManager] fireSocketNotification: No active notifications`)
@ -207,11 +203,7 @@ class NotificationManager {
Logger.debug(`[NotificationManager] fireNotificationFromSocket: ${eventKey} event fired`)
switch (eventKey) {
case 'onItemUpdated':
void this.onItemUpdated(eventData)
break
}
void this.triggerNotification(eventKey, eventData)
}
}
module.exports = new NotificationManager()

View File

@ -102,7 +102,7 @@ class Notification {
}
replaceVariablesInTemplate(templateText, data) {
const ptrn = /{{ ?([a-zA-Z]+) ?}}/mg
const ptrn = /{{ ?([a-zA-Z.]+) ?}}/mg
var match
var updatedTemplate = templateText
@ -130,4 +130,4 @@ class Notification {
}
}
}
module.exports = Notification
module.exports = Notification

View File

@ -4,29 +4,48 @@ const LibraryItem = require('../models/LibraryItem')
const libraryItemVariables = [
'id',
'ino',
'oldLibraryItemId',
'libraryId',
'folderId',
'path',
'relPath',
'mediaId',
'mediaType',
'isFile',
'mtimeMs',
'ctimeMs',
'birthtimeMs',
'addedAt',
'updatedAt',
'isMissing',
'isInvalid',
'mtime',
'ctime',
'birthtime',
'size',
'lastScan',
'lastScanVersion',
'libraryFiles',
'extraData',
'title',
'titleIgnorePrefix',
'authorNamesFirstLast',
'authorNamesLastFirst',
'createdAt',
'updatedAt',
'libraryId',
'libraryFolderId',
'mediaType',
'media.id',
'media.metadata.title',
'media.metadata.titleIgnorePrefix',
'media.metadata.subtitle',
'media.metadata.authorName',
'media.metadata.authorNameLF',
'media.metadata.narratorName',
'media.metadata.seriesName',
'media.metadata.genres',
'media.metadata.publishedYear',
'media.metadata.publishedDate',
'media.metadata.publisher',
'media.metadata.description',
'media.metadata.isbn',
'media.metadata.asin',
'media.metadata.language',
'media.metadata.explicit',
'media.metadata.abridged',
'media.coverPath',
'media.tags',
'media.numTracks',
'media.numAudioFiles',
'media.numChapters',
'media.duration',
'media.size',
'media.ebookFormat',
'numFiles',
'size'
]
const libraryItemTestData = {
@ -119,6 +138,18 @@ module.exports.notificationData = {
},
// Sockets - Silently crying because not using typescript
{
name: 'onItemAdded',
requiresLibrary: true,
description: 'Triggered when an item is added',
descriptionKey: 'NotificationOnItemAddedDescription',
variables: libraryItemVariables,
defaults: {
title: 'Item Added: {{media.metadata.title}}',
body: 'Item {{media.metadata.title}} has been added.\n\nPath: {{path}}\nSize: {{size}} bytes\nLibrary ID: {{libraryId}}'
},
testData: libraryItemTestData
},
{
name: 'onItemUpdated',
requiresLibrary: true,
@ -126,11 +157,22 @@ module.exports.notificationData = {
descriptionKey: 'NotificationOnItemUpdatedDescription',
variables: libraryItemVariables,
defaults: {
title: 'Item Updated: {{title}}',
body: 'Item {{title}} has been updated.\n\nPath: {{path}}\nSize: {{size}} bytes\nLast Scan: {{lastScan}}\nLibrary ID: {{libraryId}}\nLibrary Folder ID: {{libraryFolderId}}'
title: 'Item Updated: {{media.metadata.title}}',
body: 'Item {{media.metadata.title}} has been added.\n\nPath: {{path}}\nSize: {{size}} bytes\nLibrary ID: {{libraryId}}'
},
testData: libraryItemTestData
},
{
name: 'onUserOnline',
requiresLibrary: false,
description: 'Triggered when a user comes online',
descriptionKey: 'NotificationOnUserOnlineDescription',
variables: [ 'id', 'username', 'type', 'session', 'lastSeen', 'createdAt'],
defaults: {
title: 'User Online: {{username}}',
body: 'User {{username}} (ID: {{id}}) is now online.'
},
},
// Test
{

View File

@ -0,0 +1,26 @@
function flattenAny(obj, prefix = '', result = {}) {
const entries =
obj instanceof Map
? obj.entries()
: Object.entries(obj);
for (const [key, value] of entries) {
const newKey = prefix ? `${prefix}.${key}` : `${key}`;
if (
value instanceof Map ||
(typeof value === 'object' &&
value !== null &&
!Array.isArray(value))
) {
flattenAny(value, newKey, result);
} else {
result[newKey] = value;
}
}
return result;
}
module.exports = {
flattenAny
}