Skip to content

Commit

Permalink
6.16.4 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
XilinJia committed Dec 21, 2024
1 parent 6cf1c28 commit 4377b71
Show file tree
Hide file tree
Showing 26 changed files with 984 additions and 692 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ While podcast subscriptions' OPML files (from AntennaPod or any other sources) c
* copy the previous directories "Podcini-Prefs" and/or "Podcini-MediaFiles" into the above directory
* no need to copy all three, only the ones you need
* then do the combo import
* There is an option to turn on auto backup in Settings->Import/Export
* if turned on, one needs to specify interval (in hours), a folder, and number of copies to keep
* then Preferences and DB are backed up in sub-folder named "Podcini-AudoBackups-(date)"
* backup time is on the next resume of Podcini after interval hours from last backup time
* to restore, use Combo restore
* Play history/progress can be separately exported/imported as Json files
* Reconsile feature (accessed from Downloads view) is added to ensure downloaded media files are in sync with specs in DB
* Podcasts can be selectively exported from Subscriptions view
Expand Down
16 changes: 8 additions & 8 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ android {
vectorDrawables.useSupportLibrary false
vectorDrawables.generatedDensities = []

versionCode 3020325
versionName "6.16.3"
versionCode 3020326
versionName "6.16.4"

ndkVersion "27.0.12077973"

Expand Down Expand Up @@ -196,18 +196,18 @@ dependencies {
implementation "androidx.work:work-runtime:2.10.0"
implementation "androidx.fragment:fragment-ktx:1.8.5"

implementation "androidx.media3:media3-exoplayer:1.5.0"
implementation "androidx.media3:media3-datasource-okhttp:1.5.0"
implementation "androidx.media3:media3-ui:1.5.0"
implementation "androidx.media3:media3-common:1.5.0"
implementation "androidx.media3:media3-session:1.5.0"
implementation "androidx.media3:media3-exoplayer:1.5.1"
implementation "androidx.media3:media3-datasource-okhttp:1.5.1"
implementation "androidx.media3:media3-ui:1.5.1"
implementation "androidx.media3:media3-common:1.5.1"
implementation "androidx.media3:media3-session:1.5.1"

implementation "com.google.android.material:material:1.12.0"

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"

/** Desugaring for using VistaGuide **/
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs_nio:2.1.3"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs_nio:2.1.4"
implementation "com.github.XilinJia.vistaguide:VistaGuide:lv0.24.2.6"

implementation "com.github.skydoves:balloon:1.6.6"
Expand Down
77 changes: 77 additions & 0 deletions app/src/main/kotlin/ac/mdiq/podcini/preferences/AutoBackup.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ac.mdiq.podcini.preferences

import ac.mdiq.podcini.preferences.UserPreferences.appPrefs
import ac.mdiq.podcini.util.Logd
import ac.mdiq.podcini.util.MiscFormatter.dateStampFilename
import android.app.Activity
import android.net.Uri
import android.util.Log
import androidx.documentfile.provider.DocumentFile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.IOException

fun autoBackup(activity: Activity) {
val TAG = "autoBackup"

val backupDirName = "Podcini-AudoBackups"
val prefsDirName = "Podcini-Prefs"

val isAutoBackup = appPrefs.getBoolean(UserPreferences.Prefs.prefAutoBackup.name, false)
if (!isAutoBackup) return
val uriString = appPrefs.getString(UserPreferences.Prefs.prefAutoBackupFolder.name, "")
if (uriString.isNullOrBlank()) return

Logd("autoBackup", "in autoBackup directory: $uriString")

fun deleteDirectoryAndContents(directory: DocumentFile): Boolean {
if (directory.isDirectory) {
directory.listFiles().forEach { file ->
if (file.isDirectory) deleteDirectoryAndContents(file)
Logd(TAG, "deleting ${file.name}")
file.delete()
}
}
return directory.delete()
}

CoroutineScope(Dispatchers.IO).launch {
val interval = appPrefs.getInt(UserPreferences.Prefs.prefAutoBackupIntervall.name, 24)
var lastBackupTime = appPrefs.getLong(UserPreferences.Prefs.prefAutoBackupTimeStamp.name, 0L)
val curTime = System.currentTimeMillis()
if ((curTime - lastBackupTime) / 1000 / 3600 > interval) {
val uri = Uri.parse(uriString)
val permissions = activity.contentResolver.persistedUriPermissions.find { it.uri == uri }
if (permissions != null && permissions.isReadPermission && permissions.isWritePermission) {
val chosenDir = DocumentFile.fromTreeUri(activity, uri)
if (chosenDir != null) {
val backupDirs = mutableListOf<DocumentFile>()
try {
if (chosenDir.isDirectory) {
chosenDir.listFiles().forEach { file ->
Logd(TAG, "file: $file")
if (file.isDirectory && file.name?.startsWith(backupDirName, ignoreCase = true) == true) backupDirs.add(file)
}
}
Logd(TAG, "backupDirs: ${backupDirs.size}")
val limit = appPrefs.getInt(UserPreferences.Prefs.prefAutoBackupLimit.name, 2)
if (backupDirs.size >= limit) {
backupDirs.sortBy { it.name }
for (i in 0..(backupDirs.size - limit)) deleteDirectoryAndContents(backupDirs[i])
}

val dirName = dateStampFilename("$backupDirName-%s")
val exportSubDir = chosenDir.createDirectory(dirName) ?: throw IOException("Error creating subdirectory $dirName")
val subUri: Uri = exportSubDir.uri
PreferencesTransporter(prefsDirName).exportToDocument(subUri, activity)
val realmFile = exportSubDir.createFile("application/octet-stream", "backup.realm")
if (realmFile != null) DatabaseTransporter().exportToDocument(realmFile.uri, activity)

appPrefs.edit().putLong(UserPreferences.Prefs.prefAutoBackupTimeStamp.name, curTime).apply()
} catch (e: Exception) { Log.e("autoBackup", "Error backing up ${e.message}") }
}
} else Log.e("autoBackup", "Uri permissions are no longer valid")
}
}
}
Loading

0 comments on commit 4377b71

Please sign in to comment.