2022-12-26 23:58:36 +01:00
const Logger = require ( '../Logger' )
2023-07-05 01:14:44 +02:00
const Database = require ( '../Database' )
2022-12-26 23:58:36 +01:00
class RSSFeedController {
constructor ( ) { }
// POST: api/feeds/item/:itemId/open
async openRSSFeedForItem ( req , res ) {
const options = req . body || { }
2023-07-05 01:14:44 +02:00
const item = Database . libraryItems . find ( li => li . id === req . params . itemId )
2022-12-26 23:58:36 +01:00
if ( ! item ) return res . sendStatus ( 404 )
// Check user can access this library item
if ( ! req . user . checkCanAccessLibraryItem ( item ) ) {
Logger . error ( ` [RSSFeedController] User " ${ req . user . username } " attempted to open an RSS feed for item " ${ item . media . metadata . title } " that they don \' t have access to ` )
return res . sendStatus ( 403 )
}
// Check request body options exist
2023-02-25 15:53:09 +01:00
if ( ! options . serverAddress || ! options . slug ) {
2022-12-26 23:58:36 +01:00
Logger . error ( ` [RSSFeedController] Invalid request body to open RSS feed ` )
return res . status ( 400 ) . send ( 'Invalid request body' )
}
// Check item has audio tracks
if ( ! item . media . numTracks ) {
Logger . error ( ` [RSSFeedController] Cannot open RSS feed for item " ${ item . media . metadata . title } " because it has no audio tracks ` )
return res . status ( 400 ) . send ( 'Item has no audio tracks' )
}
// Check that this slug is not being used for another feed (slug will also be the Feed id)
2023-07-17 23:48:46 +02:00
if ( await this . rssFeedManager . findFeedBySlug ( options . slug ) ) {
2022-12-26 23:58:36 +01:00
Logger . error ( ` [RSSFeedController] Cannot open RSS feed because slug " ${ options . slug } " is already in use ` )
return res . status ( 400 ) . send ( 'Slug already in use' )
}
const feed = await this . rssFeedManager . openFeedForItem ( req . user , item , req . body )
res . json ( {
feed : feed . toJSONMinified ( )
} )
}
2022-12-27 00:48:39 +01:00
// POST: api/feeds/collection/:collectionId/open
async openRSSFeedForCollection ( req , res ) {
const options = req . body || { }
2023-07-22 23:18:55 +02:00
const collection = await Database . models . collection . getById ( req . params . collectionId )
2022-12-27 00:48:39 +01:00
if ( ! collection ) return res . sendStatus ( 404 )
// Check request body options exist
2023-02-25 15:53:09 +01:00
if ( ! options . serverAddress || ! options . slug ) {
2022-12-27 00:48:39 +01:00
Logger . error ( ` [RSSFeedController] Invalid request body to open RSS feed ` )
return res . status ( 400 ) . send ( 'Invalid request body' )
}
// Check that this slug is not being used for another feed (slug will also be the Feed id)
2023-07-17 23:48:46 +02:00
if ( await this . rssFeedManager . findFeedBySlug ( options . slug ) ) {
2022-12-27 00:48:39 +01:00
Logger . error ( ` [RSSFeedController] Cannot open RSS feed because slug " ${ options . slug } " is already in use ` )
return res . status ( 400 ) . send ( 'Slug already in use' )
}
2023-07-05 01:14:44 +02:00
const collectionExpanded = collection . toJSONExpanded ( Database . libraryItems )
2022-12-27 00:48:39 +01:00
const collectionItemsWithTracks = collectionExpanded . books . filter ( li => li . media . tracks . length )
// Check collection has audio tracks
if ( ! collectionItemsWithTracks . length ) {
Logger . error ( ` [RSSFeedController] Cannot open RSS feed for collection " ${ collection . name } " because it has no audio tracks ` )
return res . status ( 400 ) . send ( 'Collection has no audio tracks' )
}
const feed = await this . rssFeedManager . openFeedForCollection ( req . user , collectionExpanded , req . body )
res . json ( {
feed : feed . toJSONMinified ( )
} )
}
2022-12-31 23:58:19 +01:00
// POST: api/feeds/series/:seriesId/open
async openRSSFeedForSeries ( req , res ) {
const options = req . body || { }
2023-07-05 01:14:44 +02:00
const series = Database . series . find ( se => se . id === req . params . seriesId )
2022-12-31 23:58:19 +01:00
if ( ! series ) return res . sendStatus ( 404 )
// Check request body options exist
2023-02-25 15:53:09 +01:00
if ( ! options . serverAddress || ! options . slug ) {
2022-12-31 23:58:19 +01:00
Logger . error ( ` [RSSFeedController] Invalid request body to open RSS feed ` )
return res . status ( 400 ) . send ( 'Invalid request body' )
}
// Check that this slug is not being used for another feed (slug will also be the Feed id)
2023-07-17 23:48:46 +02:00
if ( await this . rssFeedManager . findFeedBySlug ( options . slug ) ) {
2022-12-31 23:58:19 +01:00
Logger . error ( ` [RSSFeedController] Cannot open RSS feed because slug " ${ options . slug } " is already in use ` )
return res . status ( 400 ) . send ( 'Slug already in use' )
}
const seriesJson = series . toJSON ( )
// Get books in series that have audio tracks
2023-07-05 01:14:44 +02:00
seriesJson . books = Database . libraryItems . filter ( li => li . mediaType === 'book' && li . media . metadata . hasSeries ( series . id ) && li . media . tracks . length )
2022-12-31 23:58:19 +01:00
// Check series has audio tracks
if ( ! seriesJson . books . length ) {
Logger . error ( ` [RSSFeedController] Cannot open RSS feed for series " ${ seriesJson . name } " because it has no audio tracks ` )
return res . status ( 400 ) . send ( 'Series has no audio tracks' )
}
const feed = await this . rssFeedManager . openFeedForSeries ( req . user , seriesJson , req . body )
res . json ( {
feed : feed . toJSONMinified ( )
} )
}
2022-12-26 23:58:36 +01:00
// POST: api/feeds/:id/close
2023-07-07 00:07:10 +02:00
closeRSSFeed ( req , res ) {
this . rssFeedManager . closeRssFeed ( req , res )
2022-12-26 23:58:36 +01:00
}
middleware ( req , res , next ) {
if ( ! req . user . isAdminOrUp ) { // Only admins can manage rss feeds
Logger . error ( ` [RSSFeedController] Non-admin user attempted to make a request to an RSS feed route ` , req . user . username )
return res . sendStatus ( 403 )
}
next ( )
}
}
2023-02-25 14:20:26 +01:00
module . exports = new RSSFeedController ( )