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