From b06e6cd831ed8598576726f7db8c02dd7dcb31e5 Mon Sep 17 00:00:00 2001 From: atbest Date: Sun, 26 May 2019 00:41:22 -0400 Subject: [PATCH] Created backup and restore objects --- .../java/io/legado/app/help/storage/Backup.kt | 12 ++ .../io/legado/app/help/storage/Restore.kt | 121 ++++++++++++++++ .../app/lib/theme/ThemeStorePrefKeys.java | 2 +- .../io/legado/app/ui/main/MainActivity.kt | 133 ++---------------- .../main/res/menu/activity_main_drawer.xml | 2 +- 5 files changed, 146 insertions(+), 124 deletions(-) create mode 100644 app/src/main/java/io/legado/app/help/storage/Backup.kt create mode 100644 app/src/main/java/io/legado/app/help/storage/Restore.kt diff --git a/app/src/main/java/io/legado/app/help/storage/Backup.kt b/app/src/main/java/io/legado/app/help/storage/Backup.kt new file mode 100644 index 000000000..0f55ac786 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/storage/Backup.kt @@ -0,0 +1,12 @@ +package io.legado.app.help.storage + +object Backup { + + fun backup() { + + } + + fun autoBackup() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt new file mode 100644 index 000000000..aafb71f5c --- /dev/null +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -0,0 +1,121 @@ +package io.legado.app.help.storage + +import android.content.Context +import android.util.Log +import com.jayway.jsonpath.Configuration +import com.jayway.jsonpath.JsonPath +import com.jayway.jsonpath.Option +import io.legado.app.App +import io.legado.app.constant.AppConst +import io.legado.app.data.entities.Book +import io.legado.app.data.entities.ReplaceRule +import io.legado.app.utils.* +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.toast +import org.jetbrains.anko.uiThread +import java.io.File + +object Restore { + + fun restore() { + + } + + fun importFromGithub() { + + } + + fun importYueDuData(context: Context) { + val yuedu = File(getSdPath(), "YueDu") + val jsonPath = JsonPath.using( + Configuration.builder() + .options(Option.SUPPRESS_EXCEPTIONS) + .build() + ) + + // 导入书架 + val shelfFile = File(yuedu, "myBookShelf.json") + val books = mutableListOf() + if (shelfFile.exists()) try { + doAsync { + val items: List> = jsonPath.parse(shelfFile.readText()).read("$") + val existingBooks = App.db.bookDao().allBookUrls.toSet() + for (item in items) { + val jsonItem = jsonPath.parse(item) + val book = Book() + book.descUrl = jsonItem.readString("$.noteUrl") ?: "" + if (book.descUrl.isBlank()) continue + book.name = jsonItem.readString("$.bookInfoBean.name") + if (book.descUrl in existingBooks) { + Log.d(AppConst.APP_TAG, "Found existing book: ${book.name}") + continue + } + book.author = jsonItem.readString("$.bookInfoBean.author") + book.type = if (jsonItem.readString("$.bookInfoBean.bookSourceType") == "AUDIO") 1 else 0 + book.tocUrl = jsonItem.readString("$.bookInfoBean.chapterUrl") ?: book.descUrl + book.coverUrl = jsonItem.readString("$.bookInfoBean.coverUrl") + book.customCoverUrl = jsonItem.readString("$.customCoverPath") + book.lastCheckTime = jsonItem.readLong("$.bookInfoBean.finalRefreshData") ?: 0 + book.canUpdate = jsonItem.readBool("$.allowUpdate") == true + book.totalChapterNum = jsonItem.readInt("$.chapterListSize") ?: 0 + book.durChapterIndex = jsonItem.readInt("$.durChapter") ?: 0 + book.durChapterTitle = jsonItem.readString("$.durChapterName") + book.durChapterPos = jsonItem.readInt("$.durChapterPage") ?: 0 + book.durChapterTime = jsonItem.readLong("$.finalDate") ?: 0 + book.group = jsonItem.readInt("$.group") ?: 0 + // book. = jsonItem.readString("$.hasUpdate") + // book. = jsonItem.readString("$.isLoading") + book.latestChapterTitle = jsonItem.readString("$.lastChapterName") + book.lastCheckCount = jsonItem.readInt("$.newChapters") ?: 0 + book.order = jsonItem.readInt("$.serialNumber") ?: 0 + book.useReplaceRule = jsonItem.readBool("$.useReplaceRule") == true + book.variable = jsonItem.readString("$.variable") + books.add(book) + Log.d(AppConst.APP_TAG, "Added ${book.name}") + } + App.db.bookDao().insert(*books.toTypedArray()) + val count = books.size + + uiThread { + context.toast(if (count > 0) "成功地导入 $count 本新书和音频" else "没有发现新书或音频") + } + + } + + } catch (e: Exception) { + Log.e(AppConst.APP_TAG, "Failed to import book shelf.", e) + context.toast("Unable to import books:\n${e.localizedMessage}") + } + + // Replace rules + val ruleFile = File(yuedu, "myBookReplaceRule.json") + val replaceRules = mutableListOf() + if (ruleFile.exists()) try { + doAsync { + val items: List> = jsonPath.parse(ruleFile.readText()).read("$") + val existingRules = App.db.replaceRuleDao().all.map { it.pattern }.toSet() + for (item in items) { + val jsonItem = jsonPath.parse(item) + val rule = ReplaceRule() + rule.pattern = jsonItem.readString("$.regex") + if (rule.pattern.isNullOrEmpty() || rule.pattern in existingRules) continue + rule.name = jsonItem.readString("$.replaceSummary") + rule.replacement = jsonItem.readString("$.replacement") + rule.isRegex = jsonItem.readBool("$.isRegex") == true + rule.scope = jsonItem.readString("$.useTo") + rule.isEnabled = jsonItem.readBool("$.enable") == true + rule.order = jsonItem.readInt("$.serialNumber") ?: 0 + replaceRules.add(rule) + } + App.db.replaceRuleDao().insert(*replaceRules.toTypedArray()) + val count = replaceRules.size + uiThread { + context.toast(if (count > 0) "成功地导入 $count 条净化替换规则" else "没有发现新的净化替换规则") + } + } + + } catch (e: Exception) { + Log.e(AppConst.APP_TAG, e.localizedMessage) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.java b/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.java index 9a8286f9e..dc09388cc 100644 --- a/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.java +++ b/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.java @@ -5,7 +5,7 @@ package io.legado.app.lib.theme; */ interface ThemeStorePrefKeys { - String CONFIG_PREFS_KEY_DEFAULT = "[[kabouzeid_app-theme-helper]]"; + String CONFIG_PREFS_KEY_DEFAULT = "app_themes"; String IS_CONFIGURED_KEY = "is_configured"; String IS_CONFIGURED_VERSION_KEY = "is_configured_version"; String VALUES_CHANGED = "values_changed"; diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 46cb0096b..8e9de7e29 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -2,34 +2,24 @@ package io.legado.app.ui.main import android.content.Intent import android.os.Bundle -import android.util.Log import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.ActionBarDrawerToggle import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import com.google.android.material.navigation.NavigationView -import com.jayway.jsonpath.Configuration -import com.jayway.jsonpath.JsonPath -import com.jayway.jsonpath.Option -import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseActivity -import io.legado.app.constant.AppConst.APP_TAG -import io.legado.app.data.entities.Book -import io.legado.app.data.entities.ReplaceRule import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.PermissionsCompat +import io.legado.app.help.storage.Backup +import io.legado.app.help.storage.Restore import io.legado.app.ui.replacerule.ReplaceRuleActivity import io.legado.app.ui.search.SearchActivity import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.app_bar_main.* -import org.jetbrains.anko.doAsync import org.jetbrains.anko.startActivity -import org.jetbrains.anko.toast -import org.jetbrains.anko.uiThread -import java.io.File class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener { override val viewModel: MainViewModel @@ -74,19 +64,10 @@ class MainActivity : BaseActivity(), NavigationV override fun onNavigationItemSelected(item: MenuItem): Boolean { // Handle navigation view item clicks here. when (item.itemId) { - R.id.nav_backup -> { - // Handle the camera action - } - R.id.nav_import -> { - - } - R.id.nav_import_old -> PermissionsCompat.Builder(this) - .addPermissions(*Permissions.Group.STORAGE) - .rationale(R.string.tip_perm_request_storage) - .onGranted { importYueDu() }.request() - R.id.nav_import_github -> { - - } + R.id.nav_backup -> Backup.backup() + R.id.nav_restore -> Restore.restore() + R.id.nav_import_old -> importYueDu() + R.id.nav_import_github -> Restore.importFromGithub() R.id.nav_replace_rule -> startActivity() R.id.nav_send -> { @@ -97,103 +78,11 @@ class MainActivity : BaseActivity(), NavigationV return true } - /* - * import from YueDu backup data - * */ - fun importYueDu() { - val yuedu = File(getSdPath(), "YueDu") - val jsonPath = JsonPath.using( - Configuration.builder() - .options(Option.SUPPRESS_EXCEPTIONS) - .build() - ) - - // 导入书架 - val shelfFile = File(yuedu, "myBookShelf.json") - val books = mutableListOf() - if (shelfFile.exists()) try { - doAsync { - val items: List> = jsonPath.parse(shelfFile.readText()).read("$") - val existingBooks = App.db.bookDao().allBookUrls.toSet() - for (item in items) { - val jsonItem = jsonPath.parse(item) - val book = Book() - book.descUrl = jsonItem.readString("$.noteUrl") ?: "" - if (book.descUrl.isBlank()) continue - book.name = jsonItem.readString("$.bookInfoBean.name") - if (book.descUrl in existingBooks) { - Log.d(APP_TAG, "Found existing book: ${book.name}") - continue - } - book.author = jsonItem.readString("$.bookInfoBean.author") - book.type = if (jsonItem.readString("$.bookInfoBean.bookSourceType") == "AUDIO") 1 else 0 - book.tocUrl = jsonItem.readString("$.bookInfoBean.chapterUrl") ?: book.descUrl - book.coverUrl = jsonItem.readString("$.bookInfoBean.coverUrl") - book.customCoverUrl = jsonItem.readString("$.customCoverPath") - book.lastCheckTime = jsonItem.readLong("$.bookInfoBean.finalRefreshData") ?: 0 - book.canUpdate = jsonItem.readBool("$.allowUpdate") == true - book.totalChapterNum = jsonItem.readInt("$.chapterListSize") ?: 0 - book.durChapterIndex = jsonItem.readInt("$.durChapter") ?: 0 - book.durChapterTitle = jsonItem.readString("$.durChapterName") - book.durChapterPos = jsonItem.readInt("$.durChapterPage") ?: 0 - book.durChapterTime = jsonItem.readLong("$.finalDate") ?: 0 - book.group = jsonItem.readInt("$.group") ?: 0 - // book. = jsonItem.readString("$.hasUpdate") - // book. = jsonItem.readString("$.isLoading") - book.latestChapterTitle = jsonItem.readString("$.lastChapterName") - book.lastCheckCount = jsonItem.readInt("$.newChapters") ?: 0 - book.order = jsonItem.readInt("$.serialNumber") ?: 0 - book.useReplaceRule = jsonItem.readBool("$.useReplaceRule") == true - book.variable = jsonItem.readString("$.variable") - books.add(book) - Log.d(APP_TAG, "Added ${book.name}") - } - App.db.bookDao().insert(*books.toTypedArray()) - val count = books.size - - uiThread { - toast(if (count > 0) "成功地导入 $count 本新书和音频" else "没有发现新书或音频") - } - - } - - } catch (e: Exception) { - Log.e(APP_TAG, "Failed to import book shelf.", e) - toast("Unable to import books:\n${e.localizedMessage}") - } - - // Replace rules - val ruleFile = File(yuedu, "myBookReplaceRule.json") - val replaceRules = mutableListOf() - if (ruleFile.exists()) try { - doAsync { - val items: List> = jsonPath.parse(ruleFile.readText()).read("$") - val existingRules = App.db.replaceRuleDao().all.map { it.pattern }.toSet() - for (item in items) { - val jsonItem = jsonPath.parse(item) - val rRule = ReplaceRule() - rRule.pattern = jsonItem.readString("$.regex") - if (rRule.pattern.isNullOrEmpty() || rRule.pattern in existingRules) continue - rRule.name = jsonItem.readString("$.replaceSummary") - rRule.replacement = jsonItem.readString("$.replacement") - rRule.isRegex = jsonItem.readBool("$.isRegex") == true - rRule.scope = jsonItem.readString("$.useTo") - rRule.isEnabled = jsonItem.readBool("$.enable") == true - rRule.order = jsonItem.readInt("$.serialNumber") ?: 0 - replaceRules.add(rRule) - } - App.db.replaceRuleDao().insert(*replaceRules.toTypedArray()) - val count = replaceRules.size - val maxId = App.db.replaceRuleDao().maxOrder - uiThread { - toast(if (count > 0) "成功地导入 $count 条净化替换规则" else "没有发现新的净化替换规则") - } - } - - } catch (e: Exception) { - Log.e(APP_TAG, e.localizedMessage) - } + private fun importYueDu() { + PermissionsCompat.Builder(this) + .addPermissions(*Permissions.Group.STORAGE) + .rationale(R.string.tip_perm_request_storage) + .onGranted { Restore.importYueDuData(this) }.request() } - } diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 665919c41..7aa2f3126 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -9,7 +9,7 @@ android:icon="@drawable/ic_menu_camera" android:title="@string/menu_backup"/>