Skip to content

Commit 6cef1e3

Browse files
authored
Merge pull request #3724 from advplyr/feed_migration
Refactor Feed model to create new feed for collection
2 parents ca2327a + b39268c commit 6cef1e3

25 files changed

+859
-1161
lines changed

server/Database.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -444,21 +444,6 @@ class Database {
444444
return updated
445445
}
446446

447-
async createFeed(oldFeed) {
448-
if (!this.sequelize) return false
449-
await this.models.feed.fullCreateFromOld(oldFeed)
450-
}
451-
452-
updateFeed(oldFeed) {
453-
if (!this.sequelize) return false
454-
return this.models.feed.fullUpdateFromOld(oldFeed)
455-
}
456-
457-
async removeFeed(feedId) {
458-
if (!this.sequelize) return false
459-
await this.models.feed.removeById(feedId)
460-
}
461-
462447
async createBulkBookAuthors(bookAuthors) {
463448
if (!this.sequelize) return false
464449
await this.models.bookAuthor.bulkCreate(bookAuthors)

server/Server.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ class Server {
7171
this.playbackSessionManager = new PlaybackSessionManager()
7272
this.podcastManager = new PodcastManager()
7373
this.audioMetadataManager = new AudioMetadataMangaer()
74-
this.rssFeedManager = new RssFeedManager()
7574
this.cronManager = new CronManager(this.podcastManager, this.playbackSessionManager)
7675
this.apiCacheManager = new ApiCacheManager()
7776
this.binaryManager = new BinaryManager()
@@ -137,7 +136,7 @@ class Server {
137136

138137
await ShareManager.init()
139138
await this.backupManager.init()
140-
await this.rssFeedManager.init()
139+
await RssFeedManager.init()
141140

142141
const libraries = await Database.libraryModel.getAllWithFolders()
143142
await this.cronManager.init(libraries)
@@ -291,14 +290,14 @@ class Server {
291290
// RSS Feed temp route
292291
router.get('/feed/:slug', (req, res) => {
293292
Logger.info(`[Server] Requesting rss feed ${req.params.slug}`)
294-
this.rssFeedManager.getFeed(req, res)
293+
RssFeedManager.getFeed(req, res)
295294
})
296295
router.get('/feed/:slug/cover*', (req, res) => {
297-
this.rssFeedManager.getFeedCover(req, res)
296+
RssFeedManager.getFeedCover(req, res)
298297
})
299298
router.get('/feed/:slug/item/:episodeId/*', (req, res) => {
300299
Logger.debug(`[Server] Requesting rss feed episode ${req.params.slug}/${req.params.episodeId}`)
301-
this.rssFeedManager.getFeedItem(req, res)
300+
RssFeedManager.getFeedItem(req, res)
302301
})
303302

304303
// Auth routes

server/controllers/CollectionController.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const Logger = require('../Logger')
44
const SocketAuthority = require('../SocketAuthority')
55
const Database = require('../Database')
66

7+
const RssFeedManager = require('../managers/RssFeedManager')
78
const Collection = require('../objects/Collection')
89

910
/**
@@ -115,6 +116,7 @@ class CollectionController {
115116
}
116117

117118
// If books array is passed in then update order in collection
119+
let collectionBooksUpdated = false
118120
if (req.body.books?.length) {
119121
const collectionBooks = await req.collection.getCollectionBooks({
120122
include: {
@@ -133,9 +135,15 @@ class CollectionController {
133135
await collectionBooks[i].update({
134136
order: i + 1
135137
})
136-
wasUpdated = true
138+
collectionBooksUpdated = true
137139
}
138140
}
141+
142+
if (collectionBooksUpdated) {
143+
req.collection.changed('updatedAt', true)
144+
await req.collection.save()
145+
wasUpdated = true
146+
}
139147
}
140148

141149
const jsonExpanded = await req.collection.getOldJsonExpanded()
@@ -148,14 +156,16 @@ class CollectionController {
148156
/**
149157
* DELETE: /api/collections/:id
150158
*
159+
* @this {import('../routers/ApiRouter')}
160+
*
151161
* @param {RequestWithUser} req
152162
* @param {Response} res
153163
*/
154164
async delete(req, res) {
155165
const jsonExpanded = await req.collection.getOldJsonExpanded()
156166

157167
// Close rss feed - remove from db and emit socket event
158-
await this.rssFeedManager.closeFeedForEntityId(req.collection.id)
168+
await RssFeedManager.closeFeedForEntityId(req.collection.id)
159169

160170
await req.collection.destroy()
161171

server/controllers/LibraryController.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const LibraryScanner = require('../scanner/LibraryScanner')
1818
const Scanner = require('../scanner/Scanner')
1919
const Database = require('../Database')
2020
const Watcher = require('../Watcher')
21+
const RssFeedManager = require('../managers/RssFeedManager')
22+
2123
const libraryFilters = require('../utils/queries/libraryFilters')
2224
const libraryItemsPodcastFilters = require('../utils/queries/libraryItemsPodcastFilters')
2325
const authorFilters = require('../utils/queries/authorFilters')
@@ -759,8 +761,8 @@ class LibraryController {
759761
}
760762

761763
if (include.includes('rssfeed')) {
762-
const feedObj = await this.rssFeedManager.findFeedForEntityId(seriesJson.id)
763-
seriesJson.rssFeed = feedObj?.toJSONMinified() || null
764+
const feedObj = await RssFeedManager.findFeedForEntityId(seriesJson.id)
765+
seriesJson.rssFeed = feedObj?.toOldJSONMinified() || null
764766
}
765767

766768
res.json(seriesJson)

server/controllers/LibraryItemController.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const { getAudioMimeTypeFromExtname, encodeUriPath } = require('../utils/fileUti
1313
const LibraryItemScanner = require('../scanner/LibraryItemScanner')
1414
const AudioFileScanner = require('../scanner/AudioFileScanner')
1515
const Scanner = require('../scanner/Scanner')
16+
17+
const RssFeedManager = require('../managers/RssFeedManager')
1618
const CacheManager = require('../managers/CacheManager')
1719
const CoverManager = require('../managers/CoverManager')
1820
const ShareManager = require('../managers/ShareManager')
@@ -48,8 +50,8 @@ class LibraryItemController {
4850
}
4951

5052
if (includeEntities.includes('rssfeed')) {
51-
const feedData = await this.rssFeedManager.findFeedForEntityId(item.id)
52-
item.rssFeed = feedData?.toJSONMinified() || null
53+
const feedData = await RssFeedManager.findFeedForEntityId(item.id)
54+
item.rssFeed = feedData?.toOldJSONMinified() || null
5355
}
5456

5557
if (item.mediaType === 'book' && req.user.isAdminOrUp && includeEntities.includes('share')) {

server/controllers/RSSFeedController.js

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
const { Request, Response, NextFunction } = require('express')
22
const Logger = require('../Logger')
33
const Database = require('../Database')
4-
const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilters')
4+
5+
const RssFeedManager = require('../managers/RssFeedManager')
56

67
/**
78
* @typedef RequestUserObject
@@ -22,10 +23,10 @@ class RSSFeedController {
2223
* @param {Response} res
2324
*/
2425
async getAll(req, res) {
25-
const feeds = await this.rssFeedManager.getFeeds()
26+
const feeds = await RssFeedManager.getFeeds()
2627
res.json({
27-
feeds: feeds.map((f) => f.toJSON()),
28-
minified: feeds.map((f) => f.toJSONMinified())
28+
feeds: feeds.map((f) => f.toOldJSON()),
29+
minified: feeds.map((f) => f.toOldJSONMinified())
2930
})
3031
}
3132

@@ -62,12 +63,12 @@ class RSSFeedController {
6263
}
6364

6465
// Check that this slug is not being used for another feed (slug will also be the Feed id)
65-
if (await this.rssFeedManager.findFeedBySlug(reqBody.slug)) {
66+
if (await RssFeedManager.checkExistsBySlug(reqBody.slug)) {
6667
Logger.error(`[RSSFeedController] Cannot open RSS feed because slug "${reqBody.slug}" is already in use`)
6768
return res.status(400).send('Slug already in use')
6869
}
6970

70-
const feed = await this.rssFeedManager.openFeedForItem(req.user.id, itemExpanded, reqBody)
71+
const feed = await RssFeedManager.openFeedForItem(req.user.id, itemExpanded, reqBody)
7172
if (!feed) {
7273
Logger.error(`[RSSFeedController] Failed to open RSS feed for item "${itemExpanded.media.title}"`)
7374
return res.status(500).send('Failed to open RSS feed')
@@ -87,35 +88,37 @@ class RSSFeedController {
8788
* @param {Response} res
8889
*/
8990
async openRSSFeedForCollection(req, res) {
90-
const options = req.body || {}
91-
92-
const collection = await Database.collectionModel.findByPk(req.params.collectionId)
93-
if (!collection) return res.sendStatus(404)
91+
const reqBody = req.body || {}
9492

9593
// Check request body options exist
96-
if (!options.serverAddress || !options.slug) {
94+
if (!reqBody.serverAddress || !reqBody.slug || typeof reqBody.serverAddress !== 'string' || typeof reqBody.slug !== 'string') {
9795
Logger.error(`[RSSFeedController] Invalid request body to open RSS feed`)
9896
return res.status(400).send('Invalid request body')
9997
}
10098

10199
// Check that this slug is not being used for another feed (slug will also be the Feed id)
102-
if (await this.rssFeedManager.findFeedBySlug(options.slug)) {
103-
Logger.error(`[RSSFeedController] Cannot open RSS feed because slug "${options.slug}" is already in use`)
100+
if (await RssFeedManager.checkExistsBySlug(reqBody.slug)) {
101+
Logger.error(`[RSSFeedController] Cannot open RSS feed because slug "${reqBody.slug}" is already in use`)
104102
return res.status(400).send('Slug already in use')
105103
}
106104

107-
const collectionExpanded = await collection.getOldJsonExpanded()
108-
const collectionItemsWithTracks = collectionExpanded.books.filter((li) => li.media.tracks.length)
105+
const collection = await Database.collectionModel.getExpandedById(req.params.collectionId)
106+
if (!collection) return res.sendStatus(404)
109107

110108
// Check collection has audio tracks
111-
if (!collectionItemsWithTracks.length) {
109+
if (!collection.books.some((book) => book.includedAudioFiles.length)) {
112110
Logger.error(`[RSSFeedController] Cannot open RSS feed for collection "${collection.name}" because it has no audio tracks`)
113111
return res.status(400).send('Collection has no audio tracks')
114112
}
115113

116-
const feed = await this.rssFeedManager.openFeedForCollection(req.user.id, collectionExpanded, req.body)
114+
const feed = await RssFeedManager.openFeedForCollection(req.user.id, collection, reqBody)
115+
if (!feed) {
116+
Logger.error(`[RSSFeedController] Failed to open RSS feed for collection "${collection.name}"`)
117+
return res.status(500).send('Failed to open RSS feed')
118+
}
119+
117120
res.json({
118-
feed: feed.toJSONMinified()
121+
feed: feed.toOldJSONMinified()
119122
})
120123
}
121124

@@ -128,37 +131,37 @@ class RSSFeedController {
128131
* @param {Response} res
129132
*/
130133
async openRSSFeedForSeries(req, res) {
131-
const options = req.body || {}
132-
133-
const series = await Database.seriesModel.findByPk(req.params.seriesId)
134-
if (!series) return res.sendStatus(404)
134+
const reqBody = req.body || {}
135135

136136
// Check request body options exist
137-
if (!options.serverAddress || !options.slug) {
137+
if (!reqBody.serverAddress || !reqBody.slug || typeof reqBody.serverAddress !== 'string' || typeof reqBody.slug !== 'string') {
138138
Logger.error(`[RSSFeedController] Invalid request body to open RSS feed`)
139139
return res.status(400).send('Invalid request body')
140140
}
141141

142142
// Check that this slug is not being used for another feed (slug will also be the Feed id)
143-
if (await this.rssFeedManager.findFeedBySlug(options.slug)) {
144-
Logger.error(`[RSSFeedController] Cannot open RSS feed because slug "${options.slug}" is already in use`)
143+
if (await RssFeedManager.checkExistsBySlug(reqBody.slug)) {
144+
Logger.error(`[RSSFeedController] Cannot open RSS feed because slug "${reqBody.slug}" is already in use`)
145145
return res.status(400).send('Slug already in use')
146146
}
147147

148-
const seriesJson = series.toOldJSON()
149-
150-
// Get books in series that have audio tracks
151-
seriesJson.books = (await libraryItemsBookFilters.getLibraryItemsForSeries(series)).filter((li) => li.media.numTracks)
148+
const series = await Database.seriesModel.getExpandedById(req.params.seriesId)
149+
if (!series) return res.sendStatus(404)
152150

153151
// Check series has audio tracks
154-
if (!seriesJson.books.length) {
155-
Logger.error(`[RSSFeedController] Cannot open RSS feed for series "${seriesJson.name}" because it has no audio tracks`)
152+
if (!series.books.some((book) => book.includedAudioFiles.length)) {
153+
Logger.error(`[RSSFeedController] Cannot open RSS feed for series "${series.name}" because it has no audio tracks`)
156154
return res.status(400).send('Series has no audio tracks')
157155
}
158156

159-
const feed = await this.rssFeedManager.openFeedForSeries(req.user.id, seriesJson, req.body)
157+
const feed = await RssFeedManager.openFeedForSeries(req.user.id, series, req.body)
158+
if (!feed) {
159+
Logger.error(`[RSSFeedController] Failed to open RSS feed for series "${series.name}"`)
160+
return res.status(500).send('Failed to open RSS feed')
161+
}
162+
160163
res.json({
161-
feed: feed.toJSONMinified()
164+
feed: feed.toOldJSONMinified()
162165
})
163166
}
164167

@@ -170,8 +173,16 @@ class RSSFeedController {
170173
* @param {RequestWithUser} req
171174
* @param {Response} res
172175
*/
173-
closeRSSFeed(req, res) {
174-
this.rssFeedManager.closeRssFeed(req, res)
176+
async closeRSSFeed(req, res) {
177+
const feed = await Database.feedModel.findByPk(req.params.id)
178+
if (!feed) {
179+
Logger.error(`[RSSFeedController] Cannot close RSS feed because feed "${req.params.id}" does not exist`)
180+
return res.sendStatus(404)
181+
}
182+
183+
await RssFeedManager.handleCloseFeed(feed)
184+
185+
res.sendStatus(200)
175186
}
176187

177188
/**

server/controllers/SeriesController.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ const { Request, Response, NextFunction } = require('express')
22
const Logger = require('../Logger')
33
const SocketAuthority = require('../SocketAuthority')
44
const Database = require('../Database')
5+
6+
const RssFeedManager = require('../managers/RssFeedManager')
7+
58
const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilters')
69

710
/**
@@ -51,8 +54,8 @@ class SeriesController {
5154
}
5255

5356
if (include.includes('rssfeed')) {
54-
const feedObj = await this.rssFeedManager.findFeedForEntityId(seriesJson.id)
55-
seriesJson.rssFeed = feedObj?.toJSONMinified() || null
57+
const feedObj = await RssFeedManager.findFeedForEntityId(seriesJson.id)
58+
seriesJson.rssFeed = feedObj?.toOldJSONMinified() || null
5659
}
5760

5861
res.json(seriesJson)

0 commit comments

Comments
 (0)