Skip to content

Commit

Permalink
music: rename import to external
Browse files Browse the repository at this point in the history
Apparently hilt doesn't like a module with the name import, probably
because of a keyword conflict.
  • Loading branch information
OxygenCobalt committed Dec 20, 2023
1 parent 88bce61 commit e553744
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 50 deletions.
6 changes: 4 additions & 2 deletions app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import org.oxycblt.auxio.list.ListSettings
import org.oxycblt.auxio.music.import.PlaylistImporter
import org.oxycblt.auxio.music.external.PlaylistImporter
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import org.oxycblt.auxio.util.logD
Expand Down Expand Up @@ -66,7 +66,8 @@ constructor(

private val _importError = MutableEvent<Unit>()
/** Flag for when playlist importing failed. Consume this and show an error if active. */
val importError: Event<Unit> get() = _importError
val importError: Event<Unit>
get() = _importError

init {
musicRepository.addUpdateListener(this)
Expand Down Expand Up @@ -125,6 +126,7 @@ constructor(

/**
* Import a playlist from a file [Uri]. Errors pushed to [importError].
*
* @param uri The [Uri] of the file to import.
* @see PlaylistImporter
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2023 Auxio Project
* ForeignModule.kt is part of Auxio.
* ExternalModule.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
Expand All @@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.oxycblt.auxio.music.import
package org.oxycblt.auxio.music.external

import dagger.Binds
import dagger.Module
Expand All @@ -25,7 +25,7 @@ import dagger.hilt.components.SingletonComponent

@Module
@InstallIn(SingletonComponent::class)
interface ImportModule {
interface ExternalModule {
@Binds fun playlistImporter(playlistImporter: PlaylistImporterImpl): PlaylistImporter

@Binds fun m3u(m3u: M3UImpl): M3U
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.oxycblt.auxio.music.import
package org.oxycblt.auxio.music.external

import org.oxycblt.auxio.music.fs.Components
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import javax.inject.Inject
import org.oxycblt.auxio.music.fs.Components
import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.util.logW
import javax.inject.Inject

interface M3U {
fun read(stream: InputStream, workingDirectory: Path): List<Path>?
Expand Down Expand Up @@ -59,7 +59,10 @@ class M3UImpl @Inject constructor() : M3U {
return media.ifEmpty { null }
}

private fun resolveRelativePath(relative: Components, workingDirectory: Components): Components {
private fun resolveRelativePath(
relative: Components,
workingDirectory: Components
): Components {
var components = workingDirectory
for (component in relative.components) {
when (component) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
package org.oxycblt.auxio.music.import
/*
* Copyright (c) 2023 Auxio Project
* PlaylistImporter.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.auxio.music.external

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import dagger.hilt.android.qualifiers.ApplicationContext
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.device.DeviceLibrary
import javax.inject.Inject
import org.oxycblt.auxio.music.fs.ContentPathResolver
import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.music.fs.contentResolverSafe
import javax.inject.Inject

interface PlaylistImporter {
suspend fun import(uri: Uri): ImportedPlaylist?
}

data class ImportedPlaylist(val name: String?, val paths: List<Path>)

class PlaylistImporterImpl @Inject constructor(
class PlaylistImporterImpl
@Inject
constructor(
@ApplicationContext private val contentResolver: ContentResolver,
private val contentPathResolver: ContentPathResolver,
private val m3u: M3U
Expand All @@ -30,4 +45,4 @@ class PlaylistImporterImpl @Inject constructor(
return ImportedPlaylist(null, paths)
}
}
}
}
72 changes: 41 additions & 31 deletions app/src/main/java/org/oxycblt/auxio/music/fs/ContentPathResolver.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* Copyright (c) 2023 Auxio Project
* ContentPathResolver.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.auxio.music.fs

import android.content.ContentResolver
Expand All @@ -7,17 +25,18 @@ import android.os.Build
import android.provider.MediaStore
import androidx.core.database.getStringOrNull
import org.oxycblt.auxio.util.logE
import org.oxycblt.auxio.util.logW
import javax.inject.Inject

/**
* Resolves a content URI into a [Path] instance.
* TODO: Integrate this with [MediaStoreExtractor].
*
* @author Alexander Capehart (OxygenCobalt)
*
* TODO: Integrate this with [MediaStoreExtractor].
*/
interface ContentPathResolver {
/**
* Resolve a content [Uri] into it's corresponding [Path].
*
* @param uri The content [Uri] to resolve.
* @return The corresponding [Path], or null if the [Uri] is invalid.
*/
Expand All @@ -28,7 +47,6 @@ interface ContentPathResolver {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ->
Api29ContentPathResolverImpl(context.contentResolverSafe, volumeManager)

else -> Api21ContentPathResolverImpl(context.contentResolverSafe, volumeManager)
}
}
Expand All @@ -39,12 +57,11 @@ private class Api21ContentPathResolverImpl(
private val volumeManager: VolumeManager
) : ContentPathResolver {
override fun resolve(uri: Uri): Path? {
val rawPath = contentResolver.useQuery(
uri, arrayOf(MediaStore.MediaColumns.DATA)
) { cursor ->
cursor.moveToFirst()
cursor.getStringOrNull(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA))
}
val rawPath =
contentResolver.useQuery(uri, arrayOf(MediaStore.MediaColumns.DATA)) { cursor ->
cursor.moveToFirst()
cursor.getStringOrNull(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA))
}

if (rawPath == null) {
logE("No data available for uri $uri")
Expand Down Expand Up @@ -72,26 +89,19 @@ private class Api29ContentPathResolverImpl(
private data class RawPath(val volumeName: String?, val relativePath: String?)

override fun resolve(uri: Uri): Path? {
val rawPath = contentResolver.useQuery(
uri, arrayOf(
MediaStore.MediaColumns.VOLUME_NAME,
MediaStore.MediaColumns.RELATIVE_PATH
)
) { cursor ->
cursor.moveToFirst()
RawPath(
cursor.getStringOrNull(
cursor.getColumnIndexOrThrow(
MediaStore.MediaColumns.VOLUME_NAME
)
),
cursor.getStringOrNull(
cursor.getColumnIndexOrThrow(
MediaStore.MediaColumns.RELATIVE_PATH
)
)
)
}
val rawPath =
contentResolver.useQuery(
uri,
arrayOf(
MediaStore.MediaColumns.VOLUME_NAME, MediaStore.MediaColumns.RELATIVE_PATH)) {
cursor ->
cursor.moveToFirst()
RawPath(
cursor.getStringOrNull(
cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.VOLUME_NAME)),
cursor.getStringOrNull(
cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.RELATIVE_PATH)))
}

if (rawPath.volumeName == null || rawPath.relativePath == null) {
logE("No data available for uri $uri (raw path obtained: $rawPath)")
Expand All @@ -108,4 +118,4 @@ private class Api29ContentPathResolverImpl(
logE("No volume found for uri $uri")
return null
}
}
}
3 changes: 2 additions & 1 deletion app/src/main/java/org/oxycblt/auxio/music/fs/FsModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ class FsModule {
MediaStoreExtractor.from(context, volumeManager)

@Provides
fun contentPathResolver(@ApplicationContext context: Context, volumeManager: VolumeManager) = ContentPathResolver.from(context, volumeManager)
fun contentPathResolver(@ApplicationContext context: Context, volumeManager: VolumeManager) =
ContentPathResolver.from(context, volumeManager)
}

0 comments on commit e553744

Please sign in to comment.