Update folder scanner and db to store LocalLibraryItem objects instead of LocalMediaItem objects, some ui fixes and audio player service binding fix

This commit is contained in:
advplyr
2022-04-05 19:44:14 -05:00
parent 77ef0c119b
commit 12de187b7a
22 changed files with 248 additions and 158 deletions
+1 -1
View File
@@ -71,7 +71,7 @@
<service
android:exported="true"
android:enabled="true"
android:name=".PlayerNotificationService">
android:name=".player.PlayerNotificationService">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
@@ -10,7 +10,6 @@ import androidx.core.app.ActivityCompat
import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorageHelper
import com.audiobookshelf.app.data.AbsDatabase
import com.audiobookshelf.app.data.DbManager
import com.audiobookshelf.app.player.PlayerNotificationService
import com.audiobookshelf.app.plugins.AbsDownloader
import com.audiobookshelf.app.plugins.AbsAudioPlayer
@@ -18,7 +17,6 @@ import com.audiobookshelf.app.plugins.AbsFileSystem
import com.getcapacitor.BridgeActivity
import io.paperdb.Paper
class MainActivity : BridgeActivity() {
private val tag = "MainActivity"
@@ -87,6 +85,7 @@ class MainActivity : BridgeActivity() {
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
Log.d(tag, "onPostCreate MainActivity")
mConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) {
@@ -97,7 +96,6 @@ class MainActivity : BridgeActivity() {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
Log.d(tag, "Service Connected $name")
mBounded = true
val mLocalBinder = service as PlayerNotificationService.LocalBinder
foregroundService = mLocalBinder.getService()
@@ -109,8 +107,10 @@ class MainActivity : BridgeActivity() {
}
}
val startIntent = Intent(this, PlayerNotificationService::class.java)
bindService(startIntent, mConnection as ServiceConnection, Context.BIND_AUTO_CREATE);
Intent(this, PlayerNotificationService::class.java).also { intent ->
Log.d(tag, "Binding PlayerNotificationService")
bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
}
}
@@ -30,28 +30,68 @@ data class LibraryItem(
JsonSubTypes.Type(Book::class),
JsonSubTypes.Type(Podcast::class)
)
open class MediaType {}
open class MediaType(var metadata:MediaTypeMetadata, var coverPath:String?) {
@JsonIgnore
open fun getAudioTracks():List<AudioTrack> { return mutableListOf() }
@JsonIgnore
open fun setAudioTracks(audioTracks:List<AudioTrack>) { }
}
@JsonIgnoreProperties(ignoreUnknown = true)
data class Podcast(
var metadata:PodcastMetadata,
var coverPath:String?,
class Podcast(
metadata:PodcastMetadata,
coverPath:String?,
var tags:MutableList<String>,
var episodes:MutableList<PodcastEpisode>,
var autoDownloadEpisodes:Boolean
) : MediaType()
) : MediaType(metadata, coverPath) {
@JsonIgnore
override fun getAudioTracks():List<AudioTrack> {
var tracks = episodes.map { it.audioTrack }
return tracks.filterNotNull()
}
@JsonIgnore
override fun setAudioTracks(audioTracks:List<AudioTrack>) {
// Remove episodes no longer there in tracks
episodes = episodes.filter { ep ->
audioTracks.find { it.localFileId == ep.audioTrack?.localFileId } != null
} as MutableList<PodcastEpisode>
// Add new episodes
audioTracks.forEach { at ->
if (episodes.find{ it.audioTrack?.localFileId == at.localFileId } == null) {
var newEpisode = PodcastEpisode("local_" + at.localFileId,episodes.size + 1,null,null,at.title,null,null,null,at)
episodes.add(newEpisode)
}
}
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
data class Book(
var metadata:BookMetadata,
var coverPath:String?,
class Book(
metadata:BookMetadata,
coverPath:String?,
var tags:List<String>,
var audioFiles:List<AudioFile>,
var chapters:List<BookChapter>,
var tracks:List<AudioTrack>?,
var size:Long?,
var duration:Double?
) : MediaType()
) : MediaType(metadata, coverPath) {
@JsonIgnore
override fun getAudioTracks():List<AudioTrack> {
return tracks ?: mutableListOf()
}
@JsonIgnore
override fun setAudioTracks(audioTracks:List<AudioTrack>) {
tracks = audioTracks
var totalDuration = 0.0
tracks?.forEach {
totalDuration += it.duration
}
duration = totalDuration
}
}
// This auto-detects whether it is a Book or Podcast
@JsonTypeInfo(use=JsonTypeInfo.Id.DEDUCTION)
@@ -59,11 +99,11 @@ data class Book(
JsonSubTypes.Type(BookMetadata::class),
JsonSubTypes.Type(PodcastMetadata::class)
)
open class MediaTypeMetadata {}
open class MediaTypeMetadata(var title:String) {}
@JsonIgnoreProperties(ignoreUnknown = true)
data class BookMetadata(
var title:String,
class BookMetadata(
title:String,
var subtitle:String?,
var authors:MutableList<Author>,
var narrators:MutableList<String>,
@@ -81,15 +121,15 @@ data class BookMetadata(
var authorNameLF:String?,
var narratorName:String?,
var seriesName:String?
) : MediaTypeMetadata()
) : MediaTypeMetadata(title)
@JsonIgnoreProperties(ignoreUnknown = true)
data class PodcastMetadata(
var title:String,
class PodcastMetadata(
title:String,
var author:String?,
var feedUrl:String?,
var genres:MutableList<String>
) : MediaTypeMetadata()
) : MediaTypeMetadata(title)
@JsonIgnoreProperties(ignoreUnknown = true)
data class Author(
@@ -107,7 +147,8 @@ data class PodcastEpisode(
var title:String?,
var subtitle:String?,
var description:String?,
var audioFile:AudioFile
var audioFile:AudioFile?,
var audioTrack:AudioTrack?
)
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -14,11 +14,11 @@ class DbManager {
Paper.book("device").write("data", deviceData)
}
fun getLocalMediaItems():MutableList<LocalMediaItem> {
var localMediaItems:MutableList<LocalMediaItem> = mutableListOf()
Paper.book("localMediaItems").allKeys.forEach {
var localMediaItem:LocalMediaItem? = Paper.book("localMediaItems").read(it)
if (localMediaItem != null) {
fun getLocalLibraryItems():MutableList<LocalLibraryItem> {
var localLibraryItems:MutableList<LocalLibraryItem> = mutableListOf()
Paper.book("localLibraryItems").allKeys.forEach {
var localLibraryItem:LocalLibraryItem? = Paper.book("localLibraryItems").read(it)
if (localLibraryItem != null) {
// TODO: Check to make sure all file paths exist
// if (localMediaItem.coverContentUrl != null) {
// var file = DocumentFile.fromSingleUri(ctx)
@@ -29,31 +29,31 @@ class DbManager {
// localMediaItems.add(localMediaItem)
// }
// } else {
localMediaItems.add(localMediaItem)
localLibraryItems.add(localLibraryItem)
// }
}
}
return localMediaItems
return localLibraryItems
}
fun getLocalMediaItemsInFolder(folderId:String):List<LocalMediaItem> {
var localMediaItems = getLocalMediaItems()
return localMediaItems.filter {
fun getLocalLibraryItemsInFolder(folderId:String):List<LocalLibraryItem> {
var localLibraryItems = getLocalLibraryItems()
return localLibraryItems.filter {
it.folderId == folderId
}
}
fun getLocalMediaItem(localMediaItemId:String):LocalMediaItem? {
return Paper.book("localMediaItems").read(localMediaItemId)
fun getLocalLibraryItem(localLibraryItemId:String):LocalLibraryItem? {
return Paper.book("localLibraryItems").read(localLibraryItemId)
}
fun removeLocalMediaItem(localMediaItemId:String) {
Paper.book("localMediaItems").delete(localMediaItemId)
fun removeLocalLibraryItem(localLibraryItemId:String) {
Paper.book("localLibraryItems").delete(localLibraryItemId)
}
fun saveLocalMediaItems(localMediaItems:List<LocalMediaItem>) {
localMediaItems.map {
Paper.book("localMediaItems").write(it.id, it)
fun saveLocalLibraryItems(localLibraryItems:List<LocalLibraryItem>) {
localLibraryItems.map {
Paper.book("localLibraryItems").write(it.id, it)
}
}
@@ -77,9 +77,9 @@ class DbManager {
}
fun removeLocalFolder(folderId:String) {
var localMediaItems = getLocalMediaItemsInFolder(folderId)
localMediaItems.forEach {
Paper.book("localMediaItems").delete(it.id)
var localLibraryItems = getLocalLibraryItemsInFolder(folderId)
localLibraryItems.forEach {
Paper.book("localLibraryItems").delete(it.id)
}
Paper.book("localFolders").delete(folderId)
}
@@ -22,14 +22,54 @@ data class DeviceData(
@JsonIgnoreProperties(ignoreUnknown = true)
data class LocalLibraryItem(
var id:String,
var libraryItemId:String?,
var folderId:String,
var absolutePath:String,
var isInvalid:Boolean,
var mediaType:String,
var media:MediaType,
var localFiles:MutableList<LocalFile>,
var coverContentUrl:String?,
var coverAbsolutePath:String?,
var isLocal:Boolean
)
) {
@JsonIgnore
fun getDuration():Double {
var total = 0.0
var audioTracks = media.getAudioTracks()
audioTracks.forEach{ total += it.duration }
return total
}
@JsonIgnore
fun updateFromScan(audioTracks:List<AudioTrack>, _localFiles:MutableList<LocalFile>) {
media.setAudioTracks(audioTracks)
localFiles = _localFiles
if (coverContentUrl != null) {
if (localFiles.find { it.contentUrl == coverContentUrl } == null) {
// Cover was removed
coverContentUrl = null
coverAbsolutePath = null
media.coverPath = null
}
}
}
@JsonIgnore
fun getPlaybackSession():PlaybackSession {
var sessionId = "play-${UUID.randomUUID()}"
var mediaMetadata = media.metadata
var chapters = if (mediaType == "book") (media as Book).chapters else mutableListOf()
var authorName = "Unknown"
if (mediaType == "book") {
var bookMetadata = mediaMetadata as BookMetadata
authorName = bookMetadata?.authorName ?: "Unknown"
}
return PlaybackSession(sessionId,null,null,null, mediaType, mediaMetadata, chapters, mediaMetadata.title, authorName,null,getDuration(),PLAYMETHOD_LOCAL, media.getAudioTracks() as MutableList<AudioTrack>,0.0,null,this,null,null)
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
data class LocalMediaItem(
@@ -69,20 +109,6 @@ data class LocalMediaItem(
}
}
@JsonIgnore
fun getPlaybackSession():PlaybackSession {
var sessionId = "play-${UUID.randomUUID()}"
var mediaMetadata = getMediaMetadata()
var chapters = getAudiobookChapters()
var authorName = "Unknown"
if (mediaType == "book") {
var bookMetadata = mediaMetadata as BookMetadata
authorName = bookMetadata?.authorName ?: "Unknown"
}
return PlaybackSession(sessionId,null,null,null, mediaType, mediaMetadata, chapters, name, authorName,null,getDuration(),PLAYMETHOD_LOCAL,audioTracks,0.0,null,this,null,null)
}
@JsonIgnore
fun getAudiobookChapters():List<BookChapter> {
if (mediaType != "book" || audioTracks.isEmpty()) return mutableListOf()
@@ -98,11 +124,11 @@ data class LocalMediaItem(
var mediaMetadata = getMediaMetadata()
if (mediaType == "book") {
var chapters = getAudiobookChapters()
var book = Book(mediaMetadata as BookMetadata, coverContentUrl, mutableListOf(), mutableListOf(), chapters,audioTracks,getTotalSize(),getDuration())
return LocalLibraryItem(id, folderId, absolutePath, false,mediaType, book, localFiles, true)
var book = Book(mediaMetadata as BookMetadata, coverAbsolutePath, mutableListOf(), mutableListOf(), chapters,audioTracks,getTotalSize(),getDuration())
return LocalLibraryItem(id, null, folderId, absolutePath, false,mediaType, book, localFiles, coverContentUrl, coverAbsolutePath,true)
} else {
var podcast = Podcast(mediaMetadata as PodcastMetadata, coverContentUrl, mutableListOf(), mutableListOf(), false)
return LocalLibraryItem(id, folderId, absolutePath, false, mediaType, podcast,localFiles,true)
var podcast = Podcast(mediaMetadata as PodcastMetadata, coverAbsolutePath, mutableListOf(), mutableListOf(), false)
return LocalLibraryItem(id, null, folderId, absolutePath, false, mediaType, podcast,localFiles,coverContentUrl, coverAbsolutePath, true)
}
}
}
@@ -6,5 +6,5 @@ data class FolderScanResult(
var itemsRemoved:Int,
var itemsUpToDate:Int,
val localFolder:LocalFolder,
val localMediaItems:List<LocalMediaItem>,
val localLibraryItems:List<LocalLibraryItem>,
)
@@ -32,7 +32,7 @@ class PlaybackSession(
var audioTracks:MutableList<AudioTrack>,
var currentTime:Double,
var libraryItem:LibraryItem?,
var localMediaItem:LocalMediaItem?,
var localLibraryItem:LocalLibraryItem?,
var serverUrl:String?,
var token:String?
) {
@@ -74,7 +74,7 @@ class PlaybackSession(
@JsonIgnore
fun getCoverUri(): Uri {
if (localMediaItem?.coverContentUrl != null) return Uri.parse(localMediaItem?.coverContentUrl) ?: Uri.parse("android.resource://com.audiobookshelf.app/" + R.drawable.icon)
if (localLibraryItem?.coverContentUrl != null) return Uri.parse(localLibraryItem?.coverContentUrl) ?: Uri.parse("android.resource://com.audiobookshelf.app/" + R.drawable.icon)
if (coverPath == null) return Uri.parse("android.resource://com.audiobookshelf.app/" + R.drawable.icon)
return Uri.parse("$serverUrl/api/items/$libraryItemId/cover?token=$token")
@@ -15,6 +15,10 @@ import com.fasterxml.jackson.module.kotlin.readValue
class FolderScanner(var ctx: Context) {
private val tag = "FolderScanner"
private fun getLocalLibraryItemId(mediaItemId:String):String {
return "local_" + DeviceManager.getBase64Id(mediaItemId)
}
// TODO: CLEAN this monster! Divide into bite-size methods
fun scanForMediaItems(localFolder:LocalFolder, forceAudioProbe:Boolean):FolderScanResult? {
FFmpegKitConfig.enableLogCallback { log ->
@@ -38,32 +42,32 @@ class FolderScanner(var ctx: Context) {
// Search for files in media item folder
var foldersFound = df.search(false, DocumentFileType.FOLDER)
// Match folders found with media items already saved in db
var existingMediaItems = DeviceManager.dbManager.getLocalMediaItemsInFolder(localFolder.id)
// Match folders found with local library items already saved in db
var existingLocalLibraryItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(localFolder.id)
// Remove existing items no longer there
existingMediaItems = existingMediaItems.filter { lmi ->
var fileFound = foldersFound.find { f -> lmi.id == DeviceManager.getBase64Id(f.id) }
existingLocalLibraryItems = existingLocalLibraryItems.filter { lli ->
var fileFound = foldersFound.find { f -> lli.id == getLocalLibraryItemId(f.id) }
if (fileFound == null) {
Log.d(tag, "Existing media item is no longer in file system ${lmi.name}")
DeviceManager.dbManager.removeLocalMediaItem(lmi.id)
Log.d(tag, "Existing local library item is no longer in file system ${lli.media.metadata.title}")
DeviceManager.dbManager.removeLocalLibraryItem(lli.id)
mediaItemsRemoved++
}
fileFound != null
}
var mediaItems = mutableListOf<LocalMediaItem>()
var localLibraryItems = mutableListOf<LocalLibraryItem>()
foldersFound.forEach {
Log.d(tag, "Iterating over Folder Found ${it.name} | ${it.getSimplePath(ctx)} | URI: ${it.uri}")
foldersFound.forEach { itemFolder ->
Log.d(tag, "Iterating over Folder Found ${itemFolder.name} | ${itemFolder.getSimplePath(ctx)} | URI: ${itemFolder.uri}")
var itemFolderName = it.name ?: ""
var itemId = "local_" + DeviceManager.getBase64Id(it.id)
var itemFolderName = itemFolder.name ?: ""
var itemId = getLocalLibraryItemId(itemFolder.id)
var existingMediaItem = existingMediaItems.find { emi -> emi.id == itemId }
var existingLocalFiles = existingMediaItem?.localFiles ?: mutableListOf()
var existingAudioTracks = existingMediaItem?.audioTracks ?: mutableListOf()
var isNewOrUpdated = existingMediaItem == null
var existingItem = existingLocalLibraryItems.find { emi -> emi.id == itemId }
var existingLocalFiles = existingItem?.localFiles ?: mutableListOf()
var existingAudioTracks = existingItem?.media?.getAudioTracks() ?: mutableListOf()
var isNewOrUpdated = existingItem == null
var audioTracks = mutableListOf<AudioTrack>()
var localFiles = mutableListOf<LocalFile>()
@@ -72,13 +76,14 @@ class FolderScanner(var ctx: Context) {
var coverContentUrl:String? = null
var coverAbsolutePath:String? = null
var filesInFolder = it.search(false, DocumentFileType.FILE, arrayOf("audio/*", "image/*"))
var filesInFolder = itemFolder.search(false, DocumentFileType.FILE, arrayOf("audio/*", "image/*"))
var existingLocalFilesRemoved = existingLocalFiles.filter { elf ->
filesInFolder.find { fif -> DeviceManager.getBase64Id(fif.id) == elf.id } == null // File was not found in media item folder
}
if (existingLocalFilesRemoved.isNotEmpty()) {
Log.d(tag, "${existingLocalFilesRemoved.size} Local files were removed from local media item ${existingMediaItem?.name}")
Log.d(tag, "${existingLocalFilesRemoved.size} Local files were removed from local media item ${existingItem?.media?.metadata?.title}")
isNewOrUpdated = true
}
@@ -147,9 +152,12 @@ class FolderScanner(var ctx: Context) {
if (existingLocalFile == null) {
isNewOrUpdated = true
}
if (existingMediaItem != null && existingMediaItem.coverContentUrl == null) {
if (existingItem != null && existingItem.coverContentUrl == null) {
// Existing media item did not have a cover - cover found on scan
isNewOrUpdated = true
existingItem.coverAbsolutePath = localFile.absolutePath
existingItem.coverContentUrl = localFile.contentUrl
existingItem.media.coverPath = localFile.absolutePath
}
// First image file use as cover path
@@ -160,30 +168,36 @@ class FolderScanner(var ctx: Context) {
}
}
if (existingMediaItem != null && audioTracks.isEmpty()) {
Log.d(tag, "Local media item ${existingMediaItem.name} no longer has audio tracks - removing item")
DeviceManager.dbManager.removeLocalMediaItem(existingMediaItem.id)
if (existingItem != null && audioTracks.isEmpty()) {
Log.d(tag, "Local library item ${existingItem.media.metadata.title} no longer has audio tracks - removing item")
DeviceManager.dbManager.removeLocalLibraryItem(existingItem.id)
mediaItemsRemoved++
} else if (existingMediaItem != null && !isNewOrUpdated) {
Log.d(tag, "Local media item ${existingMediaItem.name} has no updates")
} else if (existingItem != null && !isNewOrUpdated) {
Log.d(tag, "Local library item ${existingItem.media.metadata.title} has no updates")
mediaItemsUpToDate++
} else if (audioTracks.isNotEmpty()) {
if (existingMediaItem != null) mediaItemsUpdated++
else mediaItemsAdded++
} else if (existingItem != null) {
Log.d(tag, "Updating local library item ${existingItem.media.metadata.title}")
mediaItemsUpdated++
Log.d(tag, "Found local media item named $itemFolderName with ${audioTracks.size} tracks and ${localFiles.size} local files")
var localMediaItem = LocalMediaItem(itemId, itemFolderName, localFolder.mediaType, localFolder.id, it.uri.toString(), it.getSimplePath(ctx), it.getAbsolutePath(ctx),audioTracks,localFiles,coverContentUrl,coverAbsolutePath)
mediaItems.add(localMediaItem)
existingItem.updateFromScan(audioTracks,localFiles)
localLibraryItems.add(existingItem)
} else if (audioTracks.isNotEmpty()) {
Log.d(tag, "Found local media item named $itemFolderName with ${audioTracks.size} tracks and ${localFiles.size} local files")
mediaItemsAdded++
var localMediaItem = LocalMediaItem(itemId, itemFolderName, localFolder.mediaType, localFolder.id, itemFolder.uri.toString(), itemFolder.getSimplePath(ctx), itemFolder.getAbsolutePath(ctx),audioTracks,localFiles,coverContentUrl,coverAbsolutePath)
var localLibraryItem = localMediaItem.getLocalLibraryItem()
localLibraryItems.add(localLibraryItem)
}
}
Log.d(tag, "Folder $${localFolder.name} scan Results: $mediaItemsAdded Added | $mediaItemsUpdated Updated | $mediaItemsRemoved Removed | $mediaItemsUpToDate Up-to-date")
return if (mediaItems.isNotEmpty()) {
DeviceManager.dbManager.saveLocalMediaItems(mediaItems)
return if (localLibraryItems.isNotEmpty()) {
DeviceManager.dbManager.saveLocalLibraryItems(localLibraryItems)
var folderMediaItems = DeviceManager.dbManager.getLocalMediaItemsInFolder(localFolder.id) // Get all local media items
FolderScanResult(mediaItemsAdded, mediaItemsUpdated, mediaItemsRemoved, mediaItemsUpToDate, localFolder, folderMediaItems)
var folderLibraryItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(localFolder.id) // Get all local media items
FolderScanResult(mediaItemsAdded, mediaItemsUpdated, mediaItemsRemoved, mediaItemsUpToDate, localFolder, folderLibraryItems)
} else {
Log.d(tag, "No Media Items to save")
FolderScanResult(mediaItemsAdded, mediaItemsUpdated, mediaItemsRemoved, mediaItemsUpToDate, localFolder, mutableListOf())
@@ -133,8 +133,8 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(tag, "onStartCommand $startId")
isStarted = true
Log.d(tag, "onStartCommand $startId")
return START_STICKY
}
@@ -1,8 +1,10 @@
package com.audiobookshelf.app.plugins
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.core.content.ContextCompat
import com.audiobookshelf.app.MainActivity
import com.audiobookshelf.app.data.PlaybackSession
import com.audiobookshelf.app.device.DeviceManager
@@ -75,11 +77,19 @@ class AbsAudioPlayer : Plugin() {
@PluginMethod
fun prepareLibraryItem(call: PluginCall) {
// Need to make sure the player service has been started
if (!PlayerNotificationService.isStarted) {
Log.w(tag, "prepareLibraryItem: PlayerService not started - Starting foreground service --")
Intent(mainActivity, PlayerNotificationService::class.java).also { intent ->
ContextCompat.startForegroundService(mainActivity, intent)
}
}
var libraryItemId = call.getString("libraryItemId", "").toString()
var playWhenReady = call.getBoolean("playWhenReady") == true
if (libraryItemId.startsWith("local")) { // Play local media item
DeviceManager.dbManager.getLocalMediaItem(libraryItemId)?.let {
DeviceManager.dbManager.getLocalLibraryItem(libraryItemId)?.let {
Handler(Looper.getMainLooper()).post() {
Log.d(tag, "Preparing Local Media item ${jacksonObjectMapper().writeValueAsString(it)}")
var playbackSession = it.getPlaybackSession()
@@ -48,23 +48,22 @@ class AbsDatabase : Plugin() {
}
@PluginMethod
fun getLocalMediaItemsInFolder(call:PluginCall) {
var folderId = call.getString("folderId", "").toString()
fun getLocalLibraryItem(call:PluginCall) {
var id = call.getString("id", "").toString()
GlobalScope.launch(Dispatchers.IO) {
var localMediaItems = DeviceManager.dbManager.getLocalMediaItemsInFolder(folderId)
var mediaItemsArray = jacksonObjectMapper().writeValueAsString(localMediaItems)
var jsobj = JSObject()
jsobj.put("localMediaItems", mediaItemsArray)
call.resolve(jsobj)
var localLibraryItem = DeviceManager.dbManager.getLocalLibraryItem(id)
if (localLibraryItem == null) {
call.resolve()
} else {
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(localLibraryItem)))
}
}
}
@PluginMethod
fun getLocalLibraryItems(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var localLibraryItems = DeviceManager.dbManager.getLocalMediaItems().map {
it.getLocalLibraryItem()
}
var localLibraryItems = DeviceManager.dbManager.getLocalLibraryItems()
var jsobj = JSObject()
jsobj.put("localLibraryItems", jacksonObjectMapper().writeValueAsString(localLibraryItems))
call.resolve(jsobj)
@@ -72,16 +71,14 @@ class AbsDatabase : Plugin() {
}
@PluginMethod
fun getLocalLibraryItem(call:PluginCall) {
var id = call.getString("id", "").toString()
fun getLocalLibraryItemsInFolder(call:PluginCall) {
var folderId = call.getString("folderId", "").toString()
GlobalScope.launch(Dispatchers.IO) {
var mediaItem = DeviceManager.dbManager.getLocalMediaItem(id)
var localLibraryItem = mediaItem?.getLocalLibraryItem()
if (localLibraryItem == null) {
call.resolve()
} else {
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(localLibraryItem)))
}
var localMediaItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(folderId)
var mediaItemsArray = jacksonObjectMapper().writeValueAsString(localMediaItems)
var jsobj = JSObject()
jsobj.put("localLibraryItems", mediaItemsArray)
call.resolve(jsobj)
}
}
@@ -118,11 +118,11 @@ class AbsDownloader : Plugin() {
fun getAbMetadataText(libraryItem:LibraryItem):String {
var bookMedia = libraryItem.media as com.audiobookshelf.app.data.Book
var fileString = ";ABMETADATA1\n"
fileString += "#libraryItemId=${libraryItem.id}\n"
fileString += "title=${bookMedia.metadata.title}\n"
fileString += "author=${bookMedia.metadata.authorName}\n"
fileString += "narrator=${bookMedia.metadata.narratorName}\n"
fileString += "series=${bookMedia.metadata.seriesName}\n"
// fileString += "#libraryItemId=${libraryItem.id}\n"
// fileString += "title=${bookMedia.metadata.title}\n"
// fileString += "author=${bookMedia.metadata.authorName}\n"
// fileString += "narrator=${bookMedia.metadata.narratorName}\n"
// fileString += "series=${bookMedia.metadata.seriesName}\n"
return fileString
}