mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Update:Cleanup socket usage & add func for emitting events to admin users
This commit is contained in:
parent
e2af33e136
commit
180293ebc1
@ -378,7 +378,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
streamReady() {
|
streamReady() {
|
||||||
console.log(`[STREAM-CONTAINER] Stream Ready`)
|
console.log(`[StreamContainer] Stream Ready`)
|
||||||
if (this.$refs.audioPlayer) {
|
if (this.$refs.audioPlayer) {
|
||||||
this.$refs.audioPlayer.setStreamReady()
|
this.$refs.audioPlayer.setStreamReady()
|
||||||
} else {
|
} else {
|
||||||
|
@ -342,6 +342,7 @@ export default {
|
|||||||
this.$root.socket = this.socket
|
this.$root.socket = this.socket
|
||||||
console.log('Socket initialized')
|
console.log('Socket initialized')
|
||||||
|
|
||||||
|
// Pre-defined socket events
|
||||||
this.socket.on('connect', this.connect)
|
this.socket.on('connect', this.connect)
|
||||||
this.socket.on('connect_error', this.connectError)
|
this.socket.on('connect_error', this.connectError)
|
||||||
this.socket.on('disconnect', this.disconnect)
|
this.socket.on('disconnect', this.disconnect)
|
||||||
@ -350,6 +351,7 @@ export default {
|
|||||||
this.socket.io.on('reconnect_error', this.reconnectError)
|
this.socket.io.on('reconnect_error', this.reconnectError)
|
||||||
this.socket.io.on('reconnect_failed', this.reconnectFailed)
|
this.socket.io.on('reconnect_failed', this.reconnectFailed)
|
||||||
|
|
||||||
|
// Event received after authorizing socket
|
||||||
this.socket.on('init', this.init)
|
this.socket.on('init', this.init)
|
||||||
|
|
||||||
// Stream Listeners
|
// Stream Listeners
|
||||||
|
17
server/Db.js
17
server/Db.js
@ -258,23 +258,6 @@ class Db {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserStream(userId, streamId) {
|
|
||||||
return this.usersDb.update((record) => record.id === userId, (user) => {
|
|
||||||
user.stream = streamId
|
|
||||||
return user
|
|
||||||
}).then((results) => {
|
|
||||||
Logger.debug(`[DB] Updated user ${results.updated}`)
|
|
||||||
this.users = this.users.map(u => {
|
|
||||||
if (u.id === userId) {
|
|
||||||
u.stream = streamId
|
|
||||||
}
|
|
||||||
return u
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
|
||||||
Logger.error(`[DB] Update user Failed ${error}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
updateServerSettings() {
|
updateServerSettings() {
|
||||||
global.ServerSettings = this.serverSettings.toJSON()
|
global.ServerSettings = this.serverSettings.toJSON()
|
||||||
return this.updateEntity('settings', this.serverSettings)
|
return this.updateEntity('settings', this.serverSettings)
|
||||||
|
@ -100,7 +100,7 @@ class Server {
|
|||||||
Logger.info('[Server] Init v' + version)
|
Logger.info('[Server] Init v' + version)
|
||||||
await this.playbackSessionManager.removeOrphanStreams()
|
await this.playbackSessionManager.removeOrphanStreams()
|
||||||
|
|
||||||
var previousVersion = await this.db.checkPreviousVersion() // Returns null if same server version
|
const previousVersion = await this.db.checkPreviousVersion() // Returns null if same server version
|
||||||
if (previousVersion) {
|
if (previousVersion) {
|
||||||
Logger.debug(`[Server] Upgraded from previous version ${previousVersion}`)
|
Logger.debug(`[Server] Upgraded from previous version ${previousVersion}`)
|
||||||
}
|
}
|
||||||
@ -167,13 +167,13 @@ class Server {
|
|||||||
|
|
||||||
// EBook static file routes
|
// EBook static file routes
|
||||||
router.get('/ebook/:library/:folder/*', (req, res) => {
|
router.get('/ebook/:library/:folder/*', (req, res) => {
|
||||||
var library = this.db.libraries.find(lib => lib.id === req.params.library)
|
const library = this.db.libraries.find(lib => lib.id === req.params.library)
|
||||||
if (!library) return res.sendStatus(404)
|
if (!library) return res.sendStatus(404)
|
||||||
var folder = library.folders.find(fol => fol.id === req.params.folder)
|
const folder = library.folders.find(fol => fol.id === req.params.folder)
|
||||||
if (!folder) return res.status(404).send('Folder not found')
|
if (!folder) return res.status(404).send('Folder not found')
|
||||||
|
|
||||||
var remainingPath = req.params['0']
|
const remainingPath = req.params['0']
|
||||||
var fullPath = Path.join(folder.fullPath, remainingPath)
|
const fullPath = Path.join(folder.fullPath, remainingPath)
|
||||||
res.sendFile(fullPath)
|
res.sendFile(fullPath)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -264,15 +264,15 @@ class Server {
|
|||||||
|
|
||||||
// Remove unused /metadata/items/{id} folders
|
// Remove unused /metadata/items/{id} folders
|
||||||
async purgeMetadata() {
|
async purgeMetadata() {
|
||||||
var itemsMetadata = Path.join(global.MetadataPath, 'items')
|
const itemsMetadata = Path.join(global.MetadataPath, 'items')
|
||||||
if (!(await fs.pathExists(itemsMetadata))) return
|
if (!(await fs.pathExists(itemsMetadata))) return
|
||||||
var foldersInItemsMetadata = await fs.readdir(itemsMetadata)
|
const foldersInItemsMetadata = await fs.readdir(itemsMetadata)
|
||||||
|
|
||||||
var purged = 0
|
let purged = 0
|
||||||
await Promise.all(foldersInItemsMetadata.map(async foldername => {
|
await Promise.all(foldersInItemsMetadata.map(async foldername => {
|
||||||
var hasMatchingItem = this.db.libraryItems.find(ab => ab.id === foldername)
|
const hasMatchingItem = this.db.libraryItems.find(ab => ab.id === foldername)
|
||||||
if (!hasMatchingItem) {
|
if (!hasMatchingItem) {
|
||||||
var folderPath = Path.join(itemsMetadata, foldername)
|
const folderPath = Path.join(itemsMetadata, foldername)
|
||||||
Logger.debug(`[Server] Purging unused metadata ${folderPath}`)
|
Logger.debug(`[Server] Purging unused metadata ${folderPath}`)
|
||||||
|
|
||||||
await fs.remove(folderPath).then(() => {
|
await fs.remove(folderPath).then(() => {
|
||||||
@ -291,8 +291,8 @@ class Server {
|
|||||||
// Remove user media progress with items that no longer exist & remove seriesHideFrom that no longer exist
|
// Remove user media progress with items that no longer exist & remove seriesHideFrom that no longer exist
|
||||||
async cleanUserData() {
|
async cleanUserData() {
|
||||||
for (let i = 0; i < this.db.users.length; i++) {
|
for (let i = 0; i < this.db.users.length; i++) {
|
||||||
var _user = this.db.users[i]
|
const _user = this.db.users[i]
|
||||||
var hasUpdated = false
|
let hasUpdated = false
|
||||||
if (_user.mediaProgress.length) {
|
if (_user.mediaProgress.length) {
|
||||||
const lengthBefore = _user.mediaProgress.length
|
const lengthBefore = _user.mediaProgress.length
|
||||||
_user.mediaProgress = _user.mediaProgress.filter(mp => {
|
_user.mediaProgress = _user.mediaProgress.filter(mp => {
|
||||||
@ -338,9 +338,10 @@ class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logout(req, res) {
|
logout(req, res) {
|
||||||
var { socketId } = req.body
|
if (req.body.socketId) {
|
||||||
Logger.info(`[Server] User ${req.user ? req.user.username : 'Unknown'} is logging out with socket ${socketId}`)
|
Logger.info(`[Server] User ${req.user ? req.user.username : 'Unknown'} is logging out with socket ${req.body.socketId}`)
|
||||||
SocketAuthority.logout(socketId)
|
SocketAuthority.logout(req.body.socketId)
|
||||||
|
}
|
||||||
|
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
}
|
}
|
||||||
|
@ -30,24 +30,37 @@ class SocketAuthority {
|
|||||||
return Object.values(this.clients).filter(c => c.user && c.user.id === userId)
|
return Object.values(this.clients).filter(c => c.user && c.user.id === userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emits event to all authorized clients
|
||||||
emitter(evt, data) {
|
emitter(evt, data) {
|
||||||
for (const socketId in this.clients) {
|
for (const socketId in this.clients) {
|
||||||
|
if (this.clients[socketId].user) {
|
||||||
this.clients[socketId].socket.emit(evt, data)
|
this.clients[socketId].socket.emit(evt, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clientEmitter(userId, ev, data) {
|
// Emits event to all clients for a specific user
|
||||||
var clients = this.getClientsForUser(userId)
|
clientEmitter(userId, evt, data) {
|
||||||
|
const clients = this.getClientsForUser(userId)
|
||||||
if (!clients.length) {
|
if (!clients.length) {
|
||||||
return Logger.debug(`[Server] clientEmitter - no clients found for user ${userId}`)
|
return Logger.debug(`[Server] clientEmitter - no clients found for user ${userId}`)
|
||||||
}
|
}
|
||||||
clients.forEach((client) => {
|
clients.forEach((client) => {
|
||||||
if (client.socket) {
|
if (client.socket) {
|
||||||
client.socket.emit(ev, data)
|
client.socket.emit(evt, data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emits event to all admin user clients
|
||||||
|
adminEmitter(evt, data) {
|
||||||
|
for (const socketId in this.clients) {
|
||||||
|
if (this.clients[socketId].user && this.clients[socketId].user.isAdminOrUp) {
|
||||||
|
this.clients[socketId].socket.emit(evt, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initialize(Server) {
|
initialize(Server) {
|
||||||
this.Server = Server
|
this.Server = Server
|
||||||
|
|
||||||
@ -78,7 +91,29 @@ class SocketAuthority {
|
|||||||
socket.on('remove_log_listener', () => Logger.removeSocketListener(socket.id))
|
socket.on('remove_log_listener', () => Logger.removeSocketListener(socket.id))
|
||||||
socket.on('fetch_daily_logs', () => this.Server.logManager.socketRequestDailyLogs(socket))
|
socket.on('fetch_daily_logs', () => this.Server.logManager.socketRequestDailyLogs(socket))
|
||||||
|
|
||||||
|
// Sent automatically from socket.io clients
|
||||||
|
socket.on('disconnect', (reason) => {
|
||||||
|
Logger.removeSocketListener(socket.id)
|
||||||
|
|
||||||
|
const _client = this.clients[socket.id]
|
||||||
|
if (!_client) {
|
||||||
|
Logger.warn(`[Server] Socket ${socket.id} disconnect, no client (Reason: ${reason})`)
|
||||||
|
} else if (!_client.user) {
|
||||||
|
Logger.info(`[Server] Unauth socket ${socket.id} disconnected (Reason: ${reason})`)
|
||||||
|
delete this.clients[socket.id]
|
||||||
|
} else {
|
||||||
|
Logger.debug('[Server] User Offline ' + _client.user.username)
|
||||||
|
this.adminEmitter('user_offline', _client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions, this.Server.db.libraryItems))
|
||||||
|
|
||||||
|
const disconnectTime = Date.now() - _client.connected_at
|
||||||
|
Logger.info(`[Server] Socket ${socket.id} disconnected from client "${_client.user.username}" after ${disconnectTime}ms (Reason: ${reason})`)
|
||||||
|
delete this.clients[socket.id]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//
|
||||||
// Events for testing
|
// Events for testing
|
||||||
|
//
|
||||||
socket.on('message_all_users', (payload) => {
|
socket.on('message_all_users', (payload) => {
|
||||||
// admin user can send a message to all authenticated users
|
// admin user can send a message to all authenticated users
|
||||||
// displays on the web app as a toast
|
// displays on the web app as a toast
|
||||||
@ -95,26 +130,6 @@ class SocketAuthority {
|
|||||||
Logger.debug(`[Server] Received ping from socket ${user.username || 'No User'}`)
|
Logger.debug(`[Server] Received ping from socket ${user.username || 'No User'}`)
|
||||||
socket.emit('pong')
|
socket.emit('pong')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Sent automatically from socket.io clients
|
|
||||||
socket.on('disconnect', (reason) => {
|
|
||||||
Logger.removeSocketListener(socket.id)
|
|
||||||
|
|
||||||
const _client = this.clients[socket.id]
|
|
||||||
if (!_client) {
|
|
||||||
Logger.warn(`[Server] Socket ${socket.id} disconnect, no client (Reason: ${reason})`)
|
|
||||||
} else if (!_client.user) {
|
|
||||||
Logger.info(`[Server] Unauth socket ${socket.id} disconnected (Reason: ${reason})`)
|
|
||||||
delete this.clients[socket.id]
|
|
||||||
} else {
|
|
||||||
Logger.debug('[Server] User Offline ' + _client.user.username)
|
|
||||||
this.io.emit('user_offline', _client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions, this.Server.db.libraryItems))
|
|
||||||
|
|
||||||
const disconnectTime = Date.now() - _client.connected_at
|
|
||||||
Logger.info(`[Server] Socket ${socket.id} disconnected from client "${_client.user.username}" after ${disconnectTime}ms (Reason: ${reason})`)
|
|
||||||
delete this.clients[socket.id]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +156,9 @@ class SocketAuthority {
|
|||||||
|
|
||||||
Logger.debug(`[Server] User Online ${client.user.username}`)
|
Logger.debug(`[Server] User Online ${client.user.username}`)
|
||||||
|
|
||||||
// TODO: Send to authenticated clients only
|
this.adminEmitter('user_online', client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions, this.Server.db.libraryItems))
|
||||||
this.io.emit('user_online', client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions, this.Server.db.libraryItems))
|
|
||||||
|
|
||||||
|
// Update user lastSeen
|
||||||
user.lastSeen = Date.now()
|
user.lastSeen = Date.now()
|
||||||
await this.Server.db.updateEntity('user', user)
|
await this.Server.db.updateEntity('user', user)
|
||||||
|
|
||||||
@ -155,20 +170,19 @@ class SocketAuthority {
|
|||||||
if (user.isAdminOrUp) {
|
if (user.isAdminOrUp) {
|
||||||
initialPayload.usersOnline = this.getUsersOnline()
|
initialPayload.usersOnline = this.getUsersOnline()
|
||||||
}
|
}
|
||||||
|
|
||||||
client.socket.emit('init', initialPayload)
|
client.socket.emit('init', initialPayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
logout(socketId) {
|
logout(socketId) {
|
||||||
// Strip user and client from client and client socket
|
// Strip user and client from client and client socket
|
||||||
if (socketId && this.clients[socketId]) {
|
if (socketId && this.clients[socketId]) {
|
||||||
var client = this.clients[socketId]
|
const client = this.clients[socketId]
|
||||||
var clientSocket = client.socket
|
const clientSocket = client.socket
|
||||||
Logger.debug(`[Server] Found user client ${clientSocket.id}, Has user: ${!!client.user}, Socket has client: ${!!clientSocket.sheepClient}`)
|
Logger.debug(`[Server] Found user client ${clientSocket.id}, Has user: ${!!client.user}, Socket has client: ${!!clientSocket.sheepClient}`)
|
||||||
|
|
||||||
if (client.user) {
|
if (client.user) {
|
||||||
Logger.debug('[Server] User Offline ' + client.user.username)
|
Logger.debug('[Server] User Offline ' + client.user.username)
|
||||||
this.io.emit('user_offline', client.user.toJSONForPublic(null, this.Server.db.libraryItems))
|
this.adminEmitter('user_offline', client.user.toJSONForPublic(null, this.Server.db.libraryItems))
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.clients[socketId].user
|
delete this.clients[socketId].user
|
||||||
|
@ -169,7 +169,7 @@ class PlaybackSessionManager {
|
|||||||
user.currentSessionId = newPlaybackSession.id
|
user.currentSessionId = newPlaybackSession.id
|
||||||
|
|
||||||
this.sessions.push(newPlaybackSession)
|
this.sessions.push(newPlaybackSession)
|
||||||
SocketAuthority.emitter('user_stream_update', user.toJSONForPublic(this.sessions, this.db.libraryItems))
|
SocketAuthority.adminEmitter('user_stream_update', user.toJSONForPublic(this.sessions, this.db.libraryItems))
|
||||||
|
|
||||||
return newPlaybackSession
|
return newPlaybackSession
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ class PlaybackSessionManager {
|
|||||||
await this.saveSession(session)
|
await this.saveSession(session)
|
||||||
}
|
}
|
||||||
Logger.debug(`[PlaybackSessionManager] closeSession "${session.id}"`)
|
Logger.debug(`[PlaybackSessionManager] closeSession "${session.id}"`)
|
||||||
SocketAuthority.emitter('user_stream_update', user.toJSONForPublic(this.sessions, this.db.libraryItems))
|
SocketAuthority.adminEmitter('user_stream_update', user.toJSONForPublic(this.sessions, this.db.libraryItems))
|
||||||
return this.removeSession(session.id)
|
return this.removeSession(session.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,13 +262,13 @@ class ApiRouter {
|
|||||||
|
|
||||||
async getDirectories(dir, relpath, excludedDirs, level = 0) {
|
async getDirectories(dir, relpath, excludedDirs, level = 0) {
|
||||||
try {
|
try {
|
||||||
var paths = await fs.readdir(dir)
|
const paths = await fs.readdir(dir)
|
||||||
|
|
||||||
var dirs = await Promise.all(paths.map(async dirname => {
|
let dirs = await Promise.all(paths.map(async dirname => {
|
||||||
var fullPath = Path.join(dir, dirname)
|
const fullPath = Path.join(dir, dirname)
|
||||||
var path = Path.join(relpath, dirname)
|
const path = Path.join(relpath, dirname)
|
||||||
|
|
||||||
var isDir = (await fs.lstat(fullPath)).isDirectory()
|
const isDir = (await fs.lstat(fullPath)).isDirectory()
|
||||||
if (isDir && !excludedDirs.includes(path) && dirname !== 'node_modules') {
|
if (isDir && !excludedDirs.includes(path) && dirname !== 'node_modules') {
|
||||||
return {
|
return {
|
||||||
path,
|
path,
|
||||||
@ -293,13 +293,13 @@ class ApiRouter {
|
|||||||
// Helper Methods
|
// Helper Methods
|
||||||
//
|
//
|
||||||
userJsonWithItemProgressDetails(user, hideRootToken = false) {
|
userJsonWithItemProgressDetails(user, hideRootToken = false) {
|
||||||
var json = user.toJSONForBrowser()
|
const json = user.toJSONForBrowser()
|
||||||
if (json.type === 'root' && hideRootToken) {
|
if (json.type === 'root' && hideRootToken) {
|
||||||
json.token = ''
|
json.token = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
json.mediaProgress = json.mediaProgress.map(lip => {
|
json.mediaProgress = json.mediaProgress.map(lip => {
|
||||||
var libraryItem = this.db.libraryItems.find(li => li.id === lip.libraryItemId)
|
const libraryItem = this.db.libraryItems.find(li => li.id === lip.libraryItemId)
|
||||||
if (!libraryItem) {
|
if (!libraryItem) {
|
||||||
Logger.warn('[ApiRouter] Library item not found for users progress ' + lip.libraryItemId)
|
Logger.warn('[ApiRouter] Library item not found for users progress ' + lip.libraryItemId)
|
||||||
lip.media = null
|
lip.media = null
|
||||||
@ -326,31 +326,18 @@ class ApiRouter {
|
|||||||
async handleDeleteLibraryItem(libraryItem) {
|
async handleDeleteLibraryItem(libraryItem) {
|
||||||
// Remove libraryItem from users
|
// Remove libraryItem from users
|
||||||
for (let i = 0; i < this.db.users.length; i++) {
|
for (let i = 0; i < this.db.users.length; i++) {
|
||||||
var user = this.db.users[i]
|
const user = this.db.users[i]
|
||||||
var madeUpdates = user.removeMediaProgressForLibraryItem(libraryItem.id)
|
if (user.removeMediaProgressForLibraryItem(libraryItem.id)) {
|
||||||
if (madeUpdates) {
|
|
||||||
await this.db.updateEntity('user', user)
|
await this.db.updateEntity('user', user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove any streams open for this audiobook
|
// TODO: Remove open sessions for library item
|
||||||
// TODO: Change to PlaybackSessionManager to remove open sessions for user
|
|
||||||
// var streams = this.streamManager.streams.filter(stream => stream.audiobookId === libraryItem.id)
|
|
||||||
// for (let i = 0; i < streams.length; i++) {
|
|
||||||
// var stream = streams[i]
|
|
||||||
// var client = stream.client
|
|
||||||
// await stream.close()
|
|
||||||
// if (client && client.user) {
|
|
||||||
// client.user.stream = null
|
|
||||||
// client.stream = null
|
|
||||||
// this.db.updateUserStream(client.user.id, null)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// remove book from collections
|
// remove book from collections
|
||||||
var collectionsWithBook = this.db.collections.filter(c => c.books.includes(libraryItem.id))
|
const collectionsWithBook = this.db.collections.filter(c => c.books.includes(libraryItem.id))
|
||||||
for (let i = 0; i < collectionsWithBook.length; i++) {
|
for (let i = 0; i < collectionsWithBook.length; i++) {
|
||||||
var collection = collectionsWithBook[i]
|
const collection = collectionsWithBook[i]
|
||||||
collection.removeBook(libraryItem.id)
|
collection.removeBook(libraryItem.id)
|
||||||
await this.db.updateEntity('collection', collection)
|
await this.db.updateEntity('collection', collection)
|
||||||
SocketAuthority.clientEmitter(collection.userId, 'collection_updated', collection.toJSONExpanded(this.db.libraryItems))
|
SocketAuthority.clientEmitter(collection.userId, 'collection_updated', collection.toJSONExpanded(this.db.libraryItems))
|
||||||
@ -361,34 +348,32 @@ class ApiRouter {
|
|||||||
await this.cacheManager.purgeCoverCache(libraryItem.id)
|
await this.cacheManager.purgeCoverCache(libraryItem.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
var json = libraryItem.toJSONExpanded()
|
|
||||||
await this.db.removeLibraryItem(libraryItem.id)
|
await this.db.removeLibraryItem(libraryItem.id)
|
||||||
SocketAuthority.emitter('item_removed', json)
|
SocketAuthority.emitter('item_removed', libraryItem.toJSONExpanded())
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserListeningSessionsHelper(userId) {
|
async getUserListeningSessionsHelper(userId) {
|
||||||
var userSessions = await this.db.selectUserSessions(userId)
|
const userSessions = await this.db.selectUserSessions(userId)
|
||||||
return userSessions.sort((a, b) => b.updatedAt - a.updatedAt)
|
return userSessions.sort((a, b) => b.updatedAt - a.updatedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllSessionsWithUserData() {
|
async getAllSessionsWithUserData() {
|
||||||
var sessions = await this.db.getAllSessions()
|
const sessions = await this.db.getAllSessions()
|
||||||
sessions.sort((a, b) => b.updatedAt - a.updatedAt)
|
sessions.sort((a, b) => b.updatedAt - a.updatedAt)
|
||||||
return sessions.map(se => {
|
return sessions.map(se => {
|
||||||
var user = this.db.users.find(u => u.id === se.userId)
|
const user = this.db.users.find(u => u.id === se.userId)
|
||||||
var _se = {
|
return {
|
||||||
...se,
|
...se,
|
||||||
user: user ? { id: user.id, username: user.username } : null
|
user: user ? { id: user.id, username: user.username } : null
|
||||||
}
|
}
|
||||||
return _se
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserListeningStatsHelpers(userId) {
|
async getUserListeningStatsHelpers(userId) {
|
||||||
const today = date.format(new Date(), 'YYYY-MM-DD')
|
const today = date.format(new Date(), 'YYYY-MM-DD')
|
||||||
|
|
||||||
var listeningSessions = await this.getUserListeningSessionsHelper(userId)
|
const listeningSessions = await this.getUserListeningSessionsHelper(userId)
|
||||||
var listeningStats = {
|
const listeningStats = {
|
||||||
totalTime: 0,
|
totalTime: 0,
|
||||||
items: {},
|
items: {},
|
||||||
days: {},
|
days: {},
|
||||||
@ -397,7 +382,7 @@ class ApiRouter {
|
|||||||
recentSessions: listeningSessions.slice(0, 10)
|
recentSessions: listeningSessions.slice(0, 10)
|
||||||
}
|
}
|
||||||
listeningSessions.forEach((s) => {
|
listeningSessions.forEach((s) => {
|
||||||
var sessionTimeListening = s.timeListening
|
let sessionTimeListening = s.timeListening
|
||||||
if (typeof sessionTimeListening == 'string') {
|
if (typeof sessionTimeListening == 'string') {
|
||||||
sessionTimeListening = Number(sessionTimeListening)
|
sessionTimeListening = Number(sessionTimeListening)
|
||||||
}
|
}
|
||||||
@ -432,15 +417,15 @@ class ApiRouter {
|
|||||||
|
|
||||||
async createAuthorsAndSeriesForItemUpdate(mediaPayload) {
|
async createAuthorsAndSeriesForItemUpdate(mediaPayload) {
|
||||||
if (mediaPayload.metadata) {
|
if (mediaPayload.metadata) {
|
||||||
var mediaMetadata = mediaPayload.metadata
|
const mediaMetadata = mediaPayload.metadata
|
||||||
|
|
||||||
// Create new authors if in payload
|
// Create new authors if in payload
|
||||||
if (mediaMetadata.authors && mediaMetadata.authors.length) {
|
if (mediaMetadata.authors && mediaMetadata.authors.length) {
|
||||||
// TODO: validate authors
|
// TODO: validate authors
|
||||||
var newAuthors = []
|
const newAuthors = []
|
||||||
for (let i = 0; i < mediaMetadata.authors.length; i++) {
|
for (let i = 0; i < mediaMetadata.authors.length; i++) {
|
||||||
if (mediaMetadata.authors[i].id.startsWith('new')) {
|
if (mediaMetadata.authors[i].id.startsWith('new')) {
|
||||||
var author = this.db.authors.find(au => au.checkNameEquals(mediaMetadata.authors[i].name))
|
let author = this.db.authors.find(au => au.checkNameEquals(mediaMetadata.authors[i].name))
|
||||||
if (!author) {
|
if (!author) {
|
||||||
author = new Author()
|
author = new Author()
|
||||||
author.setData(mediaMetadata.authors[i])
|
author.setData(mediaMetadata.authors[i])
|
||||||
@ -461,10 +446,10 @@ class ApiRouter {
|
|||||||
// Create new series if in payload
|
// Create new series if in payload
|
||||||
if (mediaMetadata.series && mediaMetadata.series.length) {
|
if (mediaMetadata.series && mediaMetadata.series.length) {
|
||||||
// TODO: validate series
|
// TODO: validate series
|
||||||
var newSeries = []
|
const newSeries = []
|
||||||
for (let i = 0; i < mediaMetadata.series.length; i++) {
|
for (let i = 0; i < mediaMetadata.series.length; i++) {
|
||||||
if (mediaMetadata.series[i].id.startsWith('new')) {
|
if (mediaMetadata.series[i].id.startsWith('new')) {
|
||||||
var seriesItem = this.db.series.find(se => se.checkNameEquals(mediaMetadata.series[i].name))
|
let seriesItem = this.db.series.find(se => se.checkNameEquals(mediaMetadata.series[i].name))
|
||||||
if (!seriesItem) {
|
if (!seriesItem) {
|
||||||
seriesItem = new Series()
|
seriesItem = new Series()
|
||||||
seriesItem.setData(mediaMetadata.series[i])
|
seriesItem.setData(mediaMetadata.series[i])
|
||||||
|
Loading…
Reference in New Issue
Block a user