mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-31 18:39:27 +01:00
Merge pull request #1231 from k9withabone/server/respond-with-objects
Server respond with objects
This commit is contained in:
commit
05d10b73c3
@ -122,7 +122,7 @@ export default {
|
||||
return this.$store.state.globals.selectedMediaItems
|
||||
},
|
||||
selectedMediaItemsArePlayable() {
|
||||
return !this.selectedMediaItems.some(i => !i.hasTracks)
|
||||
return !this.selectedMediaItems.some((i) => !i.hasTracks)
|
||||
},
|
||||
userMediaProgress() {
|
||||
return this.$store.state.user.user.mediaProgress || []
|
||||
@ -164,12 +164,15 @@ export default {
|
||||
this.$store.commit('setProcessingBatch', true)
|
||||
|
||||
const libraryItemIds = this.selectedMediaItems.map((i) => i.id)
|
||||
const libraryItems = await this.$axios.$post(`/api/items/batch/get`, { libraryItemIds }).catch((error) => {
|
||||
const errorMsg = error.response.data || 'Failed to get items'
|
||||
console.error(errorMsg, error)
|
||||
this.$toast.error(errorMsg)
|
||||
return []
|
||||
})
|
||||
const libraryItems = await this.$axios
|
||||
.$post(`/api/items/batch/get`, { libraryItemIds })
|
||||
.then((res) => res.libraryItems)
|
||||
.catch((error) => {
|
||||
const errorMsg = error.response.data || 'Failed to get items'
|
||||
console.error(errorMsg, error)
|
||||
this.$toast.error(errorMsg)
|
||||
return []
|
||||
})
|
||||
|
||||
if (!libraryItems.length) {
|
||||
this.$store.commit('setProcessingBatch', false)
|
||||
|
@ -201,8 +201,8 @@ export default {
|
||||
this.loadingTags = true
|
||||
this.$axios
|
||||
.$get(`/api/tags`)
|
||||
.then((tags) => {
|
||||
this.tags = tags
|
||||
.then((res) => {
|
||||
this.tags = res.tags
|
||||
this.loadingTags = false
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -303,11 +303,14 @@ export default {
|
||||
this.persistProvider()
|
||||
|
||||
this.isProcessing = true
|
||||
var searchQuery = this.getSearchQuery()
|
||||
var results = await this.$axios.$get(`/api/search/covers?${searchQuery}`).catch((error) => {
|
||||
console.error('Failed', error)
|
||||
return []
|
||||
})
|
||||
const searchQuery = this.getSearchQuery()
|
||||
const results = await this.$axios
|
||||
.$get(`/api/search/covers?${searchQuery}`)
|
||||
.then((res) => res.results)
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
return []
|
||||
})
|
||||
this.coversFound = results
|
||||
this.isProcessing = false
|
||||
this.hasSearched = true
|
||||
|
@ -306,13 +306,13 @@ export default {
|
||||
this.runSearch()
|
||||
},
|
||||
async runSearch() {
|
||||
var searchQuery = this.getSearchQuery()
|
||||
const searchQuery = this.getSearchQuery()
|
||||
if (this.lastSearch === searchQuery) return
|
||||
this.searchResults = []
|
||||
this.isProcessing = true
|
||||
this.lastSearch = searchQuery
|
||||
var searchEntity = this.isPodcast ? 'podcast' : 'books'
|
||||
var results = await this.$axios.$get(`/api/search/${searchEntity}?${searchQuery}`, { timeout: 20000 }).catch((error) => {
|
||||
const searchEntity = this.isPodcast ? 'podcast' : 'books'
|
||||
let results = await this.$axios.$get(`/api/search/${searchEntity}?${searchQuery}`, { timeout: 20000 }).catch((error) => {
|
||||
console.error('Failed', error)
|
||||
return []
|
||||
})
|
||||
|
@ -109,8 +109,8 @@ export default {
|
||||
loadUsers() {
|
||||
this.$axios
|
||||
.$get('/api/users')
|
||||
.then((users) => {
|
||||
this.users = users.sort((a, b) => {
|
||||
.then((res) => {
|
||||
this.users = res.users.sort((a, b) => {
|
||||
return a.createdAt - b.createdAt
|
||||
})
|
||||
})
|
||||
|
@ -82,10 +82,10 @@ export default {
|
||||
})
|
||||
var newOrder = libraryOrderData.map((lib) => lib.id).join(',')
|
||||
if (currOrder !== newOrder) {
|
||||
this.$axios.$post('/api/libraries/order', libraryOrderData).then((libraries) => {
|
||||
if (libraries && libraries.length) {
|
||||
this.$axios.$post('/api/libraries/order', libraryOrderData).then((response) => {
|
||||
if (response.libraries && response.libraries.length) {
|
||||
this.$toast.success('Library order saved', { timeout: 1500 })
|
||||
this.$store.commit('libraries/set', libraries)
|
||||
this.$store.commit('libraries/set', response.libraries)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -96,11 +96,14 @@ export default {
|
||||
}
|
||||
|
||||
const libraryItemIds = store.state.globals.selectedMediaItems.map((i) => i.id)
|
||||
const libraryItems = await app.$axios.$post(`/api/items/batch/get`, { libraryItemIds }).catch((error) => {
|
||||
const errorMsg = error.response.data || 'Failed to get items'
|
||||
console.error(errorMsg, error)
|
||||
return []
|
||||
})
|
||||
const libraryItems = await app.$axios
|
||||
.$post(`/api/items/batch/get`, { libraryItemIds })
|
||||
.then((res) => res.libraryItems)
|
||||
.catch((error) => {
|
||||
const errorMsg = error.response.data || 'Failed to get items'
|
||||
console.error(errorMsg, error)
|
||||
return []
|
||||
})
|
||||
return {
|
||||
mediaType: libraryItems[0].mediaType,
|
||||
libraryItems
|
||||
|
@ -61,10 +61,10 @@
|
||||
<script>
|
||||
export default {
|
||||
async asyncData({ params, redirect, app }) {
|
||||
var users = await app.$axios
|
||||
const users = await app.$axios
|
||||
.$get('/api/users')
|
||||
.then((users) => {
|
||||
return users.sort((a, b) => {
|
||||
.then((res) => {
|
||||
return res.users.sort((a, b) => {
|
||||
return a.createdAt - b.createdAt
|
||||
})
|
||||
})
|
||||
|
@ -48,10 +48,13 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async init() {
|
||||
this.authors = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/authors`).catch((error) => {
|
||||
console.error('Failed to load authors', error)
|
||||
return []
|
||||
})
|
||||
this.authors = await this.$axios
|
||||
.$get(`/api/libraries/${this.currentLibraryId}/authors`)
|
||||
.then((response) => response.authors)
|
||||
.catch((error) => {
|
||||
console.error('Failed to load authors', error)
|
||||
return []
|
||||
})
|
||||
this.loading = false
|
||||
},
|
||||
authorAdded(author) {
|
||||
|
@ -86,8 +86,8 @@ export const actions = {
|
||||
.$get('/api/filesystem')
|
||||
.then((res) => {
|
||||
console.log('Settings folders', res)
|
||||
commit('setFolders', res)
|
||||
return res
|
||||
commit('setFolders', res.directories)
|
||||
return res.directories
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to load dirs', error)
|
||||
@ -151,7 +151,7 @@ export const actions = {
|
||||
this.$axios
|
||||
.$get(`/api/libraries`)
|
||||
.then((data) => {
|
||||
commit('set', data)
|
||||
commit('set', data.libraries)
|
||||
commit('setLastLoad')
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -148,7 +148,9 @@ class AuthorController {
|
||||
var limit = (req.query.limit && !isNaN(req.query.limit)) ? Number(req.query.limit) : 25
|
||||
var authors = this.db.authors.filter(au => au.name.toLowerCase().includes(q))
|
||||
authors = authors.slice(0, limit)
|
||||
res.json(authors)
|
||||
res.json({
|
||||
results: authors
|
||||
})
|
||||
}
|
||||
|
||||
async match(req, res) {
|
||||
|
@ -20,8 +20,9 @@ class CollectionController {
|
||||
}
|
||||
|
||||
findAll(req, res) {
|
||||
var expandedCollections = this.db.collections.map(c => c.toJSONExpanded(this.db.libraryItems))
|
||||
res.json(expandedCollections)
|
||||
res.json({
|
||||
collections: this.db.collections.map(c => c.toJSONExpanded(this.db.libraryItems))
|
||||
})
|
||||
}
|
||||
|
||||
findOne(req, res) {
|
||||
|
@ -19,8 +19,9 @@ class FileSystemController {
|
||||
})
|
||||
|
||||
Logger.debug(`[Server] get file system paths, excluded: ${excludedDirs.join(', ')}`)
|
||||
var dirs = await this.getDirectories(global.appRoot, '/', excludedDirs)
|
||||
res.json(dirs)
|
||||
res.json({
|
||||
directories: await this.getDirectories(global.appRoot, '/', excludedDirs)
|
||||
})
|
||||
}
|
||||
}
|
||||
module.exports = new FileSystemController()
|
@ -62,7 +62,9 @@ class LibraryController {
|
||||
return res.json(this.db.libraries.filter(lib => librariesAccessible.includes(lib.id)).map(lib => lib.toJSON()))
|
||||
}
|
||||
|
||||
res.json(this.db.libraries.map(lib => lib.toJSON()))
|
||||
res.json({
|
||||
libraries: this.db.libraries.map(lib => lib.toJSON())
|
||||
})
|
||||
}
|
||||
|
||||
async findOne(req, res) {
|
||||
@ -496,8 +498,9 @@ class LibraryController {
|
||||
Logger.debug(`[LibraryController] Library orders were up to date`)
|
||||
}
|
||||
|
||||
var libraries = this.db.libraries.map(lib => lib.toJSON())
|
||||
res.json(libraries)
|
||||
res.json({
|
||||
libraries: this.db.libraries.map(lib => lib.toJSON())
|
||||
})
|
||||
}
|
||||
|
||||
// GET: Global library search
|
||||
@ -603,7 +606,9 @@ class LibraryController {
|
||||
}
|
||||
})
|
||||
|
||||
res.json(naturalSort(Object.values(authors)).asc(au => au.name))
|
||||
res.json({
|
||||
authors: naturalSort(Object.values(authors)).asc(au => au.name)
|
||||
})
|
||||
}
|
||||
|
||||
async matchAll(req, res) {
|
||||
|
@ -308,16 +308,18 @@ class LibraryItemController {
|
||||
|
||||
// POST: api/items/batch/get
|
||||
async batchGet(req, res) {
|
||||
var libraryItemIds = req.body.libraryItemIds || []
|
||||
const libraryItemIds = req.body.libraryItemIds || []
|
||||
if (!libraryItemIds.length) {
|
||||
return res.status(403).send('Invalid payload')
|
||||
}
|
||||
var libraryItems = []
|
||||
const libraryItems = []
|
||||
libraryItemIds.forEach((lid) => {
|
||||
const li = this.db.libraryItems.find(_li => _li.id === lid)
|
||||
if (li) libraryItems.push(li.toJSONExpanded())
|
||||
})
|
||||
res.json(libraryItems)
|
||||
res.json({
|
||||
libraryItems
|
||||
})
|
||||
}
|
||||
|
||||
// POST: api/items/batch/quickmatch
|
||||
|
@ -137,7 +137,9 @@ class MiscController {
|
||||
})
|
||||
}
|
||||
})
|
||||
res.json(tags)
|
||||
res.json({
|
||||
tags: tags
|
||||
})
|
||||
}
|
||||
|
||||
validateCronExpression(req, res) {
|
||||
|
@ -4,15 +4,15 @@ class SearchController {
|
||||
constructor() { }
|
||||
|
||||
async findBooks(req, res) {
|
||||
var provider = req.query.provider || 'google'
|
||||
var title = req.query.title || ''
|
||||
var author = req.query.author || ''
|
||||
var results = await this.bookFinder.search(provider, title, author)
|
||||
const provider = req.query.provider || 'google'
|
||||
const title = req.query.title || ''
|
||||
const author = req.query.author || ''
|
||||
const results = await this.bookFinder.search(provider, title, author)
|
||||
res.json(results)
|
||||
}
|
||||
|
||||
async findCovers(req, res) {
|
||||
var query = req.query
|
||||
const query = req.query
|
||||
const podcast = query.podcast == 1
|
||||
|
||||
if (!query.title) {
|
||||
@ -20,28 +20,30 @@ class SearchController {
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
|
||||
var result = null
|
||||
if (podcast) result = await this.podcastFinder.findCovers(query.title)
|
||||
else result = await this.bookFinder.findCovers(query.provider || 'google', query.title, query.author || null)
|
||||
res.json(result)
|
||||
let results = null
|
||||
if (podcast) results = await this.podcastFinder.findCovers(query.title)
|
||||
else results = await this.bookFinder.findCovers(query.provider || 'google', query.title, query.author || null)
|
||||
res.json({
|
||||
results
|
||||
})
|
||||
}
|
||||
|
||||
async findPodcasts(req, res) {
|
||||
var term = req.query.term
|
||||
var results = await this.podcastFinder.search(term)
|
||||
const term = req.query.term
|
||||
const results = await this.podcastFinder.search(term)
|
||||
res.json(results)
|
||||
}
|
||||
|
||||
async findAuthor(req, res) {
|
||||
var query = req.query.q
|
||||
var author = await this.authorFinder.findAuthorByName(query)
|
||||
const query = req.query.q
|
||||
const author = await this.authorFinder.findAuthorByName(query)
|
||||
res.json(author)
|
||||
}
|
||||
|
||||
async findChapters(req, res) {
|
||||
var asin = req.query.asin
|
||||
var region = (req.query.region || 'us').toLowerCase()
|
||||
var chapterData = await this.bookFinder.findChapters(asin, region)
|
||||
const asin = req.query.asin
|
||||
const region = (req.query.region || 'us').toLowerCase()
|
||||
const chapterData = await this.bookFinder.findChapters(asin, region)
|
||||
if (!chapterData) {
|
||||
return res.json({ error: 'Chapters not found' })
|
||||
}
|
||||
|
@ -32,7 +32,9 @@ class SeriesController {
|
||||
var limit = (req.query.limit && !isNaN(req.query.limit)) ? Number(req.query.limit) : 25
|
||||
var series = this.db.series.filter(se => se.name.toLowerCase().includes(q))
|
||||
series = series.slice(0, limit)
|
||||
res.json(series)
|
||||
res.json({
|
||||
results: series
|
||||
})
|
||||
}
|
||||
|
||||
async update(req, res) {
|
||||
|
@ -12,7 +12,9 @@ class UserController {
|
||||
if (!req.user.isAdminOrUp) return res.sendStatus(403)
|
||||
const hideRootToken = !req.user.isRoot
|
||||
const users = this.db.users.map(u => this.userJsonWithItemProgressDetails(u, hideRootToken))
|
||||
res.json(users)
|
||||
res.json({
|
||||
users: users
|
||||
})
|
||||
}
|
||||
|
||||
findOne(req, res) {
|
||||
|
@ -31,7 +31,7 @@ class PlaybackSessionManager {
|
||||
return this.sessions.find(s => s.userId === userId)
|
||||
}
|
||||
getStream(sessionId) {
|
||||
var session = this.getSession(sessionId)
|
||||
const session = this.getSession(sessionId)
|
||||
return session ? session.stream : null
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ class PlaybackSessionManager {
|
||||
}
|
||||
|
||||
async syncSessionRequest(user, session, payload, res) {
|
||||
var result = await this.syncSession(user, session, payload)
|
||||
const result = await this.syncSession(user, session, payload)
|
||||
if (result) {
|
||||
res.json(session.toJSONForClient(result.libraryItem))
|
||||
}
|
||||
@ -66,7 +66,7 @@ class PlaybackSessionManager {
|
||||
return res.status(500).send('Local session is locked and already syncing')
|
||||
}
|
||||
|
||||
var libraryItem = this.db.getLibraryItem(sessionJson.libraryItemId)
|
||||
const libraryItem = this.db.getLibraryItem(sessionJson.libraryItemId)
|
||||
if (!libraryItem) {
|
||||
Logger.error(`[PlaybackSessionManager] syncLocalSessionRequest: Library item not found for session "${sessionJson.libraryItemId}"`)
|
||||
return res.status(500).send('Library item not found')
|
||||
@ -74,7 +74,7 @@ class PlaybackSessionManager {
|
||||
|
||||
this.localSessionLock[sessionJson.id] = true // Lock local session
|
||||
|
||||
var session = await this.db.getPlaybackSession(sessionJson.id)
|
||||
let session = await this.db.getPlaybackSession(sessionJson.id)
|
||||
if (!session) {
|
||||
// New session from local
|
||||
session = new PlaybackSession(sessionJson)
|
||||
@ -96,10 +96,10 @@ class PlaybackSessionManager {
|
||||
progress: session.progress,
|
||||
lastUpdate: session.updatedAt // Keep media progress update times the same as local
|
||||
}
|
||||
var wasUpdated = user.createUpdateMediaProgress(libraryItem, itemProgressUpdate, session.episodeId)
|
||||
const wasUpdated = user.createUpdateMediaProgress(libraryItem, itemProgressUpdate, session.episodeId)
|
||||
if (wasUpdated) {
|
||||
await this.db.updateEntity('user', user)
|
||||
var itemProgress = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
const itemProgress = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
SocketAuthority.clientEmitter(user.id, 'user_item_progress_updated', {
|
||||
id: itemProgress.id,
|
||||
data: itemProgress.toJSON()
|
||||
@ -118,18 +118,25 @@ class PlaybackSessionManager {
|
||||
|
||||
async startSession(user, deviceInfo, libraryItem, episodeId, options) {
|
||||
// Close any sessions already open for user
|
||||
var userSessions = this.sessions.filter(playbackSession => playbackSession.userId === user.id)
|
||||
const userSessions = this.sessions.filter(playbackSession => playbackSession.userId === user.id)
|
||||
for (const session of userSessions) {
|
||||
Logger.info(`[PlaybackSessionManager] startSession: Closing open session "${session.displayTitle}" for user "${user.username}"`)
|
||||
await this.closeSession(user, session, null)
|
||||
}
|
||||
|
||||
var shouldDirectPlay = options.forceDirectPlay || (!options.forceTranscode && libraryItem.media.checkCanDirectPlay(options, episodeId))
|
||||
var mediaPlayer = options.mediaPlayer || 'unknown'
|
||||
const shouldDirectPlay = options.forceDirectPlay || (!options.forceTranscode && libraryItem.media.checkCanDirectPlay(options, episodeId))
|
||||
const mediaPlayer = options.mediaPlayer || 'unknown'
|
||||
|
||||
const userProgress = user.getMediaProgress(libraryItem.id, episodeId)
|
||||
var userStartTime = 0
|
||||
if (userProgress) userStartTime = Number.parseFloat(userProgress.currentTime) || 0
|
||||
let userStartTime = 0
|
||||
if (userProgress) {
|
||||
if (userProgress.isFinished) {
|
||||
Logger.info(`[PlaybackSessionManager] Starting session for user "${user.username}" and resetting progress for finished item "${libraryItem.media.metadata.title}"`)
|
||||
// Keep userStartTime as 0 so the client restarts the media
|
||||
} else {
|
||||
userStartTime = Number.parseFloat(userProgress.currentTime) || 0
|
||||
}
|
||||
}
|
||||
const newPlaybackSession = new PlaybackSession()
|
||||
newPlaybackSession.setData(libraryItem, user, mediaPlayer, deviceInfo, userStartTime, episodeId)
|
||||
|
||||
@ -142,14 +149,14 @@ class PlaybackSessionManager {
|
||||
// HLS not supported for video yet
|
||||
}
|
||||
} else {
|
||||
var audioTracks = []
|
||||
let audioTracks = []
|
||||
if (shouldDirectPlay) {
|
||||
Logger.debug(`[PlaybackSessionManager] "${user.username}" starting direct play session for item "${libraryItem.id}"`)
|
||||
audioTracks = libraryItem.getDirectPlayTracklist(episodeId)
|
||||
newPlaybackSession.playMethod = PlayMethod.DIRECTPLAY
|
||||
} else {
|
||||
Logger.debug(`[PlaybackSessionManager] "${user.username}" starting stream session for item "${libraryItem.id}"`)
|
||||
var stream = new Stream(newPlaybackSession.id, this.StreamsPath, user, libraryItem, episodeId, userStartTime)
|
||||
const stream = new Stream(newPlaybackSession.id, this.StreamsPath, user, libraryItem, episodeId, userStartTime)
|
||||
await stream.generatePlaylist()
|
||||
stream.start() // Start transcode
|
||||
|
||||
@ -175,7 +182,7 @@ class PlaybackSessionManager {
|
||||
}
|
||||
|
||||
async syncSession(user, session, syncData) {
|
||||
var libraryItem = this.db.libraryItems.find(li => li.id === session.libraryItemId)
|
||||
const libraryItem = this.db.libraryItems.find(li => li.id === session.libraryItemId)
|
||||
if (!libraryItem) {
|
||||
Logger.error(`[PlaybackSessionManager] syncSession Library Item not found "${session.libraryItemId}"`)
|
||||
return null
|
||||
@ -190,11 +197,11 @@ class PlaybackSessionManager {
|
||||
currentTime: syncData.currentTime,
|
||||
progress: session.progress
|
||||
}
|
||||
var wasUpdated = user.createUpdateMediaProgress(libraryItem, itemProgressUpdate, session.episodeId)
|
||||
const wasUpdated = user.createUpdateMediaProgress(libraryItem, itemProgressUpdate, session.episodeId)
|
||||
if (wasUpdated) {
|
||||
|
||||
await this.db.updateEntity('user', user)
|
||||
var itemProgress = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
const itemProgress = user.getMediaProgress(session.libraryItemId, session.episodeId)
|
||||
SocketAuthority.clientEmitter(user.id, 'user_item_progress_updated', {
|
||||
id: itemProgress.id,
|
||||
data: itemProgress.toJSON()
|
||||
@ -229,7 +236,7 @@ class PlaybackSessionManager {
|
||||
}
|
||||
|
||||
async removeSession(sessionId) {
|
||||
var session = this.sessions.find(s => s.id === sessionId)
|
||||
const session = this.sessions.find(s => s.id === sessionId)
|
||||
if (!session) return
|
||||
if (session.stream) {
|
||||
await session.stream.close()
|
||||
@ -242,13 +249,13 @@ class PlaybackSessionManager {
|
||||
async removeOrphanStreams() {
|
||||
await fs.ensureDir(this.StreamsPath)
|
||||
try {
|
||||
var streamsInPath = await fs.readdir(this.StreamsPath)
|
||||
const streamsInPath = await fs.readdir(this.StreamsPath)
|
||||
for (let i = 0; i < streamsInPath.length; i++) {
|
||||
var streamId = streamsInPath[i]
|
||||
const streamId = streamsInPath[i]
|
||||
if (streamId.startsWith('play_')) { // Make sure to only remove folders that are a stream
|
||||
var session = this.sessions.find(se => se.id === streamId)
|
||||
const session = this.sessions.find(se => se.id === streamId)
|
||||
if (!session) {
|
||||
var streamPath = Path.join(this.StreamsPath, streamId)
|
||||
const streamPath = Path.join(this.StreamsPath, streamId)
|
||||
Logger.debug(`[PlaybackSessionManager] Removing orphan stream "${streamPath}"`)
|
||||
await fs.remove(streamPath)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user