diff --git a/server/ApiController.js b/server/ApiController.js index f1da5357..c767b485 100644 --- a/server/ApiController.js +++ b/server/ApiController.js @@ -172,6 +172,8 @@ class ApiController { this.router.post('/syncUserAudiobookData', this.syncUserAudiobookData.bind(this)) this.router.post('/purgecache', this.purgeCache.bind(this)) + + this.router.post('/syncStream', this.syncStream.bind(this)) } async findBooks(req, res) { @@ -405,6 +407,11 @@ class ApiController { res.json(allUserAudiobookData) } + async syncStream(req, res) { + Logger.debug(`[ApiController] syncStream for ${req.user.username} - ${req.body.streamId}`) + this.streamManager.streamSyncFromApi(req, res) + } + // // Helper Methods // diff --git a/server/Server.js b/server/Server.js index 6f1e125a..08f6a16e 100644 --- a/server/Server.js +++ b/server/Server.js @@ -229,10 +229,6 @@ class Server { // Used in development to set-up streams without authentication if (process.env.NODE_ENV !== 'production') { app.use('/test-hls', this.hlsController.router) - app.get('/catalog.json', (req, res) => { - Logger.error('Catalog request made', req.headers) - res.json() - }) } this.server.listen(this.Port, this.Host, () => { diff --git a/server/StreamManager.js b/server/StreamManager.js index 236eed34..2b8a6451 100644 --- a/server/StreamManager.js +++ b/server/StreamManager.js @@ -194,6 +194,46 @@ class StreamManager { } } + streamSyncFromApi(req, res) { + var user = req.user + var syncData = req.body + + var stream = this.streams.find(s => s.id === syncData.streamId) + if (!stream) { + Logger.error(`[StreamManager] streamSyncFromApi stream not found ${syncData.streamId}`) + return res.status(404).send('Stream not found') + } + if (stream.userToken !== user.token) { + Logger.error(`[StreamManager] streamSyncFromApi Invalid stream not owned by user`) + return res.status(500).send('Invalid stream auth') + } + + var listeningSession = stream.syncStream(syncData) + + if (listeningSession && listeningSession.timeListening > 0) { + // Save listening session + var existingListeningSession = this.db.sessions.find(s => s.id === listeningSession.id) + if (existingListeningSession) { + this.db.updateEntity('session', listeningSession) + } else { + this.db.sessions.push(listeningSession.toJSON()) // Insert right away to prevent duplicate session + this.db.insertEntity('session', listeningSession) + } + } + + var userAudiobook = user.updateAudiobookProgressFromStream(stream) + this.db.updateEntity('user', user) + + if (userAudiobook) { + this.clientEmitter(user.id, 'current_user_audiobook_update', { + id: userAudiobook.audiobookId, + data: userAudiobook.toJSON() + }) + } + + res.sendStatus(200) + } + streamUpdate(socket, { currentTime, streamId }) { var client = socket.sheepClient if (!client || !client.stream) { diff --git a/server/objects/Stream.js b/server/objects/Stream.js index b05cd18e..033b17e1 100644 --- a/server/objects/Stream.js +++ b/server/objects/Stream.js @@ -179,10 +179,13 @@ class Stream extends EventEmitter { syncStream({ timeListened, currentTime }) { var syncLog = '' + // Set user current time if (currentTime !== null && !isNaN(currentTime)) { syncLog = `Update client current time ${secondsToTimestamp(currentTime)}` this.clientCurrentTime = currentTime } + + // Update user listening session var saveListeningSession = false if (timeListened && !isNaN(timeListened)) { @@ -202,6 +205,7 @@ class Stream extends EventEmitter { syncLog += `Add listening time ${timeListened}s, Total time listened ${this.listeningSession.timeListening}s` saveListeningSession = true } + Logger.debug('[Stream]', syncLog) return saveListeningSession ? this.listeningSession : null }