Skip to content

Commit

Permalink
6.1.1 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
XilinJia committed Jul 19, 2024
1 parent 76e350f commit d47bdab
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 34 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ android {
buildConfig true
}
defaultConfig {
versionCode 3020214
versionName "6.1.0"
versionCode 3020215
versionName "6.1.1"

applicationId "ac.mdiq.podcini.R"
def commit = ""
Expand Down
27 changes: 18 additions & 9 deletions app/src/main/kotlin/ac/mdiq/podcini/preferences/OpmlBackupAgent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,16 @@ class OpmlBackupAgent : BackupAgentHelper() {
IOUtils.closeQuietly(writer)
}
}
@OptIn(UnstableApi::class) override fun restoreEntity(data: BackupDataInputStream) {
@OptIn(UnstableApi::class)
override fun restoreEntity(data: BackupDataInputStream) {
Logd(TAG, "Backup restore")
if (OPML_ENTITY_KEY != data.key) {
Logd(TAG, "Unknown entity key: " + data.key)
return
}
var digester: MessageDigest? = null
var reader: Reader
var linesRead = 0
try {
digester = MessageDigest.getInstance("MD5")
reader = InputStreamReader(DigestInputStream(data, digester), Charset.forName("UTF-8"))
Expand All @@ -112,25 +114,30 @@ class OpmlBackupAgent : BackupAgentHelper() {
try {
mChecksum = digester?.digest() ?: byteArrayOf()
BufferedReader(reader).use { bufferedReader ->
val tempFile = File.createTempFile("opml_restored", ".tmp", mContext.filesDir)
val tempFile = File(mContext.filesDir, "opml_restored.txt")
// val tempFile = File.createTempFile("opml_restored", ".tmp", mContext.filesDir)
FileWriter(tempFile).use { fileWriter ->
while (true) {
val line = bufferedReader.readLine() ?: break
Logd(TAG, "restoreEntity: $linesRead $line")
linesRead++
fileWriter.write(line)
fileWriter.write(System.lineSeparator()) // Write a newline character
}
}
}
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext)
with(sharedPreferences.edit()) {
putBoolean(UserPreferences.Prefs.prefOPMLRestore.name, true)
apply()
}
} catch (e: XmlPullParserException) {
Log.e(TAG, "Error while parsing the OPML file", e)
} catch (e: IOException) {
Log.e(TAG, "Failed to restore OPML backup", e)
} finally {
if (linesRead > 0) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext)
with(sharedPreferences.edit()) {
putBoolean(UserPreferences.Prefs.prefOPMLRestore.name, true)
apply()
}
}
IOUtils.closeQuietly(reader)
}
}
Expand Down Expand Up @@ -166,11 +173,12 @@ class OpmlBackupAgent : BackupAgentHelper() {
private const val OPML_BACKUP_KEY = "opml"

val isOPMLRestared: Boolean
get() = appPrefs.getBoolean(UserPreferences.Prefs.prefOPMLRestore.name, true)
get() = appPrefs.getBoolean(UserPreferences.Prefs.prefOPMLRestore.name, false)

fun performRestore(context: Context) {
Logd(TAG, "performRestore")
val tempFile = File.createTempFile("opml_restored", ".tmp", context.filesDir)
val tempFile = File(context.filesDir, "opml_restored.txt")
// val tempFile = File.createTempFile("opml_restored", ".tmp", context.filesDir)
if (tempFile.exists()) {
val reader = FileReader(tempFile)
val opmlElements = OpmlReader().readDocument(reader)
Expand All @@ -179,6 +187,7 @@ class OpmlBackupAgent : BackupAgentHelper() {
feed.episodes.clear()
updateFeed(context, feed, false)
}
Toast.makeText(context, "${opmlElements.size} feeds were restored", Toast.LENGTH_SHORT).show()
runOnce(context)
} else {
Toast.makeText(context, "No backup data found", Toast.LENGTH_SHORT).show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ac.mdiq.podcini.storage.database.Queues.getInQueueEpisodeIds
import ac.mdiq.podcini.storage.model.Episode
import ac.mdiq.podcini.storage.model.EpisodeFilter
import ac.mdiq.podcini.storage.model.EpisodeSortOrder
import ac.mdiq.podcini.util.Logd
import android.content.Context
import android.util.Log
import androidx.annotation.OptIn
Expand Down Expand Up @@ -68,7 +69,8 @@ object AutoCleanups {
override fun getReclaimableItems(): Int {
return candidates.size
}
@OptIn(UnstableApi::class) public override fun performCleanup(context: Context, numToRemove: Int): Int {
@OptIn(UnstableApi::class)
public override fun performCleanup(context: Context, numToRemove: Int): Int {
var candidates = candidates
// in the absence of better data, we'll sort by item publication date
candidates = candidates.sortedWith { lhs: Episode, rhs: Episode ->
Expand Down Expand Up @@ -250,8 +252,12 @@ object AutoCleanups {
* @return The number of episodes that were deleted.
*/
protected abstract fun performCleanup(context: Context, numToRemove: Int): Int

// only used in tests
fun performCleanup(context: Context): Int {
return performCleanup(context, getDefaultCleanupParameter())
val numToRemove = getDefaultCleanupParameter()
if (numToRemove <= 0) return 0
return performCleanup(context, numToRemove)
}
/**
* Returns a parameter for performCleanup. The implementation of this interface should decide how much
Expand All @@ -266,7 +272,10 @@ object AutoCleanups {
* @return The number of epiosdes that were deleted
*/
fun makeRoomForEpisodes(context: Context, amountOfRoomNeeded: Int): Int {
return performCleanup(context, getNumEpisodesToCleanup(amountOfRoomNeeded))
val numToRemove = getNumEpisodesToCleanup(amountOfRoomNeeded)
Logd("EpisodeCleanupAlgorithm", "makeRoomForEpisodes: $numToRemove")
if (numToRemove <= 0) return 0
return performCleanup(context, numToRemove)
}
/**
* @return the number of episodes/items that *could* be cleaned up, if needed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,17 @@ import ac.mdiq.podcini.preferences.UserPreferences.isEnableAutodownload
import ac.mdiq.podcini.preferences.UserPreferences.isEnableAutodownloadOnBattery
import ac.mdiq.podcini.storage.database.Episodes.getEpisodes
import ac.mdiq.podcini.storage.database.Episodes.getEpisodesCount
import ac.mdiq.podcini.storage.database.Episodes.setPlayState
import ac.mdiq.podcini.storage.database.Feeds.getFeedList
import ac.mdiq.podcini.storage.database.RealmDB.realm
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk
import ac.mdiq.podcini.storage.model.*
import ac.mdiq.podcini.storage.utils.EpisodesPermutors.getPermutor
import ac.mdiq.podcini.util.Logd
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import androidx.media3.common.util.UnstableApi
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
Expand Down Expand Up @@ -149,37 +146,40 @@ object AutoDownloads {
if (networkShouldAutoDl && powerShouldAutoDl) {
Logd(Companion.TAG, "autoDownloadEpisodeMedia Performing auto-dl of undownloaded episodes")
val candidates: MutableSet<Episode> = mutableSetOf()
val queueItems = curQueue.episodes.filter { it.media?.downloaded != true }
val queueItems = realm.query(Episode::class).query("id IN $0 AND media.downloaded == false", curQueue.episodeIds).find()
Logd(TAG, "autoDownloadEpisodeMedia add from queue: ${queueItems.size}")
if (queueItems.isNotEmpty()) candidates.addAll(queueItems)
val feeds = feeds ?: getFeedList()
feeds.forEach { f ->
if (f.preferences?.autoDownload == true && !f.isLocalFeed) {
var episodes = mutableListOf<Episode>()
val downloadedCount = getEpisodesCount(EpisodeFilter(EpisodeFilter.States.downloaded.name), f.id)
val toDLCount = (f.preferences?.autoDLMaxEpisodes?:0) - downloadedCount
if (toDLCount > 0) {
val allowedDLCount = (f.preferences?.autoDLMaxEpisodes?:0) - downloadedCount
if (allowedDLCount > 0) {
var queryString = "feedId == ${f.id} AND isAutoDownloadEnabled == true AND media != nil AND media.downloaded == false"
when (f.preferences?.autoDLPolicy) {
FeedPreferences.AutoDLPolicy.ONLY_NEW -> {
queryString += " AND playState == -1 SORT(pubDate DESC) LIMIT(${3*toDLCount})"
queryString += " AND playState == -1 SORT(pubDate DESC) LIMIT(${3*allowedDLCount})"
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
}
FeedPreferences.AutoDLPolicy.NEWER -> {
queryString += " AND playState != 1 SORT(pubDate DESC) LIMIT(${3*toDLCount})"
queryString += " AND playState != 1 SORT(pubDate DESC) LIMIT(${3*allowedDLCount})"
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
}
FeedPreferences.AutoDLPolicy.OLDER -> {
queryString += " AND playState != 1 SORT(pubDate ASC) LIMIT(${3*toDLCount})"
queryString += " AND playState != 1 SORT(pubDate ASC) LIMIT(${3*allowedDLCount})"
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
}
else -> {}
}
if (episodes.isNotEmpty()) {
var count = 0
for (e in episodes) {
if (isCurMedia(e.media)) continue
if (f.preferences?.autoDownloadFilter?.shouldAutoDownload(e) == true) {
Logd(TAG, "autoDownloadEpisodeMedia add to cadidates: ${e.title} ${e.isDownloaded}")
candidates.add(e)
if (++count >= toDLCount) break
if (++count >= allowedDLCount) break
} else upsertBlk(e) { it.setPlayed(true)}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class AddFeedFragment : Fragment() {
.setPositiveButton("Yes") { dialog, _ ->
performRestore(requireContext())
dialog.dismiss()
parentFragmentManager.popBackStack()
}
.setNegativeButton("No") { dialog, _ ->
dialog.dismiss()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,17 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
(activity as MainActivity).setPlayerVisible(true)
}

private fun onPlaybackPositionEvent(event: FlowEvent.PlaybackPositionEvent) {
// Logd(TAG, "onPlayEvent ${event.episode.title}")
val media = event.media
if (currentMedia?.getIdentifier() == null || media?.getIdentifier() != currentMedia?.getIdentifier()) {
currentMedia = media
playerDetailsFragment?.setItem(curEpisode!!)
}
playerUI?.onPositionUpdate(event)
if (!isCollapsed) playerDetailsFragment?.onPlaybackPositionEvent(event)
}

private var eventSink: Job? = null
private fun cancelFlowEvents() {
Logd(TAG, "cancelFlowEvents")
Expand All @@ -346,10 +357,7 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
is FlowEvent.FavoritesEvent -> onFavoriteEvent(event)
is FlowEvent.PlayerErrorEvent -> MediaPlayerErrorDialog.show(activity as Activity, event)
is FlowEvent.SleepTimerUpdatedEvent -> if (event.isCancelled || event.wasJustEnabled()) loadMediaInfo(false)
is FlowEvent.PlaybackPositionEvent -> {
playerUI?.onPositionUpdate(event)
if (!isCollapsed) playerDetailsFragment?.onPlaybackPositionEvent(event)
}
is FlowEvent.PlaybackPositionEvent -> onPlaybackPositionEvent(event)
is FlowEvent.SpeedChangedEvent -> playerUI?.updatePlaybackSpeedButton(event)
else -> {}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ac.mdiq.podcini.databinding.BaseEpisodesListFragmentBinding
import ac.mdiq.podcini.databinding.MultiSelectSpeedDialBinding
import ac.mdiq.podcini.net.feed.FeedUpdateManager
import ac.mdiq.podcini.playback.base.InTheatre.isCurMedia
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
import ac.mdiq.podcini.storage.model.Episode
import ac.mdiq.podcini.storage.model.EpisodeMedia
import ac.mdiq.podcini.storage.model.EpisodeFilter
Expand Down Expand Up @@ -343,7 +344,8 @@ import kotlinx.coroutines.flow.collectLatest
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)

if (pos >= 0) {
episodes[pos] = item
episodes[pos] = unmanaged(episodes[pos])
episodes[pos].media?.position = event.media.position
curIndex = pos
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ac.mdiq.podcini.preferences.UserPreferences
import ac.mdiq.podcini.preferences.UserPreferences.appPrefs
import ac.mdiq.podcini.storage.database.Episodes.getEpisodes
import ac.mdiq.podcini.storage.database.RealmDB.realm
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
import ac.mdiq.podcini.storage.model.Episode
import ac.mdiq.podcini.storage.model.EpisodeFilter
import ac.mdiq.podcini.storage.model.EpisodeMedia
Expand Down Expand Up @@ -310,7 +311,8 @@ import java.util.*
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)

if (pos >= 0) {
episodes[pos] = item
episodes[pos] = unmanaged(episodes[pos])
episodes[pos].media?.position = event.media.position
curIndex = pos
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ import java.util.concurrent.Semaphore
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)

if (pos >= 0) {
episodes[pos] = item
episodes[pos] = unmanaged(episodes[pos])
episodes[pos].media?.position = event.media.position
curIndex = pos
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ac.mdiq.podcini.storage.database.Queues.moveInQueueSync
import ac.mdiq.podcini.storage.database.Queues.queueKeepSortedOrder
import ac.mdiq.podcini.storage.database.RealmDB.realm
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
import ac.mdiq.podcini.storage.database.RealmDB.upsert
import ac.mdiq.podcini.storage.model.Episode
import ac.mdiq.podcini.storage.model.EpisodeFilter
Expand Down Expand Up @@ -337,7 +338,8 @@ import java.util.*
curIndex else EpisodeUtil.indexOfItemWithId(queueItems, item.id)

if (pos >= 0) {
queueItems[pos] = item
queueItems[pos] = unmanaged(queueItems[pos])
queueItems[pos].media?.position = event.media.position
curIndex = pos
adapter?.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ac.mdiq.podcini.databinding.SearchFragmentBinding
import ac.mdiq.podcini.net.feed.discovery.CombinedSearcher
import ac.mdiq.podcini.playback.base.InTheatre.isCurMedia
import ac.mdiq.podcini.storage.database.RealmDB.realm
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
import ac.mdiq.podcini.storage.model.Episode
import ac.mdiq.podcini.storage.model.EpisodeMedia
import ac.mdiq.podcini.storage.model.Feed
Expand Down Expand Up @@ -300,7 +301,8 @@ import java.lang.ref.WeakReference
curIndex else EpisodeUtil.indexOfItemWithId(results, item.id)

if (pos >= 0) {
results[pos] = item
results[pos] = unmanaged(results[pos])
results[pos].media?.position = event.media.position
curIndex = pos
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
}
Expand Down
8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 6.1.1

* fixed player UI not updating on change of episode
* fixed the mal-function of restoring previously backed-up OPML
* reduced reactions to PlaybackPositionEvent
* tuned AutoCleanup a bit
* tuned and fixed some some issues in audo-downloaded

# 6.1.0

* in FeedEpisode view fixed filtering after an episode's play state is changed
Expand Down
2 changes: 1 addition & 1 deletion fastlane/metadata/android/en-US/changelogs/3020214.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

Version 6.0.14 brings several changes:
Version 6.1.0 brings several changes:

* in FeedEpisode view fixed filtering after an episode's play state is changed
* fixed refreshing a feed causes duplicate episodes in FeedEpisodes view
Expand Down
8 changes: 8 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/3020215.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

Version 6.1.1 brings several changes:

* fixed player UI not updating on change of episode
* fixed the mal-function of restoring previously backed-up OPML
* reduced reactions to PlaybackPositionEvent
* tuned AutoCleanup a bit
* tuned and fixed some some issues in audo-downloaded

0 comments on commit d47bdab

Please sign in to comment.