mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-03 17:54:54 +02:00
Update:API endpoint for syncing multiple local sessions. New API endpoint to get current user. Deprecate /me/sync-local-progress endpoint
This commit is contained in:
parent
debf0f495d
commit
f9e6655359
5 changed files with 107 additions and 46 deletions
|
@ -21,7 +21,6 @@ class PlaybackSessionManager {
|
|||
this.StreamsPath = Path.join(global.MetadataPath, 'streams')
|
||||
|
||||
this.sessions = []
|
||||
this.localSessionLock = {}
|
||||
}
|
||||
|
||||
getSession(sessionId) {
|
||||
|
@ -61,18 +60,84 @@ class PlaybackSessionManager {
|
|||
}
|
||||
}
|
||||
|
||||
async syncLocalSessionRequest(user, sessionJson, res) {
|
||||
if (this.localSessionLock[sessionJson.id]) {
|
||||
Logger.debug(`[PlaybackSessionManager] syncLocalSessionRequest: Local session is locked and already syncing`)
|
||||
return res.status(500).send('Local session is locked and already syncing')
|
||||
async syncLocalSessionsRequest(req, res) {
|
||||
const user = req.user
|
||||
const sessions = req.body.sessions || []
|
||||
|
||||
const syncResults = []
|
||||
for (const sessionJson of sessions) {
|
||||
Logger.info(`[PlaybackSessionManager] Syncing local session "${sessionJson.displayTitle}" (${sessionJson.id})`)
|
||||
const result = await this.syncLocalSession(user, sessionJson)
|
||||
syncResults.push(result)
|
||||
}
|
||||
|
||||
res.json({
|
||||
results: syncResults
|
||||
})
|
||||
}
|
||||
|
||||
async syncLocalSession(user, sessionJson) {
|
||||
const libraryItem = this.db.getLibraryItem(sessionJson.libraryItemId)
|
||||
if (!libraryItem) {
|
||||
Logger.error(`[PlaybackSessionManager] syncLocalSessionRequest: Library item not found for session "${sessionJson.libraryItemId}"`)
|
||||
return res.status(500).send('Library item not found')
|
||||
const episode = (sessionJson.episodeId && libraryItem && libraryItem.isPodcast) ? libraryItem.media.getEpisode(sessionJson.episodeId) : null
|
||||
if (!libraryItem || (libraryItem.isPodcast && !episode)) {
|
||||
Logger.error(`[PlaybackSessionManager] syncLocalSession: Media item not found for session "${sessionJson.displayTitle}" (${sessionJson.id})`)
|
||||
return {
|
||||
id: sessionJson.id,
|
||||
success: false,
|
||||
error: 'Media item not found'
|
||||
}
|
||||
}
|
||||
|
||||
let session = await this.db.getPlaybackSession(sessionJson.id)
|
||||
if (!session) {
|
||||
// New session from local
|
||||
session = new PlaybackSession(sessionJson)
|
||||
Logger.debug(`[PlaybackSessionManager] Inserting new session for "${session.displayTitle}" (${session.id})`)
|
||||
await this.db.insertEntity('session', session)
|
||||
} else {
|
||||
session.currentTime = sessionJson.currentTime
|
||||
session.timeListening = sessionJson.timeListening
|
||||
session.updatedAt = sessionJson.updatedAt
|
||||
session.date = date.format(new Date(), 'YYYY-MM-DD')
|
||||
session.dayOfWeek = date.format(new Date(), 'dddd')
|
||||
|
||||
Logger.debug(`[PlaybackSessionManager] Updated session for "${session.displayTitle}" (${session.id})`)
|
||||
await this.db.updateEntity('session', session)
|
||||
}
|
||||
|
||||
const result = {
|
||||
id: session.id,
|
||||
success: true,
|
||||
progressSynced: false
|
||||
}
|
||||
|
||||
const userProgressForItem = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
if (userProgressForItem) {
|
||||
if (userProgressForItem.lastUpdate > session.updatedAt) {
|
||||
Logger.debug(`[PlaybackSessionManager] Not updating progress for "${session.displayTitle}" because it has been updated more recently`)
|
||||
} else {
|
||||
Logger.debug(`[PlaybackSessionManager] Updating progress for "${session.displayTitle}" with current time ${session.currentTime} (previously ${userProgressForItem.currentTime})`)
|
||||
result.progressSynced = user.createUpdateMediaProgress(libraryItem, session.mediaProgressObject, session.episodeId)
|
||||
}
|
||||
} else {
|
||||
Logger.debug(`[PlaybackSessionManager] Creating new media progress for media item "${session.displayTitle}"`)
|
||||
result.progressSynced = user.createUpdateMediaProgress(libraryItem, session.mediaProgressObject, session.episodeId)
|
||||
}
|
||||
|
||||
// Update user and emit socket event
|
||||
if (result.progressSynced) {
|
||||
await this.db.updateEntity('user', user)
|
||||
const itemProgress = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
SocketAuthority.clientEmitter(user.id, 'user_item_progress_updated', {
|
||||
id: itemProgress.id,
|
||||
data: itemProgress.toJSON()
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
async syncLocalSessionRequest(user, sessionJson, res) {
|
||||
// If server session is open for this same media item then close it
|
||||
const userSessionForThisItem = this.sessions.find(playbackSession => {
|
||||
if (playbackSession.userId !== user.id) return false
|
||||
|
@ -84,43 +149,13 @@ class PlaybackSessionManager {
|
|||
await this.closeSession(user, userSessionForThisItem, null)
|
||||
}
|
||||
|
||||
this.localSessionLock[sessionJson.id] = true // Lock local session
|
||||
|
||||
let session = await this.db.getPlaybackSession(sessionJson.id)
|
||||
if (!session) {
|
||||
// New session from local
|
||||
session = new PlaybackSession(sessionJson)
|
||||
await this.db.insertEntity('session', session)
|
||||
// Sync
|
||||
const result = await this.syncLocalSession(user, sessionJson)
|
||||
if (result.error) {
|
||||
res.status(500).send(result.error)
|
||||
} else {
|
||||
session.currentTime = sessionJson.currentTime
|
||||
session.timeListening = sessionJson.timeListening
|
||||
session.updatedAt = sessionJson.updatedAt
|
||||
session.date = date.format(new Date(), 'YYYY-MM-DD')
|
||||
session.dayOfWeek = date.format(new Date(), 'dddd')
|
||||
await this.db.updateEntity('session', session)
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
session.currentTime = sessionJson.currentTime
|
||||
|
||||
const itemProgressUpdate = {
|
||||
duration: session.duration,
|
||||
currentTime: session.currentTime,
|
||||
progress: session.progress,
|
||||
lastUpdate: session.updatedAt // Keep media progress update times the same as local
|
||||
}
|
||||
const wasUpdated = user.createUpdateMediaProgress(libraryItem, itemProgressUpdate, session.episodeId)
|
||||
if (wasUpdated) {
|
||||
await this.db.updateEntity('user', user)
|
||||
const itemProgress = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
SocketAuthority.clientEmitter(user.id, 'user_item_progress_updated', {
|
||||
id: itemProgress.id,
|
||||
data: itemProgress.toJSON()
|
||||
})
|
||||
}
|
||||
|
||||
delete this.localSessionLock[sessionJson.id] // Unlock local session
|
||||
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
async closeSessionRequest(user, session, syncData, res) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue