musikr: remove di
This commit is contained in:
parent
a2498db6e5
commit
e16b23f34e
23 changed files with 80 additions and 268 deletions
|
@ -26,6 +26,7 @@ import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
import org.oxycblt.musikr.Musikr
|
||||||
import org.oxycblt.musikr.cache.CacheDatabase
|
import org.oxycblt.musikr.cache.CacheDatabase
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
@ -42,4 +43,6 @@ class MusikrShimModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun tagDatabase(@ApplicationContext context: Context) = CacheDatabase.from(context)
|
fun tagDatabase(@ApplicationContext context: Context) = CacheDatabase.from(context)
|
||||||
|
|
||||||
|
@Provides fun musikr(@ApplicationContext context: Context) = Musikr.new(context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr
|
package org.oxycblt.musikr
|
||||||
|
|
||||||
import javax.inject.Inject
|
import android.content.Context
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.buffer
|
import kotlinx.coroutines.flow.buffer
|
||||||
|
@ -37,6 +37,11 @@ interface Musikr {
|
||||||
interpretation: Interpretation,
|
interpretation: Interpretation,
|
||||||
onProgress: suspend (IndexingProgress) -> Unit = {}
|
onProgress: suspend (IndexingProgress) -> Unit = {}
|
||||||
): MutableLibrary
|
): MutableLibrary
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun new(context: Context): Musikr =
|
||||||
|
MusikrImpl(ExploreStep.from(context), ExtractStep.from(context), EvaluateStep.new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,9 +55,7 @@ sealed interface IndexingProgress {
|
||||||
data object Indeterminate : IndexingProgress
|
data object Indeterminate : IndexingProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
class MusikrImpl
|
class MusikrImpl(
|
||||||
@Inject
|
|
||||||
constructor(
|
|
||||||
private val exploreStep: ExploreStep,
|
private val exploreStep: ExploreStep,
|
||||||
private val extractStep: ExtractStep,
|
private val extractStep: ExtractStep,
|
||||||
private val evaluateStep: EvaluateStep
|
private val evaluateStep: EvaluateStep
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 Auxio Project
|
|
||||||
* MusikrModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr
|
|
||||||
|
|
||||||
import dagger.Binds
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.hilt.InstallIn
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
interface MusikrModule {
|
|
||||||
@Binds fun musikr(impl: MusikrImpl): Musikr
|
|
||||||
}
|
|
|
@ -19,8 +19,6 @@
|
||||||
package org.oxycblt.musikr.metadata
|
package org.oxycblt.musikr.metadata
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
@ -31,10 +29,13 @@ import org.oxycblt.musikr.fs.query.DeviceFile
|
||||||
|
|
||||||
interface MetadataExtractor {
|
interface MetadataExtractor {
|
||||||
suspend fun extract(file: DeviceFile): Metadata?
|
suspend fun extract(file: DeviceFile): Metadata?
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(context: Context): MetadataExtractor = MetadataExtractorImpl(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MetadataExtractorImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
private class MetadataExtractorImpl(private val context: Context) : MetadataExtractor {
|
||||||
MetadataExtractor {
|
|
||||||
override suspend fun extract(file: DeviceFile) =
|
override suspend fun extract(file: DeviceFile) =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
KTagLib.open(context, FileRef(unlikelyToBeNull(file.path.name), file.uri))
|
KTagLib.open(context, FileRef(unlikelyToBeNull(file.path.name), file.uri))
|
||||||
|
|
|
@ -28,6 +28,4 @@ import dagger.hilt.components.SingletonComponent
|
||||||
interface MetadataModule {
|
interface MetadataModule {
|
||||||
@Binds
|
@Binds
|
||||||
fun audioPropertiesFactory(interpreter: AudioPropertiesFactoryImpl): AudioProperties.Factory
|
fun audioPropertiesFactory(interpreter: AudioPropertiesFactoryImpl): AudioProperties.Factory
|
||||||
|
|
||||||
@Binds fun metadataExtractor(extractor: MetadataExtractorImpl): MetadataExtractor
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.model
|
package org.oxycblt.musikr.model
|
||||||
|
|
||||||
import javax.inject.Inject
|
|
||||||
import org.oxycblt.musikr.Album
|
import org.oxycblt.musikr.Album
|
||||||
import org.oxycblt.musikr.Artist
|
import org.oxycblt.musikr.Artist
|
||||||
import org.oxycblt.musikr.Genre
|
import org.oxycblt.musikr.Genre
|
||||||
|
@ -32,9 +31,13 @@ import org.oxycblt.musikr.graph.SongVertex
|
||||||
|
|
||||||
interface LibraryFactory {
|
interface LibraryFactory {
|
||||||
fun create(graph: MusicGraph): MutableLibrary
|
fun create(graph: MusicGraph): MutableLibrary
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun new(): LibraryFactory = LibraryFactoryImpl()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LibraryFactoryImpl @Inject constructor() : LibraryFactory {
|
private class LibraryFactoryImpl() : LibraryFactory {
|
||||||
override fun create(graph: MusicGraph): MutableLibrary {
|
override fun create(graph: MusicGraph): MutableLibrary {
|
||||||
val songs =
|
val songs =
|
||||||
graph.songVertex.mapTo(mutableSetOf()) { vertex ->
|
graph.songVertex.mapTo(mutableSetOf()) { vertex ->
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 Auxio Project
|
|
||||||
* ModelModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr.model
|
|
||||||
|
|
||||||
import dagger.Binds
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.hilt.InstallIn
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
interface ModelModule {
|
|
||||||
@Binds fun libraryFactory(factory: LibraryFactoryImpl): LibraryFactory
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.pipeline
|
package org.oxycblt.musikr.pipeline
|
||||||
|
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
@ -37,11 +36,13 @@ interface EvaluateStep {
|
||||||
interpretation: Interpretation,
|
interpretation: Interpretation,
|
||||||
extractedMusic: Flow<ExtractedMusic>
|
extractedMusic: Flow<ExtractedMusic>
|
||||||
): MutableLibrary
|
): MutableLibrary
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun new(): EvaluateStep = EvaluateStepImpl(TagInterpreter.new(), LibraryFactory.new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EvaluateStepImpl
|
private class EvaluateStepImpl(
|
||||||
@Inject
|
|
||||||
constructor(
|
|
||||||
private val tagInterpreter: TagInterpreter,
|
private val tagInterpreter: TagInterpreter,
|
||||||
private val libraryFactory: LibraryFactory
|
private val libraryFactory: LibraryFactory
|
||||||
) : EvaluateStep {
|
) : EvaluateStep {
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
package org.oxycblt.musikr.pipeline
|
package org.oxycblt.musikr.pipeline
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.asFlow
|
import kotlinx.coroutines.flow.asFlow
|
||||||
|
@ -33,12 +31,15 @@ import org.oxycblt.musikr.playlist.m3u.M3U
|
||||||
|
|
||||||
interface ExploreStep {
|
interface ExploreStep {
|
||||||
fun explore(locations: List<MusicLocation>): Flow<ExploreNode>
|
fun explore(locations: List<MusicLocation>): Flow<ExploreNode>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(context: Context): ExploreStep = ExploreStepImpl(DeviceFiles.from(context))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExploreStepImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
private class ExploreStepImpl(private val deviceFiles: DeviceFiles) : ExploreStep {
|
||||||
ExploreStep {
|
|
||||||
override fun explore(locations: List<MusicLocation>) =
|
override fun explore(locations: List<MusicLocation>) =
|
||||||
DeviceFiles.from(context)
|
deviceFiles
|
||||||
.explore(locations.asFlow())
|
.explore(locations.asFlow())
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
when {
|
when {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.pipeline
|
package org.oxycblt.musikr.pipeline
|
||||||
|
|
||||||
import javax.inject.Inject
|
import android.content.Context
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
@ -39,12 +39,17 @@ import timber.log.Timber as L
|
||||||
|
|
||||||
interface ExtractStep {
|
interface ExtractStep {
|
||||||
fun extract(storage: Storage, nodes: Flow<ExploreNode>): Flow<ExtractedMusic>
|
fun extract(storage: Storage, nodes: Flow<ExploreNode>): Flow<ExtractedMusic>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(context: Context): ExtractStep =
|
||||||
|
ExtractStepImpl(MetadataExtractor.from(context), TagParser.new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExtractStepImpl
|
private class ExtractStepImpl(
|
||||||
@Inject
|
private val metadataExtractor: MetadataExtractor,
|
||||||
constructor(private val metadataExtractor: MetadataExtractor, private val tagParser: TagParser) :
|
private val tagParser: TagParser
|
||||||
ExtractStep {
|
) : ExtractStep {
|
||||||
override fun extract(storage: Storage, nodes: Flow<ExploreNode>): Flow<ExtractedMusic> {
|
override fun extract(storage: Storage, nodes: Flow<ExploreNode>): Flow<ExtractedMusic> {
|
||||||
val cacheResults =
|
val cacheResults =
|
||||||
nodes
|
nodes
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 Auxio Project
|
|
||||||
* PipelineModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr.pipeline
|
|
||||||
|
|
||||||
import dagger.Binds
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.hilt.InstallIn
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
interface InterpretModule {
|
|
||||||
@Binds fun exploreStep(step: ExploreStepImpl): ExploreStep
|
|
||||||
|
|
||||||
@Binds fun extractStep(step: ExtractStepImpl): ExtractStep
|
|
||||||
|
|
||||||
@Binds fun evaluateStep(step: EvaluateStepImpl): EvaluateStep
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Auxio Project
|
|
||||||
* PlaylistModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr.playlist
|
|
|
@ -18,11 +18,13 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.playlist.db
|
package org.oxycblt.musikr.playlist.db
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
|
@ -39,7 +41,15 @@ import org.oxycblt.musikr.Music
|
||||||
exportSchema = false)
|
exportSchema = false)
|
||||||
@TypeConverters(Music.UID.TypeConverters::class)
|
@TypeConverters(Music.UID.TypeConverters::class)
|
||||||
abstract class PlaylistDatabase : RoomDatabase() {
|
abstract class PlaylistDatabase : RoomDatabase() {
|
||||||
abstract fun playlistDao(): PlaylistDao
|
internal abstract fun playlistDao(): PlaylistDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(context: Context) =
|
||||||
|
Room.databaseBuilder(
|
||||||
|
context.applicationContext, PlaylistDatabase::class.java, "user_music.db")
|
||||||
|
.fallbackToDestructiveMigration()
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle playlist defragmentation? I really don't want dead songs to accumulate in this
|
// TODO: Handle playlist defragmentation? I really don't want dead songs to accumulate in this
|
||||||
|
@ -51,7 +61,7 @@ abstract class PlaylistDatabase : RoomDatabase() {
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@Dao
|
@Dao
|
||||||
abstract class PlaylistDao {
|
internal abstract class PlaylistDao {
|
||||||
/**
|
/**
|
||||||
* Read out all playlists stored in the database.
|
* Read out all playlists stored in the database.
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.oxycblt.musikr.Music
|
||||||
*
|
*
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
data class RawPlaylist(
|
internal data class RawPlaylist(
|
||||||
@Embedded val playlistInfo: PlaylistInfo,
|
@Embedded val playlistInfo: PlaylistInfo,
|
||||||
@Relation(
|
@Relation(
|
||||||
parentColumn = "playlistUid",
|
parentColumn = "playlistUid",
|
||||||
|
@ -45,14 +45,14 @@ data class RawPlaylist(
|
||||||
*
|
*
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@Entity data class PlaylistInfo(@PrimaryKey val playlistUid: Music.UID, val name: String)
|
@Entity internal data class PlaylistInfo(@PrimaryKey val playlistUid: Music.UID, val name: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Song information corresponding to a [RawPlaylist] entry.
|
* Song information corresponding to a [RawPlaylist] entry.
|
||||||
*
|
*
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@Entity data class PlaylistSong(@PrimaryKey val songUid: Music.UID)
|
@Entity internal data class PlaylistSong(@PrimaryKey val songUid: Music.UID)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Links individual songs to a playlist entry.
|
* Links individual songs to a playlist entry.
|
||||||
|
@ -60,7 +60,7 @@ data class RawPlaylist(
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
data class PlaylistSongCrossRef(
|
internal data class PlaylistSongCrossRef(
|
||||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||||
@ColumnInfo(index = true) val playlistUid: Music.UID,
|
@ColumnInfo(index = true) val playlistUid: Music.UID,
|
||||||
@ColumnInfo(index = true) val songUid: Music.UID
|
@ColumnInfo(index = true) val songUid: Music.UID
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.playlist.db
|
package org.oxycblt.musikr.playlist.db
|
||||||
|
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.asFlow
|
import kotlinx.coroutines.flow.asFlow
|
||||||
import kotlinx.coroutines.flow.emitAll
|
import kotlinx.coroutines.flow.emitAll
|
||||||
|
@ -28,9 +27,13 @@ import org.oxycblt.musikr.playlist.PlaylistFile
|
||||||
|
|
||||||
interface StoredPlaylists {
|
interface StoredPlaylists {
|
||||||
fun read(): Flow<PlaylistFile>
|
fun read(): Flow<PlaylistFile>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(database: PlaylistDatabase): StoredPlaylists =
|
||||||
|
StoredPlaylistsImpl(database.playlistDao())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StoredPlaylistsImpl @Inject constructor(private val playlistDao: PlaylistDao) :
|
private class StoredPlaylistsImpl(private val playlistDao: PlaylistDao) : StoredPlaylists {
|
||||||
StoredPlaylists {
|
|
||||||
override fun read() = flow { emitAll(playlistDao.readRawPlaylists().asFlow().map { TODO() }) }
|
override fun read() = flow { emitAll(playlistDao.readRawPlaylists().asFlow().map { TODO() }) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Auxio Project
|
|
||||||
* UserModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr.playlist.db
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.room.Room
|
|
||||||
import dagger.Binds
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.Provides
|
|
||||||
import dagger.hilt.InstallIn
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
interface PlaylistModule {
|
|
||||||
@Binds fun storedPlaylists(impl: StoredPlaylistsImpl): StoredPlaylists
|
|
||||||
}
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
class PlaylistRoomModule {
|
|
||||||
@Provides fun playlistDao(database: PlaylistDatabase) = database.playlistDao()
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
fun playlistDatabase(@ApplicationContext context: Context) =
|
|
||||||
Room.databaseBuilder(
|
|
||||||
context.applicationContext, PlaylistDatabase::class.java, "user_music.db")
|
|
||||||
.fallbackToDestructiveMigration()
|
|
||||||
.build()
|
|
||||||
}
|
|
|
@ -25,7 +25,6 @@ import java.io.BufferedWriter
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import javax.inject.Inject
|
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
import org.oxycblt.musikr.Playlist
|
import org.oxycblt.musikr.Playlist
|
||||||
import org.oxycblt.musikr.fs.Components
|
import org.oxycblt.musikr.fs.Components
|
||||||
|
@ -80,9 +79,7 @@ interface M3U {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class M3UImpl
|
private class M3UImpl(
|
||||||
@Inject
|
|
||||||
constructor(
|
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
private val volumeManager: VolumeManager
|
private val volumeManager: VolumeManager
|
||||||
) : M3U {
|
) : M3U {
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 Auxio Project
|
|
||||||
* InterpretModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr.tag.interpret
|
|
||||||
|
|
||||||
import dagger.Binds
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.hilt.InstallIn
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
interface InterpretModule {
|
|
||||||
@Binds fun tagInterpreter(factory: TagInterpreterImpl): TagInterpreter
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.tag.interpret
|
package org.oxycblt.musikr.tag.interpret
|
||||||
|
|
||||||
import javax.inject.Inject
|
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
|
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
|
||||||
import org.oxycblt.auxio.util.toUuidOrNull
|
import org.oxycblt.auxio.util.toUuidOrNull
|
||||||
|
@ -39,9 +38,13 @@ interface TagInterpreter {
|
||||||
cover: Cover.Single?,
|
cover: Cover.Single?,
|
||||||
interpretation: Interpretation
|
interpretation: Interpretation
|
||||||
): PreSong
|
): PreSong
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun new(): TagInterpreter = TagInterpreterImpl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TagInterpreterImpl @Inject constructor() : TagInterpreter {
|
private data object TagInterpreterImpl : TagInterpreter {
|
||||||
override fun interpret(
|
override fun interpret(
|
||||||
file: DeviceFile,
|
file: DeviceFile,
|
||||||
parsedTags: ParsedTags,
|
parsedTags: ParsedTags,
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 Auxio Project
|
|
||||||
* ParseModule.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.musikr.tag.parse
|
|
||||||
|
|
||||||
import dagger.Binds
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.hilt.InstallIn
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
interface ParseModule {
|
|
||||||
@Binds fun tagParser(factory: TagParserImpl): TagParser
|
|
||||||
}
|
|
|
@ -18,17 +18,20 @@
|
||||||
|
|
||||||
package org.oxycblt.musikr.tag.parse
|
package org.oxycblt.musikr.tag.parse
|
||||||
|
|
||||||
import javax.inject.Inject
|
|
||||||
import org.oxycblt.ktaglib.Metadata
|
import org.oxycblt.ktaglib.Metadata
|
||||||
import org.oxycblt.musikr.fs.query.DeviceFile
|
import org.oxycblt.musikr.fs.query.DeviceFile
|
||||||
|
|
||||||
interface TagParser {
|
interface TagParser {
|
||||||
fun parse(file: DeviceFile, metadata: Metadata): ParsedTags
|
fun parse(file: DeviceFile, metadata: Metadata): ParsedTags
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun new(): TagParser = TagParserImpl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MissingTagError(what: String) : Error("missing tag: $what")
|
class MissingTagError(what: String) : Error("missing tag: $what")
|
||||||
|
|
||||||
class TagParserImpl @Inject constructor() : TagParser {
|
private data object TagParserImpl : TagParser {
|
||||||
override fun parse(file: DeviceFile, metadata: Metadata): ParsedTags {
|
override fun parse(file: DeviceFile, metadata: Metadata): ParsedTags {
|
||||||
return ParsedTags(
|
return ParsedTags(
|
||||||
durationMs = metadata.properties.durationMs,
|
durationMs = metadata.properties.durationMs,
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
JVMMetadataBuilder::JVMMetadataBuilder(JNIEnv *env) : env(env), id3v2(env), xiph(env), mp4(env),
|
JVMMetadataBuilder::JVMMetadataBuilder(JNIEnv *env) : env(env), id3v2(env), xiph(env), mp4(env),
|
||||||
cover(), properties(nullptr) {}
|
cover(), properties(nullptr) {}
|
||||||
|
|
||||||
void JVMMetadataBuilder::setMimeType(const std::string_view mimeType) {
|
void JVMMetadataBuilder::setMimeType(const std::string_view type) {
|
||||||
this->mimeType = mimeType;
|
this->mimeType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMMetadataBuilder::setId3v2(const TagLib::ID3v2::Tag &tag) {
|
void JVMMetadataBuilder::setId3v2(const TagLib::ID3v2::Tag &tag) {
|
||||||
|
@ -124,8 +124,9 @@ jobject JVMMetadataBuilder::build() {
|
||||||
jobject mp4Map = mp4.getObject();
|
jobject mp4Map = mp4.getObject();
|
||||||
jbyteArray coverArray = nullptr;
|
jbyteArray coverArray = nullptr;
|
||||||
if (cover.has_value()) {
|
if (cover.has_value()) {
|
||||||
coverArray = env->NewByteArray(static_cast<jsize>(cover->size());
|
auto coverSize = static_cast<jsize>(cover->size());
|
||||||
env->SetByteArrayRegion(coverArray, 0, cover->size(), reinterpret_cast<const jbyte *>(cover->data()));
|
coverArray = env->NewByteArray(coverSize);
|
||||||
|
env->SetByteArrayRegion(coverArray, 0, coverSize, reinterpret_cast<const jbyte *>(cover->data()));
|
||||||
}
|
}
|
||||||
jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map, xiphMap, mp4Map, coverArray, propertiesObj);
|
jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map, xiphMap, mp4Map, coverArray, propertiesObj);
|
||||||
env->DeleteLocalRef(metadataClass);
|
env->DeleteLocalRef(metadataClass);
|
||||||
|
|
|
@ -20,7 +20,7 @@ class JVMMetadataBuilder {
|
||||||
public:
|
public:
|
||||||
JVMMetadataBuilder(JNIEnv *env);
|
JVMMetadataBuilder(JNIEnv *env);
|
||||||
|
|
||||||
void setMimeType(const std::string_view mimeType);
|
void setMimeType(const std::string_view type);
|
||||||
void setId3v2(const TagLib::ID3v2::Tag &tag);
|
void setId3v2(const TagLib::ID3v2::Tag &tag);
|
||||||
void setXiph(const TagLib::Ogg::XiphComment &tag);
|
void setXiph(const TagLib::Ogg::XiphComment &tag);
|
||||||
void setMp4(const TagLib::MP4::Tag &tag);
|
void setMp4(const TagLib::MP4::Tag &tag);
|
||||||
|
|
Loading…
Reference in a new issue