music: cleanup old cover revisions
This commit is contained in:
parent
8409a93c4e
commit
0cfd6ddb67
3 changed files with 26 additions and 23 deletions
|
@ -25,6 +25,7 @@ import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.selects.select
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.yield
|
import kotlinx.coroutines.yield
|
||||||
import org.oxycblt.auxio.music.MusicRepository.IndexingWorker
|
import org.oxycblt.auxio.music.MusicRepository.IndexingWorker
|
||||||
|
@ -361,25 +362,18 @@ constructor(
|
||||||
}
|
}
|
||||||
val locations = musicSettings.musicLocations
|
val locations = musicSettings.musicLocations
|
||||||
|
|
||||||
val revision: UUID
|
val currentRevision = musicSettings.revision
|
||||||
val storage: Storage
|
val newRevision = currentRevision?.takeIf { withCache } ?: UUID.randomUUID()
|
||||||
if (withCache) {
|
val cache = if (withCache) cache else WriteOnlyCache(cache)
|
||||||
revision = musicSettings.revision
|
val covers = MutableRevisionedStoredCovers(context, newRevision)
|
||||||
storage =
|
val storage = Storage(cache, covers, storedPlaylists)
|
||||||
Storage(cache, MutableRevisionedStoredCovers(context, revision), storedPlaylists)
|
|
||||||
} else {
|
|
||||||
revision = UUID.randomUUID()
|
|
||||||
storage =
|
|
||||||
Storage(
|
|
||||||
WriteOnlyCache(cache),
|
|
||||||
MutableRevisionedStoredCovers(context, revision),
|
|
||||||
storedPlaylists)
|
|
||||||
}
|
|
||||||
|
|
||||||
val interpretation = Interpretation(nameFactory, separators)
|
val interpretation = Interpretation(nameFactory, separators)
|
||||||
|
|
||||||
val newLibrary =
|
val newLibrary =
|
||||||
Musikr.new(context, storage, interpretation).run(locations, ::emitIndexingProgress)
|
Musikr.new(context, storage, interpretation).run(locations, ::emitIndexingProgress)
|
||||||
|
// Music loading completed, update the revision right now so we re-use this work
|
||||||
|
// later.
|
||||||
|
musicSettings.revision = newRevision
|
||||||
|
|
||||||
emitIndexingCompletion(null)
|
emitIndexingCompletion(null)
|
||||||
|
|
||||||
|
@ -415,8 +409,9 @@ constructor(
|
||||||
dispatchLibraryChange(deviceLibraryChanged, userLibraryChanged)
|
dispatchLibraryChange(deviceLibraryChanged, userLibraryChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quietly update the revision if needed (this way we don't disrupt any new loads)
|
// Old cover revisions may be lying around, even during a normal refresh due
|
||||||
musicSettings.revision = revision
|
// to realyl lucky cancellations. Clean those up.
|
||||||
|
RevisionedStoredCovers.cleanup(context, newRevision)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun emitIndexingProgress(progress: IndexingProgress) {
|
private suspend fun emitIndexingProgress(progress: IndexingProgress) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ import timber.log.Timber as L
|
||||||
*/
|
*/
|
||||||
interface MusicSettings : Settings<MusicSettings.Listener> {
|
interface MusicSettings : Settings<MusicSettings.Listener> {
|
||||||
/** The current library revision. */
|
/** The current library revision. */
|
||||||
var revision: UUID
|
var revision: UUID?
|
||||||
/** The locations of music to load. */
|
/** The locations of music to load. */
|
||||||
var musicLocations: List<MusicLocation>
|
var musicLocations: List<MusicLocation>
|
||||||
/** Whether to exclude non-music audio files from the music library. */
|
/** Whether to exclude non-music audio files from the music library. */
|
||||||
|
@ -58,11 +58,9 @@ interface MusicSettings : Settings<MusicSettings.Listener> {
|
||||||
class MusicSettingsImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
class MusicSettingsImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
||||||
Settings.Impl<MusicSettings.Listener>(context), MusicSettings {
|
Settings.Impl<MusicSettings.Listener>(context), MusicSettings {
|
||||||
|
|
||||||
override var revision: UUID
|
override var revision: UUID?
|
||||||
get() =
|
get() =
|
||||||
UUID.fromString(
|
sharedPreferences.getString(getString(R.string.set_key_library_revision), null)?.let(UUID::fromString)
|
||||||
sharedPreferences.getString(getString(R.string.set_key_library_revision), null)
|
|
||||||
?: UUID.randomUUID().toString())
|
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPreferences.edit {
|
sharedPreferences.edit {
|
||||||
putString(getString(R.string.set_key_library_revision), value.toString())
|
putString(getString(R.string.set_key_library_revision), value.toString())
|
||||||
|
|
|
@ -15,16 +15,19 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music
|
package org.oxycblt.auxio.music
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
import org.oxycblt.musikr.cover.Cover
|
import org.oxycblt.musikr.cover.Cover
|
||||||
import org.oxycblt.musikr.cover.CoverFormat
|
import org.oxycblt.musikr.cover.CoverFormat
|
||||||
import org.oxycblt.musikr.cover.MutableStoredCovers
|
import org.oxycblt.musikr.cover.MutableStoredCovers
|
||||||
import org.oxycblt.musikr.cover.StoredCovers
|
import org.oxycblt.musikr.cover.StoredCovers
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
open class RevisionedStoredCovers(private val context: Context, private val revision: UUID?) :
|
open class RevisionedStoredCovers(private val context: Context, private val revision: UUID?) :
|
||||||
StoredCovers {
|
StoredCovers {
|
||||||
|
@ -48,6 +51,13 @@ open class RevisionedStoredCovers(private val context: Context, private val revi
|
||||||
return storedCovers.obtain(coverId)?.let { RevisionedCover(coverRevision, it) }
|
return storedCovers.obtain(coverId)?.let { RevisionedCover(coverRevision, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
suspend fun cleanup(context: Context, exclude: UUID) = withContext(Dispatchers.IO) {
|
||||||
|
context.filesDir.listFiles { file -> file.name.startsWith("covers_") && file.name != "covers_$exclude" }
|
||||||
|
?.forEach { it.deleteRecursively() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MutableRevisionedStoredCovers(context: Context, private val revision: UUID) :
|
class MutableRevisionedStoredCovers(context: Context, private val revision: UUID) :
|
||||||
|
|
Loading…
Reference in a new issue