From 8416f2d6beb03c62670b7967387ceb9c7e51ef55 Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 29 Jul 2022 17:13:46 -0500 Subject: [PATCH] Fix:Remove invalid playback sessions on server start #868 --- server/Db.js | 21 +++++++++++++++++++-- server/Server.js | 2 +- server/managers/PlaybackSessionManager.js | 11 +++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/server/Db.js b/server/Db.js index ceb80c53..5893eef5 100644 --- a/server/Db.js +++ b/server/Db.js @@ -413,6 +413,23 @@ class Db { }) } + removeEntities(entityName, selectFunc) { + var entityDb = this.getEntityDb(entityName) + return entityDb.delete(selectFunc).then((results) => { + Logger.debug(`[DB] Deleted entities ${entityName}: ${results.deleted}`) + var arrayKey = this.getEntityArrayKey(entityName) + if (this[arrayKey]) { + this[arrayKey] = this[arrayKey].filter(e => { + return !selectFunc(e) + }) + } + return results.deleted + }).catch((error) => { + Logger.error(`[DB] Remove entities ${entityName} Failed: ${error}`) + return 0 + }) + } + recreateLibraryItemsDb() { return this.libraryItemsDb.drop().then((results) => { Logger.info(`[DB] Dropped library items db`, results) @@ -425,8 +442,8 @@ class Db { }) } - getAllSessions() { - return this.sessionsDb.select(() => true).then((results) => { + getAllSessions(selectFunc = () => true) { + return this.sessionsDb.select(selectFunc).then((results) => { return results.data || [] }).catch((error) => { Logger.error('[Db] Failed to select sessions', error) diff --git a/server/Server.js b/server/Server.js index cac5deb7..c204a57f 100644 --- a/server/Server.js +++ b/server/Server.js @@ -143,6 +143,7 @@ class Server { await this.checkUserMediaProgress() // Remove invalid user item progress await this.purgeMetadata() // Remove metadata folders without library item + await this.playbackSessionManager.removeInvalidSessions() await this.cacheManager.ensureCachePaths() await this.abMergeManager.ensureDownloadDirPath() @@ -176,7 +177,6 @@ class Server { const distPath = Path.join(global.appRoot, '/client/dist') app.use(express.static(distPath)) - // Metadata folder static path app.use('/metadata', this.authMiddleware.bind(this), express.static(global.MetadataPath)) diff --git a/server/managers/PlaybackSessionManager.js b/server/managers/PlaybackSessionManager.js index f32ba639..9d358719 100644 --- a/server/managers/PlaybackSessionManager.js +++ b/server/managers/PlaybackSessionManager.js @@ -244,5 +244,16 @@ class PlaybackSessionManager { Logger.error(`[PlaybackSessionManager] cleanOrphanStreams failed`, error) } } + + // Android app v0.9.54 and below had a bug where listening time was sending unix timestamp + // See https://github.com/advplyr/audiobookshelf/issues/868 + // Remove playback sessions with listening time too high + async removeInvalidSessions() { + const selectFunc = (session) => isNaN(session.timeListening) || Number(session.timeListening) > 3600000000 + const numSessionsRemoved = await this.db.removeEntities('session', selectFunc) + if (numSessionsRemoved) { + Logger.info(`[PlaybackSessionManager] Removed ${numSessionsRemoved} invalid playback sessions`) + } + } } module.exports = PlaybackSessionManager \ No newline at end of file