Skip to content
This repository has been archived by the owner on Aug 27, 2024. It is now read-only.

Commit

Permalink
do not override an existing collection with an empty one - except whe…
Browse files Browse the repository at this point in the history
…n last podcast is deleted
  • Loading branch information
y20k committed Jul 21, 2020
1 parent 1407440 commit 8525442
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 53 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.4"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4"

implementation "com.google.android.material:material:1.2.0-beta01"

Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/y20k/escapepod/Keys.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ object Keys {
const val PREF_ONE_TIME_HOUSEKEEPING_NECESSARY = "ONE_TIME_HOUSEKEEPING_NECESSARY_VERSIONCODE_26" // increment to current app version code to trigger housekeeping that runs only once
const val PREF_THEME_SELECTION: String= "THEME_SELECTION"
const val PREF_LAST_UPDATE_COLLECTION: String = "LAST_UPDATE_COLLECTION"
const val PREF_COLLECTION_SIZE: String = "COLLECTION_SIZE"
const val PREF_COLLECTION_MODIFICATION_DATE: String = "COLLECTION_MODIFICATION_DATE"
const val PREF_CURRENT_MEDIA_ID: String = "CURRENT_MEDIA_ID"
const val PREF_CURRENT_PLAYBACK_STATE: String = "CURRENT_PLAYBACK_STATE"
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/org/y20k/escapepod/PlayerService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,6 @@ class PlayerService(): MediaBrowserServiceCompat(), Player.EventListener, Corout
}
}


override fun onFastForward() {
LogHelper.d(TAG, "Skipping forward")
// update position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class CollectionViewModel(application: Application) : AndroidViewModel(applicati
private var collectionChangedReceiver: BroadcastReceiver
private val backgroundJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + backgroundJob)
//private var collectionDatabase: CollectionDatabase
// private var collectionDatabase: CollectionDatabase


/* Init constructor */
Expand All @@ -56,7 +56,7 @@ class CollectionViewModel(application: Application) : AndroidViewModel(applicati
collectionChangedReceiver = createCollectionChangedReceiver()
LocalBroadcastManager.getInstance(application).registerReceiver(collectionChangedReceiver, IntentFilter(Keys.ACTION_COLLECTION_CHANGED))
// get instance of collection database // todo remove: just a database test
//collectionDatabase = CollectionDatabase.getInstance(application)
// collectionDatabase = CollectionDatabase.getInstance(application)
}


Expand Down Expand Up @@ -98,17 +98,24 @@ class CollectionViewModel(application: Application) : AndroidViewModel(applicati
// update collection view model
collectionLiveData.value = collection
// Todo remove: just a database test
//insertPodcasts(collection)
// insertPodcasts(collection)
}
}

// todo read this :-) https://itnext.io/room-persistence-library-using-mutablelivedata-observable-to-update-the-ui-after-a-database-6836d25e8267

///* Todo remove: just a database test */

/* Todo remove: just a database test */
//private fun insertPodcasts(collection: Collection) {
// GlobalScope.launch {
// collectionDatabase.podcastDao().insertAll(DatabaseHelper.convertToPodcastEntityList(collection))
// //collectionDatabase.clearAllTables()
//
// val result: Pair<List<PodcastEntity>, List<EpisodeEntity>> = DatabaseHelper.convertToPodcastEntityList(collection)
// collectionDatabase.podcastDao().insertAll(result.first)
// collectionDatabase.episodeDao().insertAll(result.second)
//
// LogHelper.e(TAG, "${collectionDatabase.podcastDao().findByName("Subnet").pid}")
// val numberOfEpisodes = collectionDatabase.episodeDao().getSize()
// val numberOfPodcasts = collectionDatabase.podcastDao().getSize()
// }
//}

Expand Down
43 changes: 32 additions & 11 deletions app/src/main/java/org/y20k/escapepod/database/EpisodeDao.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,51 @@
package org.y20k.escapepod.database

import androidx.lifecycle.LiveData
import androidx.room.*

@Dao
interface EpisodeDao {
@Query("SELECT * FROM episode")
fun getAll(): List<EpisodeEntity>
@Query("SELECT COUNT(*) FROM episodes")
fun getSize(): Int

@Query("SELECT * FROM episode WHERE eid IN (:eids)")
@Query("SELECT * FROM episodes")
fun getAll(): LiveData<List<EpisodeEntity>>

@Query("SELECT * FROM episodes WHERE eid IN (:eids)")
fun loadAllByIds(eids: IntArray): List<EpisodeEntity>

@Query("SELECT * FROM episode WHERE episode_title LIKE :title LIMIT 1")
@Query("SELECT * FROM episodes WHERE episode_title LIKE :title LIMIT 1")
fun findByTitle(title: String): EpisodeEntity

@Query("SELECT * FROM episode WHERE episode_guid IS :guid LIMIT 1")
@Query("SELECT * FROM episodes WHERE episode_guid IS :guid LIMIT 1")
fun findByGuid(guid: String): EpisodeEntity

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(episode: EpisodeEntity)
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(episode: EpisodeEntity): Long

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(vararg episodes: EpisodeEntity)
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertAll(episodes: List<EpisodeEntity>): List< Long>

@Update
fun add(episode: EpisodeEntity)
@Update(onConflict = OnConflictStrategy.REPLACE)
fun update(episode: EpisodeEntity)

@Delete
fun delete(episode: EpisodeEntity)

@Transaction
fun upsert(episode: EpisodeEntity) {
val rowId = insert(episode)
if (rowId == -1L) {
update(episode)
}
}

@Transaction
fun upsertAll(episodes: List<EpisodeEntity>) {
val rowIds = insertAll(episodes)
val episodesToUpdate = rowIds.mapIndexedNotNull { index, rowId ->
if (rowId == -1L) null else episodes[index] }
episodesToUpdate.forEach { update(it) }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package org.y20k.escapepod.database

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey

@Entity(tableName = "episode")
@Entity(tableName = "episodes", indices = arrayOf(Index(value = ["episode_guid"], unique = true)))
data class EpisodeEntity (

@PrimaryKey (autoGenerate = true) val eid: Long,
@ColumnInfo (name = "podcast_id") val podcastId: Long,
@ColumnInfo (name = "episode_guid") val guid: String,
@ColumnInfo (name = "episode_title") val title: String,
Expand All @@ -24,4 +24,6 @@ data class EpisodeEntity (
@ColumnInfo (name = "episode_remote_cover_file_location") val remoteCoverFileLocation: String,
@ColumnInfo (name = "episode_remote_audio_file_location") val remoteAudioFileLocation: String

)
) {
@PrimaryKey (autoGenerate = true) var eid: Long = 0L
}
48 changes: 37 additions & 11 deletions app/src/main/java/org/y20k/escapepod/database/PodcastDao.kt
Original file line number Diff line number Diff line change
@@ -1,32 +1,58 @@
package org.y20k.escapepod.database

import androidx.lifecycle.LiveData
import androidx.room.*

@Dao
interface PodcastDao {
@Query("SELECT * FROM podcast")
fun getAll(): List<PodcastEntity>
@Query("SELECT COUNT(*) FROM podcasts")
fun getSize(): Int

@Query("SELECT * FROM podcast WHERE pid IN (:pids)")
@Query("SELECT * FROM podcasts")
fun getAll(): LiveData<List<PodcastEntity>>

@Query("SELECT * FROM podcasts WHERE pid IN (:pids)")
fun loadAllByIds(pids: IntArray): List<PodcastEntity>

@Query("SELECT * FROM podcast WHERE podcast_name LIKE :name LIMIT 1")
@Query("SELECT * FROM podcasts WHERE podcast_name LIKE :name LIMIT 1")
fun findByName(name: String): PodcastEntity

@Insert
fun insert(podcast: PodcastEntity)
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(podcast: PodcastEntity): Long

@Insert
fun insertAll(podcasts: List<PodcastEntity>)
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertAll(podcasts: List<PodcastEntity>): List<Long>

@Update
fun add(podcast: PodcastEntity)
@Update(onConflict = OnConflictStrategy.REPLACE)
fun update(podcast: PodcastEntity)

@Delete
fun delete(user: PodcastEntity)

@Transaction
@Query("SELECT * FROM podcast")
fun upsert(podcast: PodcastEntity) {
val rowId = insert(podcast)
if (rowId == -1L) {
update(podcast)
}
}

@Transaction
fun upsertAll(podcasts: List<PodcastEntity>) {
val rowIds = insertAll(podcasts)
val podcastsToUpdate = rowIds.mapIndexedNotNull { index, rowId ->
if (rowId == -1L) null else podcasts[index] }
podcastsToUpdate.forEach { update(it) }
}


/**
* This query will tell Room to query both the Podcast and Episode tables and handle
* the object mapping.
*/
@Transaction
//@Query("SELECT * FROM episodes WHERE podcast_id IN (SELECT DISTINCT(pid) FROM podcasts)")
@Query("SELECT * FROM podcasts")
fun getPodcastsWithEpisodes(): List<PodcastWithEpisodesEntity>

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package org.y20k.escapepod.database

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey


@Entity(tableName = "podcast")
@Entity(tableName = "podcasts", indices = arrayOf(Index(value = ["podcast_remote_podcast_feed_location"], unique = true)))
data class PodcastEntity(

@ColumnInfo (name = "podcast_name") val name: String,
Expand Down
33 changes: 29 additions & 4 deletions app/src/main/java/org/y20k/escapepod/helpers/DatabaseHelper.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package org.y20k.escapepod.helpers

import org.y20k.escapepod.core.Collection
import org.y20k.escapepod.database.EpisodeEntity
import org.y20k.escapepod.database.PodcastEntity

object DatabaseHelper {

fun convertToPodcastEntityList(collection: Collection): List<PodcastEntity> {
val list: MutableList<PodcastEntity> = mutableListOf()
fun convertToPodcastEntityList(collection: Collection): Pair<List<PodcastEntity>, List<EpisodeEntity>> {
val podcastList: MutableList<PodcastEntity> = mutableListOf()
val episodeList: MutableList<EpisodeEntity> = mutableListOf()
collection.podcasts.forEach { podcast ->
val podcastEntity: PodcastEntity = PodcastEntity(
name = podcast.name,
Expand All @@ -18,9 +20,32 @@ object DatabaseHelper {
remoteImageFileLocation = podcast.remoteImageFileLocation,
remotePodcastFeedLocation = podcast.remotePodcastFeedLocation
)
list.add(podcastEntity)
podcastList.add(podcastEntity)

podcast.episodes.forEach { episode ->
val episodeEntity: EpisodeEntity = EpisodeEntity(
podcastId = podcastEntity.pid,
guid = episode.guid,
title = episode.title,
description = episode.description,
audio = episode.audio,
cover = episode.cover,
smallCover = episode.smallCover,
publicationDate = episode.publicationDate.time,
playbackState = episode.playbackState,
playbackPosition = episode.playbackPosition,
duration = episode.duration,
manuallyDownloaded = episode.manuallyDownloaded,
manuallyDeleted = episode.manuallyDeleted,
remoteCoverFileLocation = episode.remoteCoverFileLocation,
remoteAudioFileLocation = episode.remoteAudioFileLocation
)
episodeList.add(episodeEntity)
}


}
return list
return Pair(podcastList, episodeList)
}

}
33 changes: 19 additions & 14 deletions app/src/main/java/org/y20k/escapepod/helpers/FileHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -181,23 +181,28 @@ object FileHelper {
/* Saves podcast collection as JSON text file */
fun saveCollection(context: Context, collection: Collection, lastSave: Date) {
LogHelper.v(TAG, "Saving collection - Thread: ${Thread.currentThread().name}")
// convert to JSON
val gson: Gson = getCustomGson()
var json: String = String()
try {
json = gson.toJson(collection)
} catch (e: Exception) {
e.printStackTrace()
}
if (json.isNotBlank()) {
// save modification date
PreferencesHelper.saveCollectionModificationDate(context, lastSave)
// write text file
writeTextFile(context, json, Keys.FOLDER_COLLECTION, Keys.COLLECTION_FILE)
val collectionSize: Int = collection.podcasts.size
// do not override an existing collection with an empty one - except when last podcast is deleted
if (collectionSize > 0 || PreferencesHelper.loadCollectionSize(context) == 1) {
// convert to JSON
val gson: Gson = getCustomGson()
var json: String = String()
try {
json = gson.toJson(collection)
} catch (e: Exception) {
e.printStackTrace()
}
if (json.isNotBlank()) {
// save modification date
PreferencesHelper.saveCollectionModificationDate(context, lastSave)
// write text file
writeTextFile(context, json, Keys.FOLDER_COLLECTION, Keys.COLLECTION_FILE)
}
} else {
LogHelper.w(TAG, "Not saving collection. Collection is empty.")
}
}


/* Reads podcast collection from storage using GSON */
fun readCollection(context: Context): Collection {
LogHelper.v(TAG, "Reading collection - Thread: ${Thread.currentThread().name}")
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/java/org/y20k/escapepod/helpers/PreferencesHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ object PreferencesHelper {
}


/* Loads size of collection from shared preferences */
fun loadCollectionSize(context: Context): Int {
val settings = PreferenceManager.getDefaultSharedPreferences(context)
return settings.getInt(Keys.PREF_COLLECTION_SIZE, -1)
}


/* Saves site of collection to shared preferences */
fun saveCollectionSize(context: Context, size: Int) {
val settings = PreferenceManager.getDefaultSharedPreferences(context)
val editor = settings.edit()
editor.putInt(Keys.PREF_COLLECTION_SIZE, size)
editor.apply()
}


/* Loads date of last save operation from shared preferences */
fun loadCollectionModificationDate(context: Context): Date {
val settings = PreferenceManager.getDefaultSharedPreferences(context)
Expand Down

0 comments on commit 8525442

Please sign in to comment.