Add jsdoc types to remaining models

This commit is contained in:
advplyr 2023-08-16 16:38:48 -05:00
parent 0bc89cd40f
commit a98942a361
11 changed files with 2302 additions and 1939 deletions

View File

@ -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 })
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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