mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-10 01:15:06 +02:00
Update API media progress endpoints to use new user model. Merge book & episode endpoints
This commit is contained in:
parent
68ef3a07a7
commit
9cd92c7b7f
8 changed files with 295 additions and 109 deletions
|
@ -3,6 +3,8 @@ const sequelize = require('sequelize')
|
|||
const Logger = require('../Logger')
|
||||
const oldUser = require('../objects/user/User')
|
||||
const SocketAuthority = require('../SocketAuthority')
|
||||
const { isNullOrNaN } = require('../utils')
|
||||
|
||||
const { DataTypes, Model } = sequelize
|
||||
|
||||
class User extends Model {
|
||||
|
@ -577,6 +579,116 @@ class User extends Model {
|
|||
})
|
||||
return mediaProgress?.getOldMediaProgress() || null
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Uses old model and should account for the different between ebook/audiobook progress
|
||||
*
|
||||
* @typedef ProgressUpdatePayload
|
||||
* @property {string} libraryItemId
|
||||
* @property {string} [episodeId]
|
||||
* @property {number} [duration]
|
||||
* @property {number} [progress]
|
||||
* @property {number} [currentTime]
|
||||
* @property {boolean} [isFinished]
|
||||
* @property {boolean} [hideFromContinueListening]
|
||||
* @property {string} [ebookLocation]
|
||||
* @property {number} [ebookProgress]
|
||||
* @property {string} [finishedAt]
|
||||
* @property {number} [lastUpdate]
|
||||
*
|
||||
* @param {ProgressUpdatePayload} progressPayload
|
||||
* @returns {Promise<{ mediaProgress: import('./MediaProgress'), error: [string], statusCode: [number] }>}
|
||||
*/
|
||||
async createUpdateMediaProgressFromPayload(progressPayload) {
|
||||
/** @type {import('./MediaProgress')|null} */
|
||||
let mediaProgress = null
|
||||
let mediaItemId = null
|
||||
if (progressPayload.episodeId) {
|
||||
const podcastEpisode = await this.sequelize.models.podcastEpisode.findByPk(progressPayload.episodeId, {
|
||||
attributes: ['id', 'podcastId'],
|
||||
include: [
|
||||
{
|
||||
model: this.sequelize.models.mediaProgress,
|
||||
where: { userId: this.id },
|
||||
required: false
|
||||
},
|
||||
{
|
||||
model: this.sequelize.models.podcast,
|
||||
attributes: ['id', 'title'],
|
||||
include: {
|
||||
model: this.sequelize.models.libraryItem,
|
||||
attributes: ['id']
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
if (!podcastEpisode) {
|
||||
Logger.error(`[User] createUpdateMediaProgress: episode ${progressPayload.episodeId} not found`)
|
||||
return {
|
||||
error: 'Episode not found',
|
||||
statusCode: 404
|
||||
}
|
||||
}
|
||||
mediaItemId = podcastEpisode.id
|
||||
mediaProgress = podcastEpisode.mediaProgresses?.[0]
|
||||
} else {
|
||||
const libraryItem = await this.sequelize.models.libraryItem.findByPk(progressPayload.libraryItemId, {
|
||||
attributes: ['id', 'mediaId', 'mediaType'],
|
||||
include: {
|
||||
model: this.sequelize.models.book,
|
||||
attributes: ['id', 'title'],
|
||||
required: false,
|
||||
include: {
|
||||
model: this.sequelize.models.mediaProgress,
|
||||
where: { userId: this.id },
|
||||
required: false
|
||||
}
|
||||
}
|
||||
})
|
||||
if (!libraryItem) {
|
||||
Logger.error(`[User] createUpdateMediaProgress: library item ${progressPayload.libraryItemId} not found`)
|
||||
return {
|
||||
error: 'Library item not found',
|
||||
statusCode: 404
|
||||
}
|
||||
}
|
||||
mediaItemId = libraryItem.media.id
|
||||
mediaProgress = libraryItem.media.mediaProgresses?.[0]
|
||||
}
|
||||
|
||||
if (mediaProgress) {
|
||||
mediaProgress = await mediaProgress.applyProgressUpdate(progressPayload)
|
||||
this.mediaProgresses = this.mediaProgresses.map((mp) => (mp.id === mediaProgress.id ? mediaProgress : mp))
|
||||
} else {
|
||||
const newMediaProgressPayload = {
|
||||
userId: this.id,
|
||||
mediaItemId,
|
||||
mediaItemType: progressPayload.episodeId ? 'podcastEpisode' : 'book',
|
||||
duration: isNullOrNaN(progressPayload.duration) ? 0 : Number(progressPayload.duration),
|
||||
currentTime: isNullOrNaN(progressPayload.currentTime) ? 0 : Number(progressPayload.currentTime),
|
||||
isFinished: !!progressPayload.isFinished,
|
||||
hideFromContinueListening: !!progressPayload.hideFromContinueListening,
|
||||
ebookLocation: progressPayload.ebookLocation || null,
|
||||
ebookProgress: isNullOrNaN(progressPayload.ebookProgress) ? 0 : Number(progressPayload.ebookProgress),
|
||||
finishedAt: progressPayload.finishedAt || null,
|
||||
extraData: {
|
||||
libraryItemId: progressPayload.libraryItemId,
|
||||
progress: isNullOrNaN(progressPayload.progress) ? 0 : Number(progressPayload.progress)
|
||||
}
|
||||
}
|
||||
if (newMediaProgressPayload.isFinished) {
|
||||
newMediaProgressPayload.finishedAt = new Date()
|
||||
newMediaProgressPayload.extraData.progress = 1
|
||||
} else {
|
||||
newMediaProgressPayload.finishedAt = null
|
||||
}
|
||||
mediaProgress = await this.sequelize.models.mediaProgress.create(newMediaProgressPayload)
|
||||
this.mediaProgresses.push(mediaProgress)
|
||||
}
|
||||
return {
|
||||
mediaProgress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = User
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue