mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			183 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const Logger = require('../Logger')
 | 
						|
const SocketAuthority = require('../SocketAuthority')
 | 
						|
const Database = require('../Database')
 | 
						|
 | 
						|
const Collection = require('../objects/Collection')
 | 
						|
 | 
						|
class CollectionController {
 | 
						|
  constructor() { }
 | 
						|
 | 
						|
  async create(req, res) {
 | 
						|
    var newCollection = new Collection()
 | 
						|
    req.body.userId = req.user.id
 | 
						|
    var success = newCollection.setData(req.body)
 | 
						|
    if (!success) {
 | 
						|
      return res.status(500).send('Invalid collection data')
 | 
						|
    }
 | 
						|
    var jsonExpanded = newCollection.toJSONExpanded(Database.libraryItems)
 | 
						|
    await Database.createCollection(newCollection)
 | 
						|
    SocketAuthority.emitter('collection_added', jsonExpanded)
 | 
						|
    res.json(jsonExpanded)
 | 
						|
  }
 | 
						|
 | 
						|
  findAll(req, res) {
 | 
						|
    res.json({
 | 
						|
      collections: Database.collections.map(c => c.toJSONExpanded(Database.libraryItems))
 | 
						|
    })
 | 
						|
  }
 | 
						|
 | 
						|
  async findOne(req, res) {
 | 
						|
    const includeEntities = (req.query.include || '').split(',')
 | 
						|
 | 
						|
    const collectionExpanded = req.collection.toJSONExpanded(Database.libraryItems)
 | 
						|
 | 
						|
    if (includeEntities.includes('rssfeed')) {
 | 
						|
      const feedData = await this.rssFeedManager.findFeedForEntityId(collectionExpanded.id)
 | 
						|
      collectionExpanded.rssFeed = feedData?.toJSONMinified() || null
 | 
						|
    }
 | 
						|
 | 
						|
    res.json(collectionExpanded)
 | 
						|
  }
 | 
						|
 | 
						|
  async update(req, res) {
 | 
						|
    const collection = req.collection
 | 
						|
    const wasUpdated = collection.update(req.body)
 | 
						|
    const jsonExpanded = collection.toJSONExpanded(Database.libraryItems)
 | 
						|
    if (wasUpdated) {
 | 
						|
      await Database.updateCollection(collection)
 | 
						|
      SocketAuthority.emitter('collection_updated', jsonExpanded)
 | 
						|
    }
 | 
						|
    res.json(jsonExpanded)
 | 
						|
  }
 | 
						|
 | 
						|
  async delete(req, res) {
 | 
						|
    const collection = req.collection
 | 
						|
    const jsonExpanded = collection.toJSONExpanded(Database.libraryItems)
 | 
						|
 | 
						|
    // Close rss feed - remove from db and emit socket event
 | 
						|
    await this.rssFeedManager.closeFeedForEntityId(collection.id)
 | 
						|
 | 
						|
    await Database.removeCollection(collection.id)
 | 
						|
    SocketAuthority.emitter('collection_removed', jsonExpanded)
 | 
						|
    res.sendStatus(200)
 | 
						|
  }
 | 
						|
 | 
						|
  async addBook(req, res) {
 | 
						|
    const collection = req.collection
 | 
						|
    const libraryItem = Database.libraryItems.find(li => li.id === req.body.id)
 | 
						|
    if (!libraryItem) {
 | 
						|
      return res.status(500).send('Book not found')
 | 
						|
    }
 | 
						|
    if (libraryItem.libraryId !== collection.libraryId) {
 | 
						|
      return res.status(500).send('Book in different library')
 | 
						|
    }
 | 
						|
    if (collection.books.includes(req.body.id)) {
 | 
						|
      return res.status(500).send('Book already in collection')
 | 
						|
    }
 | 
						|
    collection.addBook(req.body.id)
 | 
						|
    const jsonExpanded = collection.toJSONExpanded(Database.libraryItems)
 | 
						|
 | 
						|
    const collectionBook = {
 | 
						|
      collectionId: collection.id,
 | 
						|
      bookId: libraryItem.media.id,
 | 
						|
      order: collection.books.length
 | 
						|
    }
 | 
						|
    await Database.createCollectionBook(collectionBook)
 | 
						|
    SocketAuthority.emitter('collection_updated', jsonExpanded)
 | 
						|
    res.json(jsonExpanded)
 | 
						|
  }
 | 
						|
 | 
						|
  // DELETE: api/collections/:id/book/:bookId
 | 
						|
  async removeBook(req, res) {
 | 
						|
    const collection = req.collection
 | 
						|
    const libraryItem = Database.libraryItems.find(li => li.id === req.params.bookId)
 | 
						|
    if (!libraryItem) {
 | 
						|
      return res.sendStatus(404)
 | 
						|
    }
 | 
						|
 | 
						|
    if (collection.books.includes(req.params.bookId)) {
 | 
						|
      collection.removeBook(req.params.bookId)
 | 
						|
      const jsonExpanded = collection.toJSONExpanded(Database.libraryItems)
 | 
						|
      SocketAuthority.emitter('collection_updated', jsonExpanded)
 | 
						|
      await Database.updateCollection(collection)
 | 
						|
    }
 | 
						|
    res.json(collection.toJSONExpanded(Database.libraryItems))
 | 
						|
  }
 | 
						|
 | 
						|
  // POST: api/collections/:id/batch/add
 | 
						|
  async addBatch(req, res) {
 | 
						|
    const collection = req.collection
 | 
						|
    if (!req.body.books || !req.body.books.length) {
 | 
						|
      return res.status(500).send('Invalid request body')
 | 
						|
    }
 | 
						|
    const bookIdsToAdd = req.body.books
 | 
						|
    const collectionBooksToAdd = []
 | 
						|
    let hasUpdated = false
 | 
						|
 | 
						|
    let order = collection.books.length
 | 
						|
    for (const libraryItemId of bookIdsToAdd) {
 | 
						|
      const libraryItem = Database.libraryItems.find(li => li.id === libraryItemId)
 | 
						|
      if (!libraryItem) continue
 | 
						|
      if (!collection.books.includes(libraryItemId)) {
 | 
						|
        collection.addBook(libraryItemId)
 | 
						|
        collectionBooksToAdd.push({
 | 
						|
          collectionId: collection.id,
 | 
						|
          bookId: libraryItem.media.id,
 | 
						|
          order: order++
 | 
						|
        })
 | 
						|
        hasUpdated = true
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (hasUpdated) {
 | 
						|
      await Database.createBulkCollectionBooks(collectionBooksToAdd)
 | 
						|
      SocketAuthority.emitter('collection_updated', collection.toJSONExpanded(Database.libraryItems))
 | 
						|
    }
 | 
						|
    res.json(collection.toJSONExpanded(Database.libraryItems))
 | 
						|
  }
 | 
						|
 | 
						|
  // POST: api/collections/:id/batch/remove
 | 
						|
  async removeBatch(req, res) {
 | 
						|
    const collection = req.collection
 | 
						|
    if (!req.body.books || !req.body.books.length) {
 | 
						|
      return res.status(500).send('Invalid request body')
 | 
						|
    }
 | 
						|
    var bookIdsToRemove = req.body.books
 | 
						|
    let hasUpdated = false
 | 
						|
    for (const libraryItemId of bookIdsToRemove) {
 | 
						|
      const libraryItem = Database.libraryItems.find(li => li.id === libraryItemId)
 | 
						|
      if (!libraryItem) continue
 | 
						|
 | 
						|
      if (collection.books.includes(libraryItemId)) {
 | 
						|
        collection.removeBook(libraryItemId)
 | 
						|
        hasUpdated = true
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (hasUpdated) {
 | 
						|
      await Database.updateCollection(collection)
 | 
						|
      SocketAuthority.emitter('collection_updated', collection.toJSONExpanded(Database.libraryItems))
 | 
						|
    }
 | 
						|
    res.json(collection.toJSONExpanded(Database.libraryItems))
 | 
						|
  }
 | 
						|
 | 
						|
  middleware(req, res, next) {
 | 
						|
    if (req.params.id) {
 | 
						|
      const collection = Database.collections.find(c => c.id === req.params.id)
 | 
						|
      if (!collection) {
 | 
						|
        return res.status(404).send('Collection not found')
 | 
						|
      }
 | 
						|
      req.collection = collection
 | 
						|
    }
 | 
						|
 | 
						|
    if (req.method == 'DELETE' && !req.user.canDelete) {
 | 
						|
      Logger.warn(`[CollectionController] User attempted to delete without permission`, req.user.username)
 | 
						|
      return res.sendStatus(403)
 | 
						|
    } else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
 | 
						|
      Logger.warn('[CollectionController] User attempted to update without permission', req.user.username)
 | 
						|
      return res.sendStatus(403)
 | 
						|
    }
 | 
						|
 | 
						|
    next()
 | 
						|
  }
 | 
						|
}
 | 
						|
module.exports = new CollectionController() |