mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-04-20 01:17:45 +02:00
Add jsdoc types to remaining models
This commit is contained in:
parent
0bc89cd40f
commit
a98942a361
@ -92,27 +92,27 @@ class Database {
|
||||
}
|
||||
|
||||
buildModels(force = false) {
|
||||
require('./models/User')(this.sequelize)
|
||||
require('./models/User').init(this.sequelize)
|
||||
require('./models/Library').init(this.sequelize)
|
||||
require('./models/LibraryFolder').init(this.sequelize)
|
||||
require('./models/Book').init(this.sequelize)
|
||||
require('./models/Podcast')(this.sequelize)
|
||||
require('./models/PodcastEpisode')(this.sequelize)
|
||||
require('./models/LibraryItem')(this.sequelize)
|
||||
require('./models/MediaProgress')(this.sequelize)
|
||||
require('./models/Series')(this.sequelize)
|
||||
require('./models/Podcast').init(this.sequelize)
|
||||
require('./models/PodcastEpisode').init(this.sequelize)
|
||||
require('./models/LibraryItem').init(this.sequelize)
|
||||
require('./models/MediaProgress').init(this.sequelize)
|
||||
require('./models/Series').init(this.sequelize)
|
||||
require('./models/BookSeries').init(this.sequelize)
|
||||
require('./models/Author').init(this.sequelize)
|
||||
require('./models/BookAuthor').init(this.sequelize)
|
||||
require('./models/Collection').init(this.sequelize)
|
||||
require('./models/CollectionBook').init(this.sequelize)
|
||||
require('./models/Playlist')(this.sequelize)
|
||||
require('./models/PlaylistMediaItem')(this.sequelize)
|
||||
require('./models/Playlist').init(this.sequelize)
|
||||
require('./models/PlaylistMediaItem').init(this.sequelize)
|
||||
require('./models/Device').init(this.sequelize)
|
||||
require('./models/PlaybackSession')(this.sequelize)
|
||||
require('./models/PlaybackSession').init(this.sequelize)
|
||||
require('./models/Feed').init(this.sequelize)
|
||||
require('./models/FeedEpisode').init(this.sequelize)
|
||||
require('./models/Setting')(this.sequelize)
|
||||
require('./models/Setting').init(this.sequelize)
|
||||
|
||||
return this.sequelize.sync({ force, alter: false })
|
||||
}
|
||||
|
@ -4,8 +4,55 @@ const oldLibraryItem = require('../objects/LibraryItem')
|
||||
const libraryFilters = require('../utils/queries/libraryFilters')
|
||||
const { areEquivalent } = require('../utils/index')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
|
||||
class LibraryItem extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {string} */
|
||||
this.ino
|
||||
/** @type {string} */
|
||||
this.path
|
||||
/** @type {string} */
|
||||
this.relPath
|
||||
/** @type {UUIDV4} */
|
||||
this.mediaId
|
||||
/** @type {string} */
|
||||
this.mediaType
|
||||
/** @type {boolean} */
|
||||
this.isFile
|
||||
/** @type {boolean} */
|
||||
this.isMissing
|
||||
/** @type {boolean} */
|
||||
this.isInvalid
|
||||
/** @type {Date} */
|
||||
this.mtime
|
||||
/** @type {Date} */
|
||||
this.ctime
|
||||
/** @type {Date} */
|
||||
this.birthtime
|
||||
/** @type {BigInt} */
|
||||
this.size
|
||||
/** @type {Date} */
|
||||
this.lastScan
|
||||
/** @type {string} */
|
||||
this.lastScanVersion
|
||||
/** @type {Object} */
|
||||
this.libraryFiles
|
||||
/** @type {Object} */
|
||||
this.extraData
|
||||
/** @type {UUIDV4} */
|
||||
this.libraryId
|
||||
/** @type {UUIDV4} */
|
||||
this.libraryFolderId
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all podcast episodes, all library items in chunks of 500, then maps them to old library items
|
||||
* @todo this is a temporary solution until we can use the sqlite without loading all the library items on init
|
||||
@ -15,7 +62,7 @@ module.exports = (sequelize) => {
|
||||
static async loadAllLibraryItems() {
|
||||
let start = Date.now()
|
||||
Logger.info(`[LibraryItem] Loading podcast episodes...`)
|
||||
const podcastEpisodes = await sequelize.models.podcastEpisode.findAll()
|
||||
const podcastEpisodes = await this.sequelize.models.podcastEpisode.findAll()
|
||||
Logger.info(`[LibraryItem] Finished loading ${podcastEpisodes.length} podcast episodes in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||
|
||||
start = Date.now()
|
||||
@ -69,16 +116,16 @@ module.exports = (sequelize) => {
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
model: this.sequelize.models.book,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.author,
|
||||
model: this.sequelize.models.author,
|
||||
through: {
|
||||
attributes: ['createdAt']
|
||||
}
|
||||
},
|
||||
{
|
||||
model: sequelize.models.series,
|
||||
model: this.sequelize.models.series,
|
||||
through: {
|
||||
attributes: ['sequence', 'createdAt']
|
||||
}
|
||||
@ -86,14 +133,14 @@ module.exports = (sequelize) => {
|
||||
]
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcast
|
||||
model: this.sequelize.models.podcast
|
||||
}
|
||||
],
|
||||
order: [
|
||||
['createdAt', 'ASC'],
|
||||
// Ensure author & series stay in the same order
|
||||
[sequelize.models.book, sequelize.models.author, sequelize.models.bookAuthor, 'createdAt', 'ASC'],
|
||||
[sequelize.models.book, sequelize.models.series, 'bookSeries', 'createdAt', 'ASC']
|
||||
[this.sequelize.models.book, this.sequelize.models.author, this.sequelize.models.bookAuthor, 'createdAt', 'ASC'],
|
||||
[this.sequelize.models.book, this.sequelize.models.series, 'bookSeries', 'createdAt', 'ASC']
|
||||
],
|
||||
offset,
|
||||
limit
|
||||
@ -110,16 +157,16 @@ module.exports = (sequelize) => {
|
||||
where,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
model: this.sequelize.models.book,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.author,
|
||||
model: this.sequelize.models.author,
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
},
|
||||
{
|
||||
model: sequelize.models.series,
|
||||
model: this.sequelize.models.series,
|
||||
through: {
|
||||
attributes: ['sequence']
|
||||
}
|
||||
@ -127,10 +174,10 @@ module.exports = (sequelize) => {
|
||||
]
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcast,
|
||||
model: this.sequelize.models.podcast,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.podcastEpisode
|
||||
model: this.sequelize.models.podcastEpisode
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -148,9 +195,9 @@ module.exports = (sequelize) => {
|
||||
static getOldLibraryItem(libraryItemExpanded) {
|
||||
let media = null
|
||||
if (libraryItemExpanded.mediaType === 'book') {
|
||||
media = sequelize.models.book.getOldBook(libraryItemExpanded)
|
||||
media = this.sequelize.models.book.getOldBook(libraryItemExpanded)
|
||||
} else if (libraryItemExpanded.mediaType === 'podcast') {
|
||||
media = sequelize.models.podcast.getOldPodcast(libraryItemExpanded)
|
||||
media = this.sequelize.models.podcast.getOldPodcast(libraryItemExpanded)
|
||||
}
|
||||
|
||||
return new oldLibraryItem({
|
||||
@ -181,30 +228,30 @@ module.exports = (sequelize) => {
|
||||
const newLibraryItem = await this.create(this.getFromOld(oldLibraryItem))
|
||||
|
||||
if (oldLibraryItem.mediaType === 'book') {
|
||||
const bookObj = sequelize.models.book.getFromOld(oldLibraryItem.media)
|
||||
const bookObj = this.sequelize.models.book.getFromOld(oldLibraryItem.media)
|
||||
bookObj.libraryItemId = newLibraryItem.id
|
||||
const newBook = await sequelize.models.book.create(bookObj)
|
||||
const newBook = await this.sequelize.models.book.create(bookObj)
|
||||
|
||||
const oldBookAuthors = oldLibraryItem.media.metadata.authors || []
|
||||
const oldBookSeriesAll = oldLibraryItem.media.metadata.series || []
|
||||
|
||||
for (const oldBookAuthor of oldBookAuthors) {
|
||||
await sequelize.models.bookAuthor.create({ authorId: oldBookAuthor.id, bookId: newBook.id })
|
||||
await this.sequelize.models.bookAuthor.create({ authorId: oldBookAuthor.id, bookId: newBook.id })
|
||||
}
|
||||
for (const oldSeries of oldBookSeriesAll) {
|
||||
await sequelize.models.bookSeries.create({ seriesId: oldSeries.id, bookId: newBook.id, sequence: oldSeries.sequence })
|
||||
await this.sequelize.models.bookSeries.create({ seriesId: oldSeries.id, bookId: newBook.id, sequence: oldSeries.sequence })
|
||||
}
|
||||
} else if (oldLibraryItem.mediaType === 'podcast') {
|
||||
const podcastObj = sequelize.models.podcast.getFromOld(oldLibraryItem.media)
|
||||
const podcastObj = this.sequelize.models.podcast.getFromOld(oldLibraryItem.media)
|
||||
podcastObj.libraryItemId = newLibraryItem.id
|
||||
const newPodcast = await sequelize.models.podcast.create(podcastObj)
|
||||
const newPodcast = await this.sequelize.models.podcast.create(podcastObj)
|
||||
|
||||
const oldEpisodes = oldLibraryItem.media.episodes || []
|
||||
for (const oldEpisode of oldEpisodes) {
|
||||
const episodeObj = sequelize.models.podcastEpisode.getFromOld(oldEpisode)
|
||||
const episodeObj = this.sequelize.models.podcastEpisode.getFromOld(oldEpisode)
|
||||
episodeObj.libraryItemId = newLibraryItem.id
|
||||
episodeObj.podcastId = newPodcast.id
|
||||
await sequelize.models.podcastEpisode.create(episodeObj)
|
||||
await this.sequelize.models.podcastEpisode.create(episodeObj)
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,16 +262,16 @@ module.exports = (sequelize) => {
|
||||
const libraryItemExpanded = await this.findByPk(oldLibraryItem.id, {
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
model: this.sequelize.models.book,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.author,
|
||||
model: this.sequelize.models.author,
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
},
|
||||
{
|
||||
model: sequelize.models.series,
|
||||
model: this.sequelize.models.series,
|
||||
through: {
|
||||
attributes: ['id', 'sequence']
|
||||
}
|
||||
@ -232,10 +279,10 @@ module.exports = (sequelize) => {
|
||||
]
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcast,
|
||||
model: this.sequelize.models.podcast,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.podcastEpisode
|
||||
model: this.sequelize.models.podcastEpisode
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -249,7 +296,7 @@ module.exports = (sequelize) => {
|
||||
if (libraryItemExpanded.media) {
|
||||
let updatedMedia = null
|
||||
if (libraryItemExpanded.mediaType === 'podcast') {
|
||||
updatedMedia = sequelize.models.podcast.getFromOld(oldLibraryItem.media)
|
||||
updatedMedia = this.sequelize.models.podcast.getFromOld(oldLibraryItem.media)
|
||||
|
||||
const existingPodcastEpisodes = libraryItemExpanded.media.podcastEpisodes || []
|
||||
const updatedPodcastEpisodes = oldLibraryItem.media.episodes || []
|
||||
@ -266,10 +313,10 @@ module.exports = (sequelize) => {
|
||||
const existingEpisodeMatch = existingPodcastEpisodes.find(ep => ep.id === updatedPodcastEpisode.id)
|
||||
if (!existingEpisodeMatch) {
|
||||
Logger.dev(`[LibraryItem] "${libraryItemExpanded.media.title}" episode "${updatedPodcastEpisode.title}" was added`)
|
||||
await sequelize.models.podcastEpisode.createFromOld(updatedPodcastEpisode)
|
||||
await this.sequelize.models.podcastEpisode.createFromOld(updatedPodcastEpisode)
|
||||
hasUpdates = true
|
||||
} else {
|
||||
const updatedEpisodeCleaned = sequelize.models.podcastEpisode.getFromOld(updatedPodcastEpisode)
|
||||
const updatedEpisodeCleaned = this.sequelize.models.podcastEpisode.getFromOld(updatedPodcastEpisode)
|
||||
let episodeHasUpdates = false
|
||||
for (const key in updatedEpisodeCleaned) {
|
||||
let existingValue = existingEpisodeMatch[key]
|
||||
@ -287,7 +334,7 @@ module.exports = (sequelize) => {
|
||||
}
|
||||
}
|
||||
} else if (libraryItemExpanded.mediaType === 'book') {
|
||||
updatedMedia = sequelize.models.book.getFromOld(oldLibraryItem.media)
|
||||
updatedMedia = this.sequelize.models.book.getFromOld(oldLibraryItem.media)
|
||||
|
||||
const existingAuthors = libraryItemExpanded.media.authors || []
|
||||
const existingSeriesAll = libraryItemExpanded.media.series || []
|
||||
@ -298,7 +345,7 @@ module.exports = (sequelize) => {
|
||||
// Author was removed from Book
|
||||
if (!updatedAuthors.some(au => au.id === existingAuthor.id)) {
|
||||
Logger.dev(`[LibraryItem] "${libraryItemExpanded.media.title}" author "${existingAuthor.name}" was removed`)
|
||||
await sequelize.models.bookAuthor.removeByIds(existingAuthor.id, libraryItemExpanded.media.id)
|
||||
await this.sequelize.models.bookAuthor.removeByIds(existingAuthor.id, libraryItemExpanded.media.id)
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
@ -306,7 +353,7 @@ module.exports = (sequelize) => {
|
||||
// Author was added
|
||||
if (!existingAuthors.some(au => au.id === updatedAuthor.id)) {
|
||||
Logger.dev(`[LibraryItem] "${libraryItemExpanded.media.title}" author "${updatedAuthor.name}" was added`)
|
||||
await sequelize.models.bookAuthor.create({ authorId: updatedAuthor.id, bookId: libraryItemExpanded.media.id })
|
||||
await this.sequelize.models.bookAuthor.create({ authorId: updatedAuthor.id, bookId: libraryItemExpanded.media.id })
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
@ -314,7 +361,7 @@ module.exports = (sequelize) => {
|
||||
// Series was removed
|
||||
if (!updatedSeriesAll.some(se => se.id === existingSeries.id)) {
|
||||
Logger.dev(`[LibraryItem] "${libraryItemExpanded.media.title}" series "${existingSeries.name}" was removed`)
|
||||
await sequelize.models.bookSeries.removeByIds(existingSeries.id, libraryItemExpanded.media.id)
|
||||
await this.sequelize.models.bookSeries.removeByIds(existingSeries.id, libraryItemExpanded.media.id)
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
@ -323,7 +370,7 @@ module.exports = (sequelize) => {
|
||||
const existingSeriesMatch = existingSeriesAll.find(se => se.id === updatedSeries.id)
|
||||
if (!existingSeriesMatch) {
|
||||
Logger.dev(`[LibraryItem] "${libraryItemExpanded.media.title}" series "${updatedSeries.name}" was added`)
|
||||
await sequelize.models.bookSeries.create({ seriesId: updatedSeries.id, bookId: libraryItemExpanded.media.id, sequence: updatedSeries.sequence })
|
||||
await this.sequelize.models.bookSeries.create({ seriesId: updatedSeries.id, bookId: libraryItemExpanded.media.id, sequence: updatedSeries.sequence })
|
||||
hasUpdates = true
|
||||
} else if (existingSeriesMatch.bookSeries.sequence !== updatedSeries.sequence) {
|
||||
Logger.dev(`[LibraryItem] "${libraryItemExpanded.media.title}" series "${updatedSeries.name}" sequence was updated from "${existingSeriesMatch.bookSeries.sequence}" to "${updatedSeries.sequence}"`)
|
||||
@ -415,16 +462,16 @@ module.exports = (sequelize) => {
|
||||
const libraryItem = await this.findByPk(libraryItemId, {
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
model: this.sequelize.models.book,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.author,
|
||||
model: this.sequelize.models.author,
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
},
|
||||
{
|
||||
model: sequelize.models.series,
|
||||
model: this.sequelize.models.series,
|
||||
through: {
|
||||
attributes: ['sequence']
|
||||
}
|
||||
@ -432,10 +479,10 @@ module.exports = (sequelize) => {
|
||||
]
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcast,
|
||||
model: this.sequelize.models.podcast,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.podcastEpisode
|
||||
model: this.sequelize.models.podcastEpisode
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -467,7 +514,7 @@ module.exports = (sequelize) => {
|
||||
oldLibraryItem.media.metadata.series = li.series
|
||||
}
|
||||
if (li.rssFeed) {
|
||||
oldLibraryItem.rssFeed = sequelize.models.feed.getOldFeed(li.rssFeed).toJSONMinified()
|
||||
oldLibraryItem.rssFeed = this.sequelize.models.feed.getOldFeed(li.rssFeed).toJSONMinified()
|
||||
}
|
||||
if (li.media.numEpisodes) {
|
||||
oldLibraryItem.media.numEpisodes = li.media.numEpisodes
|
||||
@ -690,12 +737,16 @@ module.exports = (sequelize) => {
|
||||
|
||||
getMedia(options) {
|
||||
if (!this.mediaType) return Promise.resolve(null)
|
||||
const mixinMethodName = `get${sequelize.uppercaseFirst(this.mediaType)}`
|
||||
const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaType)}`
|
||||
return this[mixinMethodName](options)
|
||||
}
|
||||
}
|
||||
|
||||
LibraryItem.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -791,6 +842,7 @@ module.exports = (sequelize) => {
|
||||
media.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
return LibraryItem
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LibraryItem
|
||||
|
@ -1,11 +1,39 @@
|
||||
const { DataTypes, Model } = require('sequelize')
|
||||
|
||||
/*
|
||||
* Polymorphic association: https://sequelize.org/docs/v6/advanced-association-concepts/polymorphic-associations/
|
||||
* Book has many MediaProgress. PodcastEpisode has many MediaProgress.
|
||||
*/
|
||||
module.exports = (sequelize) => {
|
||||
class MediaProgress extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {UUIDV4} */
|
||||
this.mediaItemId
|
||||
/** @type {string} */
|
||||
this.mediaItemType
|
||||
/** @type {number} */
|
||||
this.duration
|
||||
/** @type {number} */
|
||||
this.currentTime
|
||||
/** @type {boolean} */
|
||||
this.isFinished
|
||||
/** @type {boolean} */
|
||||
this.hideFromContinueListening
|
||||
/** @type {string} */
|
||||
this.ebookLocation
|
||||
/** @type {number} */
|
||||
this.ebookProgress
|
||||
/** @type {Date} */
|
||||
this.finishedAt
|
||||
/** @type {Object} */
|
||||
this.extraData
|
||||
/** @type {UUIDV4} */
|
||||
this.userId
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
}
|
||||
|
||||
getOldMediaProgress() {
|
||||
const isPodcastEpisode = this.mediaItemType === 'podcastEpisode'
|
||||
|
||||
@ -66,13 +94,20 @@ module.exports = (sequelize) => {
|
||||
|
||||
getMediaItem(options) {
|
||||
if (!this.mediaItemType) return Promise.resolve(null)
|
||||
const mixinMethodName = `get${sequelize.uppercaseFirst(this.mediaItemType)}`
|
||||
const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaItemType)}`
|
||||
return this[mixinMethodName](options)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MediaProgress.init({
|
||||
/**
|
||||
* Initialize model
|
||||
*
|
||||
* Polymorphic association: Book has many MediaProgress. PodcastEpisode has many MediaProgress.
|
||||
* @see https://sequelize.org/docs/v6/advanced-association-concepts/polymorphic-associations/
|
||||
*
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -143,6 +178,7 @@ module.exports = (sequelize) => {
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
MediaProgress.belongsTo(user)
|
||||
|
||||
return MediaProgress
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MediaProgress
|
@ -2,14 +2,63 @@ const { DataTypes, Model } = require('sequelize')
|
||||
|
||||
const oldPlaybackSession = require('../objects/PlaybackSession')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
|
||||
class PlaybackSession extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {UUIDV4} */
|
||||
this.mediaItemId
|
||||
/** @type {string} */
|
||||
this.mediaItemType
|
||||
/** @type {string} */
|
||||
this.displayTitle
|
||||
/** @type {string} */
|
||||
this.displayAuthor
|
||||
/** @type {number} */
|
||||
this.duration
|
||||
/** @type {number} */
|
||||
this.playMethod
|
||||
/** @type {string} */
|
||||
this.mediaPlayer
|
||||
/** @type {number} */
|
||||
this.startTime
|
||||
/** @type {number} */
|
||||
this.currentTime
|
||||
/** @type {string} */
|
||||
this.serverVersion
|
||||
/** @type {string} */
|
||||
this.coverPath
|
||||
/** @type {number} */
|
||||
this.timeListening
|
||||
/** @type {Object} */
|
||||
this.mediaMetadata
|
||||
/** @type {string} */
|
||||
this.date
|
||||
/** @type {string} */
|
||||
this.dayOfWeek
|
||||
/** @type {Object} */
|
||||
this.extraData
|
||||
/** @type {UUIDV4} */
|
||||
this.userId
|
||||
/** @type {UUIDV4} */
|
||||
this.deviceId
|
||||
/** @type {UUIDV4} */
|
||||
this.libraryId
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
}
|
||||
|
||||
static async getOldPlaybackSessions(where = null) {
|
||||
const playbackSessions = await this.findAll({
|
||||
where,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.device
|
||||
model: this.sequelize.models.device
|
||||
}
|
||||
]
|
||||
})
|
||||
@ -20,7 +69,7 @@ module.exports = (sequelize) => {
|
||||
const playbackSession = await this.findByPk(sessionId, {
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.device
|
||||
model: this.sequelize.models.device
|
||||
}
|
||||
]
|
||||
})
|
||||
@ -112,12 +161,16 @@ module.exports = (sequelize) => {
|
||||
|
||||
getMediaItem(options) {
|
||||
if (!this.mediaItemType) return Promise.resolve(null)
|
||||
const mixinMethodName = `get${sequelize.uppercaseFirst(this.mediaItemType)}`
|
||||
const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaItemType)}`
|
||||
return this[mixinMethodName](options)
|
||||
}
|
||||
}
|
||||
|
||||
PlaybackSession.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -193,6 +246,7 @@ module.exports = (sequelize) => {
|
||||
delete instance.dataValues.podcastEpisode
|
||||
}
|
||||
})
|
||||
|
||||
return PlaybackSession
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PlaybackSession
|
||||
|
@ -3,22 +3,40 @@ const Logger = require('../Logger')
|
||||
|
||||
const oldPlaylist = require('../objects/Playlist')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class Playlist extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {string} */
|
||||
this.name
|
||||
/** @type {string} */
|
||||
this.description
|
||||
/** @type {UUIDV4} */
|
||||
this.libraryId
|
||||
/** @type {UUIDV4} */
|
||||
this.userId
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
static async getOldPlaylists() {
|
||||
const playlists = await this.findAll({
|
||||
include: {
|
||||
model: sequelize.models.playlistMediaItem,
|
||||
model: this.sequelize.models.playlistMediaItem,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.book,
|
||||
include: this.sequelize.models.libraryItem
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcastEpisode,
|
||||
model: this.sequelize.models.podcastEpisode,
|
||||
include: {
|
||||
model: sequelize.models.podcast,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.podcast,
|
||||
include: this.sequelize.models.libraryItem
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -62,24 +80,24 @@ module.exports = (sequelize) => {
|
||||
this.playlistMediaItems = await this.getPlaylistMediaItems({
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.book,
|
||||
include: this.sequelize.models.libraryItem
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcastEpisode,
|
||||
model: this.sequelize.models.podcastEpisode,
|
||||
include: {
|
||||
model: sequelize.models.podcast,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.podcast,
|
||||
include: this.sequelize.models.libraryItem
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [['order', 'ASC']]
|
||||
}) || []
|
||||
|
||||
const oldPlaylist = sequelize.models.playlist.getOldPlaylist(this)
|
||||
const oldPlaylist = this.sequelize.models.playlist.getOldPlaylist(this)
|
||||
const libraryItemIds = oldPlaylist.items.map(i => i.libraryItemId)
|
||||
|
||||
let libraryItems = await sequelize.models.libraryItem.getAllOldLibraryItems({
|
||||
let libraryItems = await this.sequelize.models.libraryItem.getAllOldLibraryItems({
|
||||
id: libraryItemIds
|
||||
})
|
||||
|
||||
@ -88,7 +106,7 @@ module.exports = (sequelize) => {
|
||||
if (include?.includes('rssfeed')) {
|
||||
const feeds = await this.getFeeds()
|
||||
if (feeds?.length) {
|
||||
playlistExpanded.rssFeed = sequelize.models.feed.getOldFeed(feeds[0])
|
||||
playlistExpanded.rssFeed = this.sequelize.models.feed.getOldFeed(feeds[0])
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,17 +145,17 @@ module.exports = (sequelize) => {
|
||||
if (!playlistId) return null
|
||||
const playlist = await this.findByPk(playlistId, {
|
||||
include: {
|
||||
model: sequelize.models.playlistMediaItem,
|
||||
model: this.sequelize.models.playlistMediaItem,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.book,
|
||||
include: this.sequelize.models.libraryItem
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcastEpisode,
|
||||
model: this.sequelize.models.podcastEpisode,
|
||||
include: {
|
||||
model: sequelize.models.podcast,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.podcast,
|
||||
include: this.sequelize.models.libraryItem
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -166,17 +184,17 @@ module.exports = (sequelize) => {
|
||||
const playlists = await this.findAll({
|
||||
where: whereQuery,
|
||||
include: {
|
||||
model: sequelize.models.playlistMediaItem,
|
||||
model: this.sequelize.models.playlistMediaItem,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.book,
|
||||
include: this.sequelize.models.libraryItem
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcastEpisode,
|
||||
model: this.sequelize.models.podcastEpisode,
|
||||
include: {
|
||||
model: sequelize.models.podcast,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.podcast,
|
||||
include: this.sequelize.models.libraryItem
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -212,7 +230,7 @@ module.exports = (sequelize) => {
|
||||
static async getPlaylistsForMediaItemIds(mediaItemIds) {
|
||||
if (!mediaItemIds?.length) return []
|
||||
|
||||
const playlistMediaItemsExpanded = await sequelize.models.playlistMediaItem.findAll({
|
||||
const playlistMediaItemsExpanded = await this.sequelize.models.playlistMediaItem.findAll({
|
||||
where: {
|
||||
mediaItemId: {
|
||||
[Op.in]: mediaItemIds
|
||||
@ -220,19 +238,19 @@ module.exports = (sequelize) => {
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.playlist,
|
||||
model: this.sequelize.models.playlist,
|
||||
include: {
|
||||
model: sequelize.models.playlistMediaItem,
|
||||
model: this.sequelize.models.playlistMediaItem,
|
||||
include: [
|
||||
{
|
||||
model: sequelize.models.book,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.book,
|
||||
include: this.sequelize.models.libraryItem
|
||||
},
|
||||
{
|
||||
model: sequelize.models.podcastEpisode,
|
||||
model: this.sequelize.models.podcastEpisode,
|
||||
include: {
|
||||
model: sequelize.models.podcast,
|
||||
include: sequelize.models.libraryItem
|
||||
model: this.sequelize.models.podcast,
|
||||
include: this.sequelize.models.libraryItem
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -265,9 +283,13 @@ module.exports = (sequelize) => {
|
||||
}
|
||||
return playlists
|
||||
}
|
||||
}
|
||||
|
||||
Playlist.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -315,6 +337,7 @@ module.exports = (sequelize) => {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
return Playlist
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Playlist
|
@ -1,7 +1,23 @@
|
||||
const { DataTypes, Model } = require('sequelize')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class PlaylistMediaItem extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {UUIDV4} */
|
||||
this.mediaItemId
|
||||
/** @type {string} */
|
||||
this.mediaItemType
|
||||
/** @type {number} */
|
||||
this.order
|
||||
/** @type {UUIDV4} */
|
||||
this.playlistId
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
}
|
||||
|
||||
static removeByIds(playlistId, mediaItemId) {
|
||||
return this.destroy({
|
||||
where: {
|
||||
@ -13,12 +29,16 @@ module.exports = (sequelize) => {
|
||||
|
||||
getMediaItem(options) {
|
||||
if (!this.mediaItemType) return Promise.resolve(null)
|
||||
const mixinMethodName = `get${sequelize.uppercaseFirst(this.mediaItemType)}`
|
||||
const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaItemType)}`
|
||||
return this[mixinMethodName](options)
|
||||
}
|
||||
}
|
||||
|
||||
PlaylistMediaItem.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -79,6 +99,7 @@ module.exports = (sequelize) => {
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
PlaylistMediaItem.belongsTo(playlist)
|
||||
|
||||
return PlaylistMediaItem
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PlaylistMediaItem
|
||||
|
@ -1,7 +1,57 @@
|
||||
const { DataTypes, Model } = require('sequelize')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class Podcast extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {string} */
|
||||
this.title
|
||||
/** @type {string} */
|
||||
this.titleIgnorePrefix
|
||||
/** @type {string} */
|
||||
this.author
|
||||
/** @type {string} */
|
||||
this.releaseDate
|
||||
/** @type {string} */
|
||||
this.feedURL
|
||||
/** @type {string} */
|
||||
this.imageURL
|
||||
/** @type {string} */
|
||||
this.description
|
||||
/** @type {string} */
|
||||
this.itunesPageURL
|
||||
/** @type {string} */
|
||||
this.itunesId
|
||||
/** @type {string} */
|
||||
this.itunesArtistId
|
||||
/** @type {string} */
|
||||
this.language
|
||||
/** @type {string} */
|
||||
this.podcastType
|
||||
/** @type {boolean} */
|
||||
this.explicit
|
||||
/** @type {boolean} */
|
||||
this.autoDownloadEpisodes
|
||||
/** @type {string} */
|
||||
this.autoDownloadSchedule
|
||||
/** @type {Date} */
|
||||
this.lastEpisodeCheck
|
||||
/** @type {number} */
|
||||
this.maxEpisodesToKeep
|
||||
/** @type {string} */
|
||||
this.coverPath
|
||||
/** @type {Object} */
|
||||
this.tags
|
||||
/** @type {Object} */
|
||||
this.genres
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
static getOldPodcast(libraryItemExpanded) {
|
||||
const podcastExpanded = libraryItemExpanded.media
|
||||
const podcastEpisodes = podcastExpanded.podcastEpisodes?.map(ep => ep.getOldPodcastEpisode(libraryItemExpanded.id)).sort((a, b) => a.index - b.index)
|
||||
@ -61,9 +111,13 @@ module.exports = (sequelize) => {
|
||||
genres: oldPodcastMetadata.genres
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Podcast.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -95,6 +149,7 @@ module.exports = (sequelize) => {
|
||||
sequelize,
|
||||
modelName: 'podcast'
|
||||
})
|
||||
|
||||
return Podcast
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Podcast
|
@ -1,7 +1,49 @@
|
||||
const { DataTypes, Model } = require('sequelize')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class PodcastEpisode extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {number} */
|
||||
this.index
|
||||
/** @type {string} */
|
||||
this.season
|
||||
/** @type {string} */
|
||||
this.episode
|
||||
/** @type {string} */
|
||||
this.episodeType
|
||||
/** @type {string} */
|
||||
this.title
|
||||
/** @type {string} */
|
||||
this.subtitle
|
||||
/** @type {string} */
|
||||
this.description
|
||||
/** @type {string} */
|
||||
this.pubDate
|
||||
/** @type {string} */
|
||||
this.enclosureURL
|
||||
/** @type {BigInt} */
|
||||
this.enclosureSize
|
||||
/** @type {string} */
|
||||
this.enclosureType
|
||||
/** @type {Date} */
|
||||
this.publishedAt
|
||||
/** @type {Object} */
|
||||
this.audioFile
|
||||
/** @type {Object} */
|
||||
this.chapters
|
||||
/** @type {Object} */
|
||||
this.extraData
|
||||
/** @type {UUIDV4} */
|
||||
this.podcastId
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
getOldPodcastEpisode(libraryItemId = null) {
|
||||
let enclosure = null
|
||||
if (this.enclosureURL) {
|
||||
@ -63,9 +105,13 @@ module.exports = (sequelize) => {
|
||||
extraData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PodcastEpisode.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -97,6 +143,7 @@ module.exports = (sequelize) => {
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
PodcastEpisode.belongsTo(podcast)
|
||||
|
||||
return PodcastEpisode
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PodcastEpisode
|
@ -2,8 +2,26 @@ const { DataTypes, Model } = require('sequelize')
|
||||
|
||||
const oldSeries = require('../objects/entities/Series')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class Series extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {string} */
|
||||
this.name
|
||||
/** @type {string} */
|
||||
this.nameIgnorePrefix
|
||||
/** @type {string} */
|
||||
this.description
|
||||
/** @type {UUIDV4} */
|
||||
this.libraryId
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
static async getAllOldSeries() {
|
||||
const series = await this.findAll()
|
||||
return series.map(se => se.getOldSeries())
|
||||
@ -56,9 +74,13 @@ module.exports = (sequelize) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Series.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -77,6 +99,7 @@ module.exports = (sequelize) => {
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
Series.belongsTo(library)
|
||||
|
||||
return Series
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Series
|
@ -4,8 +4,20 @@ const oldEmailSettings = require('../objects/settings/EmailSettings')
|
||||
const oldServerSettings = require('../objects/settings/ServerSettings')
|
||||
const oldNotificationSettings = require('../objects/settings/NotificationSettings')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class Setting extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {string} */
|
||||
this.key
|
||||
/** @type {Object} */
|
||||
this.value
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
static async getOldSettings() {
|
||||
const settings = (await this.findAll()).map(se => se.value)
|
||||
|
||||
@ -28,9 +40,13 @@ module.exports = (sequelize) => {
|
||||
value: setting
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Setting.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
key: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
@ -40,6 +56,7 @@ module.exports = (sequelize) => {
|
||||
sequelize,
|
||||
modelName: 'setting'
|
||||
})
|
||||
|
||||
return Setting
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Setting
|
@ -3,15 +3,45 @@ const { DataTypes, Model, Op } = require('sequelize')
|
||||
const Logger = require('../Logger')
|
||||
const oldUser = require('../objects/user/User')
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class User extends Model {
|
||||
constructor(values, options) {
|
||||
super(values, options)
|
||||
|
||||
/** @type {UUIDV4} */
|
||||
this.id
|
||||
/** @type {string} */
|
||||
this.username
|
||||
/** @type {string} */
|
||||
this.email
|
||||
/** @type {string} */
|
||||
this.pash
|
||||
/** @type {string} */
|
||||
this.type
|
||||
/** @type {boolean} */
|
||||
this.isActive
|
||||
/** @type {boolean} */
|
||||
this.isLocked
|
||||
/** @type {Date} */
|
||||
this.lastSeen
|
||||
/** @type {Object} */
|
||||
this.permissions
|
||||
/** @type {Object} */
|
||||
this.bookmarks
|
||||
/** @type {Object} */
|
||||
this.extraData
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
/** @type {Date} */
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all oldUsers
|
||||
* @returns {Promise<oldUser>}
|
||||
*/
|
||||
static async getOldUsers() {
|
||||
const users = await this.findAll({
|
||||
include: sequelize.models.mediaProgress
|
||||
include: this.sequelize.models.mediaProgress
|
||||
})
|
||||
return users.map(u => this.getOldUser(u))
|
||||
}
|
||||
@ -139,7 +169,7 @@ module.exports = (sequelize) => {
|
||||
}
|
||||
]
|
||||
},
|
||||
include: sequelize.models.mediaProgress
|
||||
include: this.sequelize.models.mediaProgress
|
||||
})
|
||||
if (!user) return null
|
||||
return this.getOldUser(user)
|
||||
@ -158,7 +188,7 @@ module.exports = (sequelize) => {
|
||||
[Op.like]: username
|
||||
}
|
||||
},
|
||||
include: sequelize.models.mediaProgress
|
||||
include: this.sequelize.models.mediaProgress
|
||||
})
|
||||
if (!user) return null
|
||||
return this.getOldUser(user)
|
||||
@ -172,7 +202,7 @@ module.exports = (sequelize) => {
|
||||
static async getUserById(userId) {
|
||||
if (!userId) return null
|
||||
const user = await this.findByPk(userId, {
|
||||
include: sequelize.models.mediaProgress
|
||||
include: this.sequelize.models.mediaProgress
|
||||
})
|
||||
if (!user) return null
|
||||
return this.getOldUser(user)
|
||||
@ -206,9 +236,13 @@ module.exports = (sequelize) => {
|
||||
})
|
||||
return count > 0
|
||||
}
|
||||
}
|
||||
|
||||
User.init({
|
||||
/**
|
||||
* Initialize model
|
||||
* @param {import('../Database').sequelize} sequelize
|
||||
*/
|
||||
static init(sequelize) {
|
||||
super.init({
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
@ -235,6 +269,7 @@ module.exports = (sequelize) => {
|
||||
sequelize,
|
||||
modelName: 'user'
|
||||
})
|
||||
|
||||
return User
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = User
|
Loading…
Reference in New Issue
Block a user