Merge master

This commit is contained in:
advplyr 2022-05-28 13:58:52 -05:00
commit a5dacd7821
47 changed files with 3086 additions and 598 deletions

View file

@ -0,0 +1,74 @@
class DeviceInfo {
constructor(deviceInfo = null) {
this.ipAddress = null
// From User Agent (see: https://www.npmjs.com/package/ua-parser-js)
this.browserName = null
this.browserVersion = null
this.osName = null
this.osVersion = null
this.deviceType = null
// From client
this.clientVersion = null
this.manufacturer = null
this.model = null
this.sdkVersion = null // Android Only
this.serverVersion = null
if (deviceInfo) {
this.construct(deviceInfo)
}
}
construct(deviceInfo) {
for (const key in deviceInfo) {
if (deviceInfo[key] !== undefined && this[key] !== undefined) {
this[key] = deviceInfo[key]
}
}
}
toJSON() {
const obj = {
ipAddress: this.ipAddress,
browserName: this.browserName,
browserVersion: this.browserVersion,
osName: this.osName,
osVersion: this.osVersion,
deviceType: this.deviceType,
clientVersion: this.clientVersion,
manufacturer: this.manufacturer,
model: this.model,
sdkVersion: this.sdkVersion,
serverVersion: this.serverVersion
}
for (const key in obj) {
if (obj[key] === null || obj[key] === undefined) {
delete obj[key]
}
}
return obj
}
setData(ip, ua, clientDeviceInfo, serverVersion) {
this.ipAddress = ip || null
const uaObj = ua || {}
this.browserName = uaObj.browser.name || null
this.browserVersion = uaObj.browser.version || null
this.osName = uaObj.os.name || null
this.osVersion = uaObj.os.version || null
this.deviceType = uaObj.device.type || null
var cdi = clientDeviceInfo || {}
this.clientVersion = cdi.clientVersion || null
this.manufacturer = cdi.manufacturer || null
this.model = cdi.model || null
this.sdkVersion = cdi.sdkVersion || null
this.serverVersion = serverVersion || null
}
}
module.exports = DeviceInfo

View file

@ -3,11 +3,13 @@ const { getId } = require('../utils/index')
const { PlayMethod } = require('../utils/constants')
const BookMetadata = require('./metadata/BookMetadata')
const PodcastMetadata = require('./metadata/PodcastMetadata')
const DeviceInfo = require('./DeviceInfo')
class PlaybackSession {
constructor(session) {
this.id = null
this.userId = null
this.libraryId = null
this.libraryItemId = null
this.episodeId = null
@ -21,18 +23,21 @@ class PlaybackSession {
this.playMethod = null
this.mediaPlayer = null
this.deviceInfo = null
this.date = null
this.dayOfWeek = null
this.timeListening = null
this.startTime = null // media current time at start of playback
this.currentTime = 0 // Last current time set
this.startedAt = null
this.updatedAt = null
// Not saved in DB
this.lastSave = 0
this.audioTracks = []
this.currentTime = 0
this.stream = null
if (session) {
@ -43,8 +48,8 @@ class PlaybackSession {
toJSON() {
return {
id: this.id,
sessionType: this.sessionType,
userId: this.userId,
libraryId: this.libraryId,
libraryItemId: this.libraryItemId,
episodeId: this.episodeId,
mediaType: this.mediaType,
@ -56,10 +61,13 @@ class PlaybackSession {
duration: this.duration,
playMethod: this.playMethod,
mediaPlayer: this.mediaPlayer,
deviceInfo: this.deviceInfo ? this.deviceInfo.toJSON() : null,
date: this.date,
dayOfWeek: this.dayOfWeek,
timeListening: this.timeListening,
lastUpdate: this.lastUpdate,
startTime: this.startTime,
currentTime: this.currentTime,
startedAt: this.startedAt,
updatedAt: this.updatedAt
}
}
@ -67,8 +75,8 @@ class PlaybackSession {
toJSONForClient(libraryItem) {
return {
id: this.id,
sessionType: this.sessionType,
userId: this.userId,
libraryId: this.libraryId,
libraryItemId: this.libraryItemId,
episodeId: this.episodeId,
mediaType: this.mediaType,
@ -80,27 +88,30 @@ class PlaybackSession {
duration: this.duration,
playMethod: this.playMethod,
mediaPlayer: this.mediaPlayer,
deviceInfo: this.deviceInfo ? this.deviceInfo.toJSON() : null,
date: this.date,
dayOfWeek: this.dayOfWeek,
timeListening: this.timeListening,
lastUpdate: this.lastUpdate,
startTime: this.startTime,
currentTime: this.currentTime,
startedAt: this.startedAt,
updatedAt: this.updatedAt,
audioTracks: this.audioTracks.map(at => at.toJSON()),
currentTime: this.currentTime,
libraryItem: libraryItem.toJSONExpanded()
}
}
construct(session) {
this.id = session.id
this.sessionType = session.sessionType
this.userId = session.userId
this.libraryId = session.libraryId || null
this.libraryItemId = session.libraryItemId
this.episodeId = session.episodeId
this.mediaType = session.mediaType
this.duration = session.duration
this.playMethod = session.playMethod
this.mediaPlayer = session.mediaPlayer || null
this.deviceInfo = new DeviceInfo(session.deviceInfo)
this.chapters = session.chapters || []
this.mediaMetadata = null
@ -118,6 +129,9 @@ class PlaybackSession {
this.dayOfWeek = session.dayOfWeek
this.timeListening = session.timeListening || null
this.startTime = session.startTime || 0
this.currentTime = session.currentTime || 0
this.startedAt = session.startedAt
this.updatedAt = session.updatedAt || null
}
@ -127,9 +141,10 @@ class PlaybackSession {
return Math.max(0, Math.min(this.currentTime / this.duration, 1))
}
setData(libraryItem, user, mediaPlayer, episodeId = null) {
setData(libraryItem, user, mediaPlayer, deviceInfo, startTime, episodeId = null) {
this.id = getId('play')
this.userId = user.id
this.libraryId = libraryItem.libraryId
this.libraryItemId = libraryItem.id
this.episodeId = episodeId
this.mediaType = libraryItem.mediaType
@ -146,8 +161,12 @@ class PlaybackSession {
}
this.mediaPlayer = mediaPlayer
this.deviceInfo = deviceInfo || new DeviceInfo()
this.timeListening = 0
this.startTime = startTime
this.currentTime = startTime
this.date = date.format(new Date(), 'YYYY-MM-DD')
this.dayOfWeek = date.format(new Date(), 'dddd')
this.startedAt = Date.now()

View file

@ -1,4 +1,3 @@
const { stripHtml } = require('string-strip-html')
const { getId } = require('../../utils/index')
const AudioFile = require('../files/AudioFile')
const AudioTrack = require('../files/AudioTrack')
@ -78,8 +77,7 @@ class PodcastEpisode {
episodeType: this.episodeType,
title: this.title,
subtitle: this.subtitle,
// description: this.description,
description: this.descriptionPlain, // Temporary stripping HTML until proper cleaning is implemented
description: this.description,
enclosure: this.enclosure ? { ...this.enclosure } : null,
pubDate: this.pubDate,
audioFile: this.audioFile.toJSON(),
@ -108,10 +106,6 @@ class PodcastEpisode {
if (this.episode) return `${this.episode} - ${this.title}`
return this.title
}
get descriptionPlain() {
if (!this.description) return ''
return stripHtml(this.description).result
}
setData(data, index = 1) {
this.id = getId('ep')

View file

@ -224,18 +224,10 @@ class Podcast {
this.episodes.push(pe)
}
setEpisodeOrder(episodeIds) {
episodeIds.reverse() // episode Ids will already be in descending order
this.episodes = this.episodes.map(ep => {
var indexOf = episodeIds.findIndex(id => id === ep.id)
ep.index = indexOf + 1
return ep
})
this.episodes.sort((a, b) => b.index - a.index)
}
reorderEpisodes() {
var hasUpdates = false
// TODO: Sort by published date
this.episodes = naturalSort(this.episodes).asc((ep) => ep.bestFilename)
for (let i = 0; i < this.episodes.length; i++) {
if (this.episodes[i].index !== (i + 1)) {