2019-04-06 13:35:36 +02:00
|
|
|
package exh
|
|
|
|
|
|
2019-04-18 23:47:13 +02:00
|
|
|
import android.content.Context
|
2019-04-18 23:40:13 +02:00
|
|
|
import com.elvishew.xlog.XLog
|
2019-04-06 13:35:36 +02:00
|
|
|
import com.pushtorefresh.storio.sqlite.queries.Query
|
|
|
|
|
import com.pushtorefresh.storio.sqlite.queries.RawQuery
|
2019-04-22 06:02:48 +02:00
|
|
|
import eu.kanade.tachiyomi.BuildConfig
|
2020-04-07 04:48:22 +02:00
|
|
|
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
|
2019-04-14 17:17:21 +02:00
|
|
|
import eu.kanade.tachiyomi.data.backup.models.DHistory
|
2019-04-06 13:35:36 +02:00
|
|
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
2019-04-14 17:17:21 +02:00
|
|
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
2019-04-06 13:35:36 +02:00
|
|
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
2019-04-14 17:17:21 +02:00
|
|
|
import eu.kanade.tachiyomi.data.database.models.Track
|
2019-04-06 13:35:36 +02:00
|
|
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaUrlPutResolver
|
|
|
|
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
2020-04-07 04:48:22 +02:00
|
|
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
2019-04-06 13:35:36 +02:00
|
|
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
|
|
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
2020-04-07 04:48:22 +02:00
|
|
|
import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
2020-04-13 23:53:43 +02:00
|
|
|
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
2020-03-31 22:38:40 +02:00
|
|
|
import eu.kanade.tachiyomi.util.system.jobScheduler
|
2019-04-14 18:48:59 +02:00
|
|
|
import exh.source.BlacklistedSources
|
2019-04-14 17:17:21 +02:00
|
|
|
import rx.Observable
|
2019-04-06 13:35:36 +02:00
|
|
|
import uy.kohesive.injekt.injectLazy
|
2019-04-18 23:47:13 +02:00
|
|
|
import java.io.File
|
2019-04-06 13:35:36 +02:00
|
|
|
import java.net.URI
|
|
|
|
|
import java.net.URISyntaxException
|
|
|
|
|
|
|
|
|
|
object EXHMigrations {
|
|
|
|
|
private val db: DatabaseHelper by injectLazy()
|
|
|
|
|
|
2019-04-18 23:40:13 +02:00
|
|
|
private val logger = XLog.tag("EXHMigrations")
|
|
|
|
|
|
2019-04-06 13:35:36 +02:00
|
|
|
/**
|
|
|
|
|
* Performs a migration when the application is updated.
|
|
|
|
|
*
|
|
|
|
|
* @param preferences Preferences of the application.
|
|
|
|
|
* @return true if a migration is performed, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
fun upgrade(preferences: PreferencesHelper): Boolean {
|
|
|
|
|
val context = preferences.context
|
|
|
|
|
val oldVersion = preferences.eh_lastVersionCode().getOrDefault()
|
2019-04-18 23:40:13 +02:00
|
|
|
try {
|
2019-04-22 06:02:48 +02:00
|
|
|
if (oldVersion < BuildConfig.VERSION_CODE) {
|
2019-04-18 23:40:13 +02:00
|
|
|
if (oldVersion < 1) {
|
|
|
|
|
db.inTransaction {
|
|
|
|
|
// Migrate HentaiCafe source IDs
|
2020-05-02 06:46:24 +02:00
|
|
|
db.lowLevel().executeSQL(
|
|
|
|
|
RawQuery.builder()
|
|
|
|
|
.query(
|
|
|
|
|
"""
|
|
|
|
|
UPDATE ${MangaTable.TABLE}
|
|
|
|
|
SET ${MangaTable.COL_SOURCE} = $HENTAI_CAFE_SOURCE_ID
|
|
|
|
|
WHERE ${MangaTable.COL_SOURCE} = 6908
|
|
|
|
|
""".trimIndent()
|
|
|
|
|
)
|
2019-04-18 23:40:13 +02:00
|
|
|
.affectsTables(MangaTable.TABLE)
|
2020-05-02 06:46:24 +02:00
|
|
|
.build()
|
|
|
|
|
)
|
2019-04-06 13:35:36 +02:00
|
|
|
|
2019-04-18 23:40:13 +02:00
|
|
|
// Migrate nhentai URLs
|
|
|
|
|
val nhentaiManga = db.db.get()
|
2020-05-02 06:46:24 +02:00
|
|
|
.listOfObjects(Manga::class.java)
|
|
|
|
|
.withQuery(
|
|
|
|
|
Query.builder()
|
|
|
|
|
.table(MangaTable.TABLE)
|
|
|
|
|
.where("${MangaTable.COL_SOURCE} = $NHENTAI_SOURCE_ID")
|
|
|
|
|
.build()
|
|
|
|
|
)
|
|
|
|
|
.prepare()
|
|
|
|
|
.executeAsBlocking()
|
2019-04-06 13:35:36 +02:00
|
|
|
|
2019-04-18 23:40:13 +02:00
|
|
|
nhentaiManga.forEach {
|
|
|
|
|
it.url = getUrlWithoutDomain(it.url)
|
|
|
|
|
}
|
2019-04-06 13:35:36 +02:00
|
|
|
|
2019-04-18 23:40:13 +02:00
|
|
|
db.db.put()
|
2020-05-02 06:46:24 +02:00
|
|
|
.objects(nhentaiManga)
|
|
|
|
|
// Extremely slow without the resolver :/
|
|
|
|
|
.withPutResolver(MangaUrlPutResolver())
|
|
|
|
|
.prepare()
|
|
|
|
|
.executeAsBlocking()
|
2019-04-18 23:40:13 +02:00
|
|
|
}
|
2019-04-06 13:35:36 +02:00
|
|
|
}
|
|
|
|
|
|
2019-04-18 23:47:13 +02:00
|
|
|
// Backup database in next release
|
|
|
|
|
if (oldVersion < 2) {
|
|
|
|
|
backupDatabase(context, oldVersion)
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-13 07:31:44 +02:00
|
|
|
if (oldVersion < 8405) {
|
|
|
|
|
db.inTransaction {
|
|
|
|
|
// Migrate HBrowse source IDs
|
2020-05-02 06:46:24 +02:00
|
|
|
db.lowLevel().executeSQL(
|
|
|
|
|
RawQuery.builder()
|
|
|
|
|
.query(
|
|
|
|
|
"""
|
|
|
|
|
UPDATE ${MangaTable.TABLE}
|
|
|
|
|
SET ${MangaTable.COL_SOURCE} = $HBROWSE_SOURCE_ID
|
|
|
|
|
WHERE ${MangaTable.COL_SOURCE} = 1401584337232758222
|
|
|
|
|
""".trimIndent()
|
|
|
|
|
)
|
2019-08-13 07:31:44 +02:00
|
|
|
.affectsTables(MangaTable.TABLE)
|
2020-05-02 06:46:24 +02:00
|
|
|
.build()
|
|
|
|
|
)
|
2019-08-13 07:31:44 +02:00
|
|
|
}
|
2019-08-13 07:43:07 +02:00
|
|
|
|
|
|
|
|
// Cancel old scheduler jobs with old ids
|
2020-04-22 23:26:46 +02:00
|
|
|
context.jobScheduler.cancelAll()
|
2019-08-13 07:31:44 +02:00
|
|
|
}
|
2020-02-22 11:12:30 +01:00
|
|
|
if (oldVersion < 8408) {
|
|
|
|
|
db.inTransaction {
|
|
|
|
|
// Migrate Tsumino source IDs
|
2020-05-02 06:46:24 +02:00
|
|
|
db.lowLevel().executeSQL(
|
|
|
|
|
RawQuery.builder()
|
|
|
|
|
.query(
|
|
|
|
|
"""
|
|
|
|
|
UPDATE ${MangaTable.TABLE}
|
|
|
|
|
SET ${MangaTable.COL_SOURCE} = $TSUMINO_SOURCE_ID
|
|
|
|
|
WHERE ${MangaTable.COL_SOURCE} = 6909
|
|
|
|
|
""".trimIndent()
|
|
|
|
|
)
|
2020-02-22 11:12:30 +01:00
|
|
|
.affectsTables(MangaTable.TABLE)
|
2020-05-02 06:46:24 +02:00
|
|
|
.build()
|
|
|
|
|
)
|
2020-02-22 11:12:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-03-07 10:44:25 +01:00
|
|
|
if (oldVersion < 8409) {
|
|
|
|
|
db.inTransaction {
|
|
|
|
|
// Migrate tsumino URLs
|
|
|
|
|
val tsuminoManga = db.db.get()
|
2020-04-07 04:48:22 +02:00
|
|
|
.listOfObjects(Manga::class.java)
|
|
|
|
|
.withQuery(
|
|
|
|
|
Query.builder()
|
|
|
|
|
.table(MangaTable.TABLE)
|
|
|
|
|
.where("${MangaTable.COL_SOURCE} = $TSUMINO_SOURCE_ID")
|
|
|
|
|
.build()
|
|
|
|
|
)
|
|
|
|
|
.prepare()
|
|
|
|
|
.executeAsBlocking()
|
2020-03-07 10:44:25 +01:00
|
|
|
tsuminoManga.forEach {
|
|
|
|
|
it.url = "/entry/"+it.url.split("/").last()
|
|
|
|
|
}
|
2020-02-22 11:12:30 +01:00
|
|
|
|
2020-03-07 10:44:25 +01:00
|
|
|
db.db.put()
|
2020-04-07 04:48:22 +02:00
|
|
|
.objects(tsuminoManga)
|
|
|
|
|
// Extremely slow without the resolver :/
|
|
|
|
|
.withPutResolver(MangaUrlPutResolver())
|
|
|
|
|
.prepare()
|
|
|
|
|
.executeAsBlocking()
|
|
|
|
|
}
|
2020-04-13 23:53:43 +02:00
|
|
|
}
|
|
|
|
|
if (oldVersion < 8410) {
|
|
|
|
|
// Migrate to WorkManager
|
2020-05-02 04:37:06 +02:00
|
|
|
UpdaterJob.setupTask(context)
|
2020-04-13 23:53:43 +02:00
|
|
|
LibraryUpdateJob.setupTask(context)
|
|
|
|
|
BackupCreatorJob.setupTask(context)
|
|
|
|
|
ExtensionUpdateJob.setupTask(context)
|
2020-03-07 10:44:25 +01:00
|
|
|
}
|
2020-02-22 11:12:30 +01:00
|
|
|
|
2019-08-13 07:31:44 +02:00
|
|
|
|
2019-07-30 01:36:16 +02:00
|
|
|
// TODO BE CAREFUL TO NOT FUCK UP MergedSources IF CHANGING URLs
|
|
|
|
|
|
2019-04-22 06:02:48 +02:00
|
|
|
preferences.eh_lastVersionCode().set(BuildConfig.VERSION_CODE)
|
2019-04-18 23:40:13 +02:00
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
} catch(e: Exception) {
|
2019-04-22 06:02:48 +02:00
|
|
|
logger.e( "Failed to migrate app from $oldVersion -> ${BuildConfig.VERSION_CODE}!", e)
|
2019-04-06 13:35:36 +02:00
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 17:17:21 +02:00
|
|
|
fun migrateBackupEntry(backupEntry: BackupEntry): Observable<BackupEntry> {
|
|
|
|
|
val (manga, chapters, categories, history, tracks) = backupEntry
|
|
|
|
|
|
|
|
|
|
// Migrate HentaiCafe source IDs
|
|
|
|
|
if(manga.source == 6908L) {
|
|
|
|
|
manga.source = HENTAI_CAFE_SOURCE_ID
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-22 11:12:30 +01:00
|
|
|
// Migrate Tsumino source IDs
|
|
|
|
|
if(manga.source == 6909L) {
|
|
|
|
|
manga.source = TSUMINO_SOURCE_ID
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 17:17:21 +02:00
|
|
|
// Migrate nhentai URLs
|
|
|
|
|
if(manga.source == NHENTAI_SOURCE_ID) {
|
|
|
|
|
manga.url = getUrlWithoutDomain(manga.url)
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 18:12:26 +02:00
|
|
|
// Allow importing of nhentai extension backups
|
2019-04-14 18:48:59 +02:00
|
|
|
if(manga.source in BlacklistedSources.NHENTAI_EXT_SOURCES) {
|
2019-04-14 18:12:26 +02:00
|
|
|
manga.source = NHENTAI_SOURCE_ID
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 18:48:59 +02:00
|
|
|
// Allow importing of English PervEden extension backups
|
|
|
|
|
if(manga.source in BlacklistedSources.PERVEDEN_EN_EXT_SOURCES) {
|
|
|
|
|
manga.source = PERV_EDEN_EN_SOURCE_ID
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 18:12:26 +02:00
|
|
|
// Allow importing of Italian PervEden extension backups
|
2019-04-14 18:48:59 +02:00
|
|
|
if(manga.source in BlacklistedSources.PERVEDEN_IT_EXT_SOURCES) {
|
2019-04-14 18:12:26 +02:00
|
|
|
manga.source = PERV_EDEN_IT_SOURCE_ID
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 18:48:59 +02:00
|
|
|
// Allow importing of EHentai extension backups
|
|
|
|
|
if(manga.source in BlacklistedSources.EHENTAI_EXT_SOURCES) {
|
2019-04-14 18:12:26 +02:00
|
|
|
manga.source = EH_SOURCE_ID
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 17:17:21 +02:00
|
|
|
return Observable.just(backupEntry)
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-18 23:47:13 +02:00
|
|
|
private fun backupDatabase(context: Context, oldMigrationVersion: Int) {
|
|
|
|
|
val backupLocation = File(File(context.filesDir, "exh_db_bck"), "$oldMigrationVersion.bck.db")
|
|
|
|
|
if(backupLocation.exists()) return // Do not backup same version twice
|
|
|
|
|
|
|
|
|
|
val dbLocation = context.getDatabasePath(db.lowLevel().sqliteOpenHelper().databaseName)
|
|
|
|
|
try {
|
|
|
|
|
dbLocation.copyTo(backupLocation, overwrite = true)
|
|
|
|
|
} catch(t: Throwable) {
|
|
|
|
|
XLog.w("Failed to backup database!")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-06 13:35:36 +02:00
|
|
|
private fun getUrlWithoutDomain(orig: String): String {
|
|
|
|
|
return try {
|
|
|
|
|
val uri = URI(orig)
|
|
|
|
|
var out = uri.path
|
2020-05-02 06:46:24 +02:00
|
|
|
if (uri.query != null) {
|
2019-04-06 13:35:36 +02:00
|
|
|
out += "?" + uri.query
|
2020-05-02 06:46:24 +02:00
|
|
|
}
|
|
|
|
|
if (uri.fragment != null) {
|
2019-04-06 13:35:36 +02:00
|
|
|
out += "#" + uri.fragment
|
2020-05-02 06:46:24 +02:00
|
|
|
}
|
2019-04-06 13:35:36 +02:00
|
|
|
out
|
|
|
|
|
} catch (e: URISyntaxException) {
|
|
|
|
|
orig
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-14 17:17:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data class BackupEntry(
|
|
|
|
|
val manga: Manga,
|
|
|
|
|
val chapters: List<Chapter>,
|
|
|
|
|
val categories: List<String>,
|
|
|
|
|
val history: List<DHistory>,
|
|
|
|
|
val tracks: List<Track>
|
|
|
|
|
)
|