diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt index 350e4cb81..fffd95b1b 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -40,6 +40,7 @@ import org.oxycblt.musikr.Playlist import org.oxycblt.musikr.Song import org.oxycblt.musikr.Storage import org.oxycblt.musikr.cache.MutableSongCache +import org.oxycblt.musikr.log.Logger import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.tag.interpret.Naming import org.oxycblt.musikr.tag.interpret.Separators @@ -394,7 +395,8 @@ constructor( val interpretation = Interpretation(nameFactory, separators) val result = - Musikr.new(context, storage, interpretation).run(locations, ::emitIndexingProgress) + Musikr.new(context, storage, interpretation, Logger.root()) + .run(locations, ::emitIndexingProgress) // Music loading completed, update the revision right now so we re-use this work // later. musicSettings.revision = newRevision diff --git a/musikr/src/main/java/org/oxycblt/musikr/Musikr.kt b/musikr/src/main/java/org/oxycblt/musikr/Musikr.kt index 022dccb2c..bc1f243b3 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/Musikr.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/Musikr.kt @@ -19,6 +19,7 @@ package org.oxycblt.musikr import android.content.Context +import android.os.Build import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.buffer @@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import org.oxycblt.musikr.fs.MusicLocation +import org.oxycblt.musikr.log.Logger import org.oxycblt.musikr.pipeline.Divert import org.oxycblt.musikr.pipeline.EvaluateStep import org.oxycblt.musikr.pipeline.ExploreStep @@ -68,18 +70,25 @@ interface Musikr { * Create a new instance from the given configuration. * * @param context The context to use for loading resources. + * @param logger The logger to use for logging events. * @param storage Side-effect laden storage for use within the music loader **and** when * mutating [MutableLibrary]. You should take responsibility for managing their long-term * state. * @param interpretation The configuration to use for interpreting certain vague tags. This * should be configured by the user, if possible. */ - fun new(context: Context, storage: Storage, interpretation: Interpretation): Musikr = + fun new( + context: Context, + storage: Storage, + interpretation: Interpretation, + logger: Logger + ): Musikr = MusikrImpl( + logger, storage, - ExploreStep.from(context, storage), - ExtractStep.from(context, storage), - EvaluateStep.new(storage, interpretation)) + ExploreStep.from(context, storage, logger), + ExtractStep.from(context, storage, logger), + EvaluateStep.new(storage, interpretation, logger)) } } @@ -116,6 +125,7 @@ sealed interface IndexingProgress { } private class MusikrImpl( + private val logger: Logger, private val storage: Storage, private val exploreStep: ExploreStep, private val extractStep: ExtractStep, @@ -125,6 +135,16 @@ private class MusikrImpl( locations: List, onProgress: suspend (IndexingProgress) -> Unit ) = coroutineScope { + logger.d( + "musikr start.", + "hw:", + Build.MANUFACTURER, + Build.MODEL, + Build.SUPPORTED_ABIS.joinToString(" "), + "sw:", + Build.VERSION.SDK_INT, + Build.DISPLAY) + var exploredCount = 0 var extractedCount = 0 val explored = diff --git a/musikr/src/main/java/org/oxycblt/musikr/log/Logger.kt b/musikr/src/main/java/org/oxycblt/musikr/log/Logger.kt new file mode 100644 index 000000000..803b9a4b1 --- /dev/null +++ b/musikr/src/main/java/org/oxycblt/musikr/log/Logger.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 Auxio Project + * Logger.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 . + */ + +package org.oxycblt.musikr.log + +import android.util.Log + +interface Logger { + fun v(vararg msgs: Any) + + fun d(vararg msgs: Any) + + fun w(vararg msgs: Any) + + fun e(vararg msgs: Any) + + fun primary(tag: String): Logger + + fun secondary(tag: String): Logger + + companion object { + fun root(): Logger = LoggerImpl("mskr", null) + } +} + +private class LoggerImpl(private val primaryTag: String, private val secondaryTag: String?) : + Logger { + override fun v(vararg msgs: Any) { + Log.v(primaryTag, "[$secondaryTag] ${msgs.joinToString(" ")}") + } + + override fun d(vararg msgs: Any) { + Log.d(primaryTag, "[$secondaryTag] ${msgs.joinToString(" ")}") + } + + override fun w(vararg msgs: Any) { + Log.w(primaryTag, "[$secondaryTag] ${msgs.joinToString(" ")}") + } + + override fun e(vararg msgs: Any) { + Log.e(primaryTag, "[$secondaryTag] ${msgs.joinToString(" ")}") + } + + override fun primary(tag: String) = LoggerImpl("${primaryTag}.${tag}", secondaryTag) + + override fun secondary(tag: String) = + LoggerImpl(primaryTag, secondaryTag?.let { "$it.$tag" } ?: tag) +} diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt index ddc15d0a7..4e195fdbf 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt @@ -30,6 +30,7 @@ import org.oxycblt.musikr.Interpretation import org.oxycblt.musikr.MutableLibrary import org.oxycblt.musikr.Storage import org.oxycblt.musikr.graph.MusicGraph +import org.oxycblt.musikr.log.Logger import org.oxycblt.musikr.model.LibraryFactory import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.playlist.interpret.PlaylistInterpreter @@ -39,12 +40,13 @@ internal interface EvaluateStep { suspend fun evaluate(complete: Flow): MutableLibrary companion object { - fun new(storage: Storage, interpretation: Interpretation): EvaluateStep = + fun new(storage: Storage, interpretation: Interpretation, logger: Logger): EvaluateStep = EvaluateStepImpl( Interpreter.new(interpretation), PlaylistInterpreter.new(interpretation), storage.storedPlaylists, - LibraryFactory.new()) + LibraryFactory.new(), + logger.primary("eval")) } } @@ -52,9 +54,11 @@ private class EvaluateStepImpl( private val interpreter: Interpreter, private val playlistInterpreter: PlaylistInterpreter, private val storedPlaylists: StoredPlaylists, - private val libraryFactory: LibraryFactory + private val libraryFactory: LibraryFactory, + private val logger: Logger ) : EvaluateStep { override suspend fun evaluate(complete: Flow): MutableLibrary { + logger.d("evaluate start.") val filterFlow = complete.divert { when (it) { @@ -80,7 +84,9 @@ private class EvaluateStepImpl( preSongs.onEach { graphBuilder.add(it) }, prePlaylists.onEach { graphBuilder.add(it) }) graphBuild.collect() + logger.d("starting graph build") val graph = graphBuilder.build() + logger.d("graph build done, creating library") return libraryFactory.create(graph, storedPlaylists, playlistInterpreter) } } diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExploreStep.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExploreStep.kt index 676b7676b..0f6e485ae 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExploreStep.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExploreStep.kt @@ -36,6 +36,7 @@ import org.oxycblt.musikr.cover.Covers import org.oxycblt.musikr.cover.ObtainResult import org.oxycblt.musikr.fs.MusicLocation import org.oxycblt.musikr.fs.device.DeviceFS +import org.oxycblt.musikr.log.Logger import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.playlist.m3u.M3U @@ -43,9 +44,14 @@ internal interface ExploreStep { fun explore(locations: List): Flow companion object { - fun from(context: Context, storage: Storage): ExploreStep = + fun from(context: Context, storage: Storage, logger: Logger): ExploreStep = ExploreStepImpl( - DeviceFS.from(context), storage.storedPlaylists, storage.cache, storage.covers) + DeviceFS.from(context), + storage.storedPlaylists, + storage.cache, + storage.covers, + logger.primary("expl"), + ) } } @@ -53,9 +59,11 @@ private class ExploreStepImpl( private val deviceFS: DeviceFS, private val storedPlaylists: StoredPlaylists, private val songCache: SongCache, - private val covers: Covers + private val covers: Covers, + private val logger: Logger, ) : ExploreStep { override fun explore(locations: List): Flow { + logger.d("explore start.") val audioFiles = deviceFS .explore(locations.asFlow()) diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt index fdc57ef9a..0cfd3e45d 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt @@ -31,6 +31,7 @@ import org.oxycblt.musikr.Storage import org.oxycblt.musikr.cache.CachedSong import org.oxycblt.musikr.cache.MutableSongCache import org.oxycblt.musikr.cover.MutableCovers +import org.oxycblt.musikr.log.Logger import org.oxycblt.musikr.metadata.Metadata import org.oxycblt.musikr.metadata.MetadataExtractor import org.oxycblt.musikr.metadata.MetadataHandle @@ -40,9 +41,14 @@ internal interface ExtractStep { fun extract(nodes: Flow): Flow companion object { - fun from(context: Context, storage: Storage): ExtractStep = + fun from(context: Context, storage: Storage, logger: Logger): ExtractStep = ExtractStepImpl( - MetadataExtractor.new(context), TagParser.new(), storage.cache, storage.covers) + MetadataExtractor.new(context), + TagParser.new(), + storage.cache, + storage.covers, + logger.primary("exct"), + ) } } @@ -50,9 +56,12 @@ private class ExtractStepImpl( private val metadataExtractor: MetadataExtractor, private val tagParser: TagParser, private val cache: MutableSongCache, - private val storedCovers: MutableCovers + private val storedCovers: MutableCovers, + private val logger: Logger ) : ExtractStep { override fun extract(nodes: Flow): Flow { + logger.d("extract start.") + val newSongs = nodes.filterIsInstance() val handles = diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Interpreter.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Interpreter.kt index a4d24af4f..658942bf7 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Interpreter.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Interpreter.kt @@ -1,6 +1,6 @@ /* * Copyright (c) 2024 Auxio Project - * TagInterpreter.kt is part of Auxio. + * Interpreter.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