mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-06-15 23:14:25 +02:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d4303ef7b | |||
| 1f7be58124 | |||
| 6b8b27b04f | |||
| ba4061e5a4 | |||
| 693dc00fa3 |
+1
-1
@@ -57,7 +57,7 @@ WORKDIR /app
|
||||
# Copy compiled frontend and server from build stages
|
||||
COPY --from=build-client /client/dist /app/client/dist
|
||||
COPY --from=build-server /server /app
|
||||
COPY --from=build-server /usr/local/lib/nusqlite3 /usr/local/lib/nusqlite3
|
||||
COPY --from=build-server ${NUSQLITE3_PATH} ${NUSQLITE3_PATH}
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
|
||||
+19
-8
@@ -766,14 +766,25 @@ class Database {
|
||||
Logger.warn(`Removed ${badSessionsRemoved} sessions that were 3 seconds or less`)
|
||||
}
|
||||
|
||||
// Remove mediaProgresses with duplicate mediaItemId (remove the oldest updatedAt)
|
||||
// const [duplicateMediaProgresses] = await this.sequelize.query(`SELECT id, mediaItemId FROM mediaProgresses WHERE (mediaItemId, userId, updatedAt) IN (SELECT mediaItemId, userId, MIN(updatedAt) FROM mediaProgresses GROUP BY mediaItemId, userId HAVING COUNT(*) > 1)`)
|
||||
// for (const duplicateMediaProgress of duplicateMediaProgresses) {
|
||||
// Logger.warn(`Found duplicate mediaProgress for mediaItem "${duplicateMediaProgress.mediaItemId}" - removing it`)
|
||||
// await this.mediaProgressModel.destroy({
|
||||
// where: { id: duplicateMediaProgress.id }
|
||||
// })
|
||||
// }
|
||||
// Remove mediaProgresses with duplicate mediaItemId (remove the oldest updatedAt or if updatedAt is the same, remove arbitrary one)
|
||||
const [duplicateMediaProgresses] = await this.sequelize.query(`SELECT mp1.id, mp1.mediaItemId
|
||||
FROM mediaProgresses mp1
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM mediaProgresses mp2
|
||||
WHERE mp2.mediaItemId = mp1.mediaItemId
|
||||
AND mp2.userId = mp1.userId
|
||||
AND (
|
||||
mp2.updatedAt > mp1.updatedAt
|
||||
OR (mp2.updatedAt = mp1.updatedAt AND mp2.id < mp1.id)
|
||||
)
|
||||
)`)
|
||||
for (const duplicateMediaProgress of duplicateMediaProgresses) {
|
||||
Logger.warn(`Found duplicate mediaProgress for mediaItem "${duplicateMediaProgress.mediaItemId}" - removing it`)
|
||||
await this.mediaProgressModel.destroy({
|
||||
where: { id: duplicateMediaProgress.id }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async createTextSearchQuery(query) {
|
||||
|
||||
@@ -107,7 +107,7 @@ class PlaybackSessionManager {
|
||||
|
||||
const syncResults = []
|
||||
for (const sessionJson of sessions) {
|
||||
Logger.info(`[PlaybackSessionManager] Syncing local session "${sessionJson.displayTitle}" (${sessionJson.id})`)
|
||||
Logger.info(`[PlaybackSessionManager] Syncing local session "${sessionJson.displayTitle}" (${sessionJson.id}) (updatedAt: ${sessionJson.updatedAt})`)
|
||||
const result = await this.syncLocalSession(user, sessionJson, deviceInfo)
|
||||
syncResults.push(result)
|
||||
}
|
||||
@@ -230,9 +230,9 @@ class PlaybackSessionManager {
|
||||
let userProgressForItem = user.getMediaProgress(mediaItemId)
|
||||
if (userProgressForItem) {
|
||||
if (userProgressForItem.updatedAt.valueOf() > session.updatedAt) {
|
||||
Logger.debug(`[PlaybackSessionManager] Not updating progress for "${session.displayTitle}" because it has been updated more recently`)
|
||||
Logger.info(`[PlaybackSessionManager] Not updating progress for "${session.displayTitle}" because it has been updated more recently (${userProgressForItem.updatedAt.valueOf()} > ${session.updatedAt}) (incoming currentTime: ${session.currentTime}) (current currentTime: ${userProgressForItem.currentTime})`)
|
||||
} else {
|
||||
Logger.debug(`[PlaybackSessionManager] Updating progress for "${session.displayTitle}" with current time ${session.currentTime} (previously ${userProgressForItem.currentTime})`)
|
||||
Logger.info(`[PlaybackSessionManager] Updating progress for "${session.displayTitle}" with current time ${session.currentTime} (previously ${userProgressForItem.currentTime})`)
|
||||
const updateResponse = await user.createUpdateMediaProgressFromPayload({
|
||||
libraryItemId: libraryItem.id,
|
||||
episodeId: session.episodeId,
|
||||
@@ -246,7 +246,7 @@ class PlaybackSessionManager {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Logger.debug(`[PlaybackSessionManager] Creating new media progress for media item "${session.displayTitle}"`)
|
||||
Logger.info(`[PlaybackSessionManager] Creating new media progress for media item "${session.displayTitle}"`)
|
||||
const updateResponse = await user.createUpdateMediaProgressFromPayload({
|
||||
libraryItemId: libraryItem.id,
|
||||
episodeId: session.episodeId,
|
||||
|
||||
@@ -222,13 +222,13 @@ class MediaProgress extends Model {
|
||||
const markAsFinishedPercentComplete = Number(progressPayload.markAsFinishedPercentComplete) / 100
|
||||
shouldMarkAsFinished = markAsFinishedPercentComplete < this.progress
|
||||
if (shouldMarkAsFinished) {
|
||||
Logger.debug(`[MediaProgress] Marking media progress as finished because progress (${this.progress}) is greater than ${markAsFinishedPercentComplete}`)
|
||||
Logger.info(`[MediaProgress] Marking media progress as finished because progress (${this.progress}) is greater than ${markAsFinishedPercentComplete} (media item ${this.mediaItemId})`)
|
||||
}
|
||||
} else {
|
||||
const markAsFinishedTimeRemaining = isNullOrNaN(progressPayload.markAsFinishedTimeRemaining) ? 10 : Number(progressPayload.markAsFinishedTimeRemaining)
|
||||
shouldMarkAsFinished = timeRemaining < markAsFinishedTimeRemaining
|
||||
if (shouldMarkAsFinished) {
|
||||
Logger.debug(`[MediaProgress] Marking media progress as finished because time remaining (${timeRemaining}) is less than ${markAsFinishedTimeRemaining} seconds`)
|
||||
Logger.info(`[MediaProgress] Marking media progress as finished because time remaining (${timeRemaining}) is less than ${markAsFinishedTimeRemaining} seconds (media item ${this.mediaItemId})`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,6 +246,7 @@ class MediaProgress extends Model {
|
||||
// For local sync
|
||||
if (progressPayload.lastUpdate) {
|
||||
this.updatedAt = progressPayload.lastUpdate
|
||||
Logger.info(`[MediaProgress] Manually setting updatedAt to ${this.updatedAt} (media item ${this.mediaItemId})`)
|
||||
this.changed('updatedAt', true)
|
||||
}
|
||||
|
||||
|
||||
@@ -251,6 +251,15 @@ module.exports = {
|
||||
*/
|
||||
getOrder(sortBy, sortDesc, collapseseries) {
|
||||
const dir = sortDesc ? 'DESC' : 'ASC'
|
||||
|
||||
const getTitleOrder = () => {
|
||||
if (global.ServerSettings.sortingIgnorePrefix) {
|
||||
return [Sequelize.literal('`libraryItem`.`titleIgnorePrefix` COLLATE NOCASE'), dir]
|
||||
} else {
|
||||
return [Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]
|
||||
}
|
||||
}
|
||||
|
||||
if (sortBy === 'addedAt') {
|
||||
return [[Sequelize.literal('libraryItem.createdAt'), dir]]
|
||||
} else if (sortBy === 'size') {
|
||||
@@ -264,25 +273,16 @@ module.exports = {
|
||||
} else if (sortBy === 'media.metadata.publishedYear') {
|
||||
return [[Sequelize.literal(`CAST(\`book\`.\`publishedYear\` AS INTEGER)`), dir]]
|
||||
} else if (sortBy === 'media.metadata.authorNameLF') {
|
||||
return [
|
||||
[Sequelize.literal('`libraryItem`.`authorNamesLastFirst` COLLATE NOCASE'), dir],
|
||||
[Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]
|
||||
]
|
||||
// Sort by author name last first, secondary sort by title
|
||||
return [[Sequelize.literal('`libraryItem`.`authorNamesLastFirst` COLLATE NOCASE'), dir], getTitleOrder()]
|
||||
} else if (sortBy === 'media.metadata.authorName') {
|
||||
return [
|
||||
[Sequelize.literal('`libraryItem`.`authorNamesFirstLast` COLLATE NOCASE'), dir],
|
||||
[Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]
|
||||
]
|
||||
// Sort by author name first last, secondary sort by title
|
||||
return [[Sequelize.literal('`libraryItem`.`authorNamesFirstLast` COLLATE NOCASE'), dir], getTitleOrder()]
|
||||
} else if (sortBy === 'media.metadata.title') {
|
||||
if (collapseseries) {
|
||||
return [[Sequelize.literal('display_title COLLATE NOCASE'), dir]]
|
||||
}
|
||||
|
||||
if (global.ServerSettings.sortingIgnorePrefix) {
|
||||
return [[Sequelize.literal('`libraryItem`.`titleIgnorePrefix` COLLATE NOCASE'), dir]]
|
||||
} else {
|
||||
return [[Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]]
|
||||
}
|
||||
return [getTitleOrder()]
|
||||
} else if (sortBy === 'sequence') {
|
||||
const nullDir = sortDesc ? 'DESC NULLS FIRST' : 'ASC NULLS LAST'
|
||||
return [[Sequelize.literal(`CAST(\`series.bookSeries.sequence\` AS FLOAT) ${nullDir}`)]]
|
||||
|
||||
Reference in New Issue
Block a user