Many small changes

- Remove unused gridlayout dependency
- Add RECIEVE_BOOT permission for EH updater
- Some suspending db IO calls
This commit is contained in:
Jobobby04 2021-03-07 02:47:48 -05:00
parent 7e91ae02f1
commit d64a8907eb
15 changed files with 117 additions and 171 deletions

View File

@ -304,8 +304,6 @@ dependencies {
// JsonReader for similar manga // JsonReader for similar manga
implementation("com.squareup.moshi:moshi:1.11.0") implementation("com.squareup.moshi:moshi:1.11.0")
implementation("androidx.gridlayout:gridlayout:1.0.0")
implementation("com.mikepenz:fastadapter:5.3.4") implementation("com.mikepenz:fastadapter:5.3.4")
// SY <-- // SY <--
} }

View File

@ -14,6 +14,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- For managing extensions --> <!-- For managing extensions -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

View File

@ -82,7 +82,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
// SY <-- // SY <--
private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) { private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) {
var manga = backupManga.getMangaImpl() val manga = backupManga.getMangaImpl()
val chapters = backupManga.getChaptersImpl() val chapters = backupManga.getChaptersImpl()
val categories = backupManga.categories val categories = backupManga.categories
val history = backupManga.history val history = backupManga.history
@ -93,7 +93,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
// SY <-- // SY <--
// SY --> // SY -->
manga = EXHMigrations.migrateBackupEntry(manga) EXHMigrations.migrateBackupEntry(manga)
// SY <-- // SY <--
val source = backupManager.sourceManager.get(manga.source) val source = backupManager.sourceManager.get(manga.source)

View File

@ -91,7 +91,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
// SY <-- // SY <--
private suspend fun restoreManga(mangaJson: JsonObject) { private suspend fun restoreManga(mangaJson: JsonObject) {
/* SY --> */ var /* SY <-- */ manga = backupManager.parser.fromJson<MangaImpl>( val manga = backupManager.parser.fromJson<MangaImpl>(
mangaJson.get( mangaJson.get(
Backup.MANGA Backup.MANGA
) )
@ -114,7 +114,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
) )
// EXH --> // EXH -->
manga = EXHMigrations.migrateBackupEntry(manga) EXHMigrations.migrateBackupEntry(manga)
// <-- EXH // <-- EXH
val source = backupManager.sourceManager.get(manga.source) val source = backupManager.sourceManager.get(manga.source)

View File

@ -20,6 +20,7 @@ import exh.search.SearchEngine
import exh.search.Text import exh.search.Text
import exh.source.isMetadataSource import exh.source.isMetadataSource
import exh.util.cancellable import exh.util.cancellable
import exh.util.executeOnIO
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -115,7 +116,7 @@ class LibraryCategoryAdapter(view: LibraryCategoryView, val controller: LibraryC
// Prepare filter object // Prepare filter object
val parsedQuery = searchEngine.parseQuery(savedSearchText) val parsedQuery = searchEngine.parseQuery(savedSearchText)
val mangaWithMetaIdsQuery = db.getIdsOfFavoriteMangaWithMetadata().executeAsBlocking() val mangaWithMetaIdsQuery = db.getIdsOfFavoriteMangaWithMetadata().executeOnIO()
val mangaWithMetaIds = LongArray(mangaWithMetaIdsQuery.count) val mangaWithMetaIds = LongArray(mangaWithMetaIdsQuery.count)
if (mangaWithMetaIds.isNotEmpty()) { if (mangaWithMetaIds.isNotEmpty()) {
val mangaIdCol = mangaWithMetaIdsQuery.getColumnIndex(MangaTable.COL_ID) val mangaIdCol = mangaWithMetaIdsQuery.getColumnIndex(MangaTable.COL_ID)

View File

@ -684,7 +684,7 @@ class LibraryController(
it.source in nHentaiSourceIds || it.source in nHentaiSourceIds ||
it.source == PERV_EDEN_EN_SOURCE_ID || it.source == PERV_EDEN_EN_SOURCE_ID ||
it.source == PERV_EDEN_IT_SOURCE_ID it.source == PERV_EDEN_IT_SOURCE_ID
}.toList() }
presenter.cleanTitles(mangas) presenter.cleanTitles(mangas)
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
} }
@ -692,7 +692,7 @@ class LibraryController(
private fun pushToMdList() { private fun pushToMdList() {
val mangas = selectedMangas.filter { val mangas = selectedMangas.filter {
it.source in mangaDexSourceIds it.source in mangaDexSourceIds
}.toList() }
presenter.syncMangaToDex(mangas) presenter.syncMangaToDex(mangas)
} }
// SY <-- // SY <--

View File

@ -137,7 +137,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
} }
// SY --> // SY -->
R.id.nav_updates -> { R.id.nav_updates -> {
if (router.backstack.last().controller() !is DownloadController) { if (router.backstack.lastOrNull()?.controller() !is DownloadController) {
val controller = router.getControllerWithTag(id.toString()) as? UpdatesController val controller = router.getControllerWithTag(id.toString()) as? UpdatesController
controller?.router?.pushController(DownloadController().withFadeTransaction()) controller?.router?.pushController(DownloadController().withFadeTransaction())
} }

View File

@ -44,6 +44,7 @@ import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.source.isEhBasedManga import exh.source.isEhBasedManga
import exh.uconfig.WarnConfigureDialogController import exh.uconfig.WarnConfigureDialogController
import exh.ui.login.LoginController import exh.ui.login.LoginController
import exh.util.executeOnIO
import exh.util.floor import exh.util.floor
import exh.util.nullIfBlank import exh.util.nullIfBlank
import exh.util.trans import exh.util.trans
@ -635,10 +636,10 @@ class SettingsEhController : SettingsController() {
context.getString(R.string.gallery_updater_stats_text, getRelativeTimeString(getRelativeTimeFromNow(stats.startTime.milliseconds), context), stats.updateCount, stats.possibleUpdates) context.getString(R.string.gallery_updater_stats_text, getRelativeTimeString(getRelativeTimeFromNow(stats.startTime.milliseconds), context), stats.updateCount, stats.possibleUpdates)
} else context.getString(R.string.gallery_updater_not_ran_yet) } else context.getString(R.string.gallery_updater_not_ran_yet)
val allMeta = db.getFavoriteMangaWithMetadata().executeAsBlocking() val allMeta = db.getFavoriteMangaWithMetadata().executeOnIO()
.filter(Manga::isEhBasedManga) .filter(Manga::isEhBasedManga)
.mapNotNull { .mapNotNull {
db.getFlatMetadataForManga(it.id!!).executeAsBlocking() db.getFlatMetadataForManga(it.id!!).executeOnIO()
?.raise<EHentaiSearchMetadata>() ?.raise<EHentaiSearchMetadata>()
}.toList() }.toList()

View File

@ -4,12 +4,9 @@ import android.content.Context
import com.pushtorefresh.storio.sqlite.queries.Query import com.pushtorefresh.storio.sqlite.queries.Query
import com.pushtorefresh.storio.sqlite.queries.RawQuery import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.resolvers.MangaUrlPutResolver import eu.kanade.tachiyomi.data.database.resolvers.MangaUrlPutResolver
import eu.kanade.tachiyomi.data.database.tables.ChapterTable import eu.kanade.tachiyomi.data.database.tables.ChapterTable
import eu.kanade.tachiyomi.data.database.tables.MangaTable import eu.kanade.tachiyomi.data.database.tables.MangaTable
@ -70,18 +67,7 @@ object EXHMigrations {
} }
if (oldVersion < 4) { if (oldVersion < 4) {
db.inTransaction { db.inTransaction {
db.lowLevel().executeSQL( updateSourceId(HBROWSE_SOURCE_ID, 6912)
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = $HBROWSE_SOURCE_ID
WHERE ${MangaTable.COL_SOURCE} = 6912
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
// Migrate BHrowse URLs // Migrate BHrowse URLs
val hBrowseManga = db.db.get() val hBrowseManga = db.db.get()
.listOfObjects(Manga::class.java) .listOfObjects(Manga::class.java)
@ -107,59 +93,15 @@ object EXHMigrations {
} }
if (oldVersion < 5) { if (oldVersion < 5) {
db.inTransaction { db.inTransaction {
// Migrate Tsumino source IDs // Migrate Hitomi source IDs
db.lowLevel().executeSQL( updateSourceId(Hitomi.otherId, 6910)
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = ${Hitomi.otherId}
WHERE ${MangaTable.COL_SOURCE} = 6910
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
} }
} }
if (oldVersion < 6) { if (oldVersion < 6) {
db.inTransaction { db.inTransaction {
db.lowLevel().executeSQL( updateSourceId(PERV_EDEN_EN_SOURCE_ID, 6905)
RawQuery.builder() updateSourceId(PERV_EDEN_IT_SOURCE_ID, 6906)
.query( updateSourceId(NHentai.otherId, 6907)
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = $PERV_EDEN_EN_SOURCE_ID
WHERE ${MangaTable.COL_SOURCE} = 6905
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
db.lowLevel().executeSQL(
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = $PERV_EDEN_IT_SOURCE_ID
WHERE ${MangaTable.COL_SOURCE} = 6906
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
db.lowLevel().executeSQL(
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = ${NHentai.otherId}
WHERE ${MangaTable.COL_SOURCE} = 6907
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
} }
} }
if (oldVersion < 7) { if (oldVersion < 7) {
@ -271,7 +213,7 @@ object EXHMigrations {
// if (oldVersion < 1) { } (1 is current release version) // if (oldVersion < 1) { } (1 is current release version)
// do stuff here when releasing changed crap // do stuff here when releasing changed crap
// TODO BE CAREFUL TO NOT FUCK UP MergedSources IF CHANGING URLsxdcsv // TODO BE CAREFUL TO NOT FUCK UP MergedSources IF CHANGING URLs
preferences.ehLastVersionCode().set(BuildConfig.VERSION_CODE) preferences.ehLastVersionCode().set(BuildConfig.VERSION_CODE)
@ -283,7 +225,7 @@ object EXHMigrations {
return false return false
} }
fun migrateBackupEntry(manga: MangaImpl): MangaImpl { fun migrateBackupEntry(manga: Manga) {
if (manga.source == 6905L) { if (manga.source == 6905L) {
manga.source = PERV_EDEN_EN_SOURCE_ID manga.source = PERV_EDEN_EN_SOURCE_ID
} }
@ -315,14 +257,13 @@ object EXHMigrations {
if (manga.source == 6912L) { if (manga.source == 6912L) {
manga.source = HBROWSE_SOURCE_ID manga.source = HBROWSE_SOURCE_ID
manga.url = manga.url + "/c00001/"
} }
// Allow importing of EHentai extension backups // Allow importing of EHentai extension backups
if (manga.source in BlacklistedSources.EHENTAI_EXT_SOURCES) { if (manga.source in BlacklistedSources.EHENTAI_EXT_SOURCES) {
manga.source = EH_SOURCE_ID manga.source = EH_SOURCE_ID
} }
return manga
} }
private fun backupDatabase(context: Context, oldMigrationVersion: Int) { private fun backupDatabase(context: Context, oldMigrationVersion: Int) {
@ -406,12 +347,19 @@ object EXHMigrations {
} }
private data class LoadedMangaSource(val source: Source, val manga: Manga) private data class LoadedMangaSource(val source: Source, val manga: Manga)
}
data class BackupEntry( private fun updateSourceId(newId: Long, oldId: Long) {
val manga: Manga, db.lowLevel().executeSQL(
val chapters: List<Chapter>, RawQuery.builder()
val categories: List<String>, .query(
val history: List<DHistory>, """
val tracks: List<Track> UPDATE ${MangaTable.TABLE}
) SET ${MangaTable.COL_SOURCE} = $newId
WHERE ${MangaTable.COL_SOURCE} = $oldId
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
}
}

View File

@ -200,7 +200,7 @@ object DebugFunctions {
EHentaiUpdateWorker.scheduleBackground(app) EHentaiUpdateWorker.scheduleBackground(app)
} }
fun listScheduledJobs() = app.jobScheduler.allPendingJobs.map { j -> fun listScheduledJobs() = app.jobScheduler.allPendingJobs.joinToString(",\n") { j ->
""" """
{ {
info: ${j.id}, info: ${j.id},
@ -209,7 +209,7 @@ object DebugFunctions {
intervalMillis: ${j.intervalMillis}, intervalMillis: ${j.intervalMillis},
} }
""".trimIndent() """.trimIndent()
}.joinToString(",\n") }
fun cancelAllScheduledJobs() = app.jobScheduler.cancelAll() fun cancelAllScheduledJobs() = app.jobScheduler.cancelAll()

View File

@ -7,6 +7,7 @@ import android.app.job.JobService
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import com.elvishew.xlog.Logger
import com.elvishew.xlog.XLog import com.elvishew.xlog.XLog
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
@ -21,6 +22,7 @@ import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import exh.debug.DebugToggles import exh.debug.DebugToggles
import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION
import exh.log.xLog
import exh.metadata.metadata.EHentaiSearchMetadata import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.base.getFlatMetadataForManga import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadataAsync import exh.metadata.metadata.base.insertFlatMetadataAsync
@ -44,20 +46,18 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.ArrayList import java.util.ArrayList
import kotlin.coroutines.CoroutineContext
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
import kotlin.time.days import kotlin.time.days
import kotlin.time.hours import kotlin.time.hours
class EHentaiUpdateWorker : JobService(), CoroutineScope { class EHentaiUpdateWorker : JobService() {
override val coroutineContext: CoroutineContext private val scope = CoroutineScope(Dispatchers.Default + Job())
get() = Dispatchers.Default + Job()
private val db: DatabaseHelper by injectLazy() private val db: DatabaseHelper by injectLazy()
private val prefs: PreferencesHelper by injectLazy() private val prefs: PreferencesHelper by injectLazy()
private val sourceManager: SourceManager by injectLazy() private val sourceManager: SourceManager by injectLazy()
private val updateHelper: EHentaiUpdateHelper by injectLazy() private val updateHelper: EHentaiUpdateHelper by injectLazy()
private val logger = XLog.tag("EHUpdater") private val logger: Logger = xLog()
private val updateNotifier by lazy { LibraryUpdateNotifier(this) } private val updateNotifier by lazy { LibraryUpdateNotifier(this) }
@ -85,7 +85,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
* to end the job entirely. Regardless of the value returned, your job must stop executing. * to end the job entirely. Regardless of the value returned, your job must stop executing.
*/ */
override fun onStopJob(params: JobParameters?): Boolean { override fun onStopJob(params: JobParameters?): Boolean {
runBlocking { this@EHentaiUpdateWorker.coroutineContext[Job]?.cancelAndJoin() } runBlocking { scope.coroutineContext[Job]?.cancelAndJoin() }
return false return false
} }
@ -121,7 +121,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
* extras configured with [ This object serves to identify this specific running job instance when calling][JobInfo.Builder.setExtras] * extras configured with [ This object serves to identify this specific running job instance when calling][JobInfo.Builder.setExtras]
*/ */
override fun onStartJob(params: JobParameters): Boolean { override fun onStartJob(params: JobParameters): Boolean {
launch { scope.launch {
startUpdating() startUpdating()
logger.d("Update job completed!") logger.d("Update job completed!")
jobFinished(params, false) jobFinished(params, false)
@ -144,7 +144,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
return@mapNotNull null return@mapNotNull null
} }
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking() val meta = db.getFlatMetadataForManga(manga.id!!).executeOnIO()
?: return@mapNotNull null ?: return@mapNotNull null
val raisedMeta = meta.raise<EHentaiSearchMetadata>() val raisedMeta = meta.raise<EHentaiSearchMetadata>()
@ -273,7 +273,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
return new to db.getChapters(manga).executeOnIO() return new to db.getChapters(manga).executeOnIO()
} catch (t: Throwable) { } catch (t: Throwable) {
if (t is EHentai.GalleryNotFoundException) { if (t is EHentai.GalleryNotFoundException) {
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() val meta = db.getFlatMetadataForManga(manga.id!!).executeOnIO()?.raise<EHentaiSearchMetadata>()
if (meta != null) { if (meta != null) {
// Age dead galleries // Age dead galleries
logger.d("Aged %s - notfound", manga.id) logger.d("Aged %s - notfound", manga.id)
@ -297,62 +297,54 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
private val logger by lazy { XLog.tag("EHUpdaterScheduler") } private val logger by lazy { XLog.tag("EHUpdaterScheduler") }
private fun Context.componentName(): ComponentName { private fun Context.componentName(): ComponentName =
return ComponentName(this, EHentaiUpdateWorker::class.java) ComponentName(this, EHentaiUpdateWorker::class.java)
}
private fun Context.baseBackgroundJobInfo(isTest: Boolean): JobInfo.Builder { private fun Context.baseBackgroundJobInfo(isTest: Boolean): JobInfo.Builder =
return JobInfo.Builder( JobInfo.Builder(
if (isTest) JOB_ID_UPDATE_BACKGROUND_TEST if (isTest) JOB_ID_UPDATE_BACKGROUND_TEST
else JOB_ID_UPDATE_BACKGROUND, else JOB_ID_UPDATE_BACKGROUND,
componentName() componentName()
) )
}
private fun Context.periodicBackgroundJobInfo( private fun Context.periodicBackgroundJobInfo(
period: Long, period: Long,
requireCharging: Boolean, requireCharging: Boolean,
requireUnmetered: Boolean requireUnmetered: Boolean
): JobInfo { ): JobInfo = baseBackgroundJobInfo(false)
return baseBackgroundJobInfo(false) .setPeriodic(period)
.setPeriodic(period) .setPersisted(true)
.setPersisted(true) .setRequiredNetworkType(
.setRequiredNetworkType( if (requireUnmetered) JobInfo.NETWORK_TYPE_UNMETERED
if (requireUnmetered) JobInfo.NETWORK_TYPE_UNMETERED else JobInfo.NETWORK_TYPE_ANY
else JobInfo.NETWORK_TYPE_ANY )
) .apply {
.apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { setRequiresBatteryNotLow(true)
setRequiresBatteryNotLow(true)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
setEstimatedNetworkBytes(
15000L * UPDATES_PER_ITERATION,
1000L * UPDATES_PER_ITERATION
)
}
} }
.setRequiresCharging(requireCharging) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// .setRequiresDeviceIdle(true) Job never seems to run with this setEstimatedNetworkBytes(
.build() 15000L * UPDATES_PER_ITERATION,
} 1000L * UPDATES_PER_ITERATION
)
}
}
.setRequiresCharging(requireCharging)
// .setRequiresDeviceIdle(true) Job never seems to run with this
.build()
private fun Context.testBackgroundJobInfo(): JobInfo { private fun Context.testBackgroundJobInfo(): JobInfo = baseBackgroundJobInfo(true)
return baseBackgroundJobInfo(true) .setOverrideDeadline(1)
.setOverrideDeadline(1) .build()
.build()
}
fun launchBackgroundTest(context: Context): String { fun launchBackgroundTest(context: Context): String =
val jobScheduler = context.jobScheduler if (context.jobScheduler.schedule(context.testBackgroundJobInfo()) == JobScheduler.RESULT_FAILURE) {
return if (jobScheduler.schedule(context.testBackgroundJobInfo()) == JobScheduler.RESULT_FAILURE) {
logger.e("Failed to schedule background test job!") logger.e("Failed to schedule background test job!")
"Failed" "Failed"
} else { } else {
logger.d("Successfully scheduled background test job!") logger.d("Successfully scheduled background test job!")
"Success" "Success"
} }
}
fun scheduleBackground(context: Context, prefInterval: Int? = null) { fun scheduleBackground(context: Context, prefInterval: Int? = null) {
cancelBackground(context) cancelBackground(context)

View File

@ -17,7 +17,7 @@ import java.util.Locale
class EHDebugModeOverlay(private val context: Context) : OverlayModule<String>(null, null) { class EHDebugModeOverlay(private val context: Context) : OverlayModule<String>(null, null) {
private var textView: TextView? = null private var textView: TextView? = null
private val prefs: PreferencesHelper by injectLazy() private val preferences: PreferencesHelper by injectLazy()
override fun start() {} override fun start() {}
override fun stop() {} override fun stop() {}
@ -27,25 +27,29 @@ class EHDebugModeOverlay(private val context: Context) : OverlayModule<String>(n
} }
override fun removeObserver(observer: DataObserver<Any>) {} override fun removeObserver(observer: DataObserver<Any>) {}
override fun onDataAvailable(data: String?) { override fun onDataAvailable(data: String?) {
textView?.text = HtmlCompat.fromHtml(data!!, HtmlCompat.FROM_HTML_MODE_LEGACY) textView?.text = HtmlCompat.fromHtml(data.orEmpty(), HtmlCompat.FROM_HTML_MODE_LEGACY)
} }
override fun createView(root: ViewGroup, textColor: Int, textSize: Float, textAlpha: Float): View { override fun createView(root: ViewGroup, textColor: Int, textSize: Float, textAlpha: Float): View {
val view = LinearLayout(root.context) val view = LinearLayout(root.context).apply {
view.layoutParams = ViewGroup.LayoutParams( layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT ViewGroup.LayoutParams.WRAP_CONTENT
) )
view.setPadding(4.dpToPx, 0, 4.dpToPx, 4.dpToPx) setPadding(4.dpToPx, 0, 4.dpToPx, 4.dpToPx)
val textView = TextView(view.context) }
textView.setTextColor(textColor)
textView.textSize = textSize val textView = TextView(view.context).apply {
textView.alpha = textAlpha setTextColor(textColor)
textView.text = HtmlCompat.fromHtml(buildInfo(), HtmlCompat.FROM_HTML_MODE_LEGACY) this.textSize = textSize
textView.layoutParams = LinearLayout.LayoutParams( alpha = textAlpha
ViewGroup.LayoutParams.WRAP_CONTENT, text = HtmlCompat.fromHtml(buildInfo(), HtmlCompat.FROM_HTML_MODE_LEGACY)
ViewGroup.LayoutParams.WRAP_CONTENT layoutParams = LinearLayout.LayoutParams(
) ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
view.addView(textView) view.addView(textView)
this.textView = textView this.textView = textView
return view return view
@ -59,7 +63,7 @@ class EHDebugModeOverlay(private val context: Context) : OverlayModule<String>(n
<b>Version code:</b> ${BuildConfig.VERSION_CODE}<br> <b>Version code:</b> ${BuildConfig.VERSION_CODE}<br>
<b>Commit SHA:</b> ${BuildConfig.COMMIT_SHA}<br> <b>Commit SHA:</b> ${BuildConfig.COMMIT_SHA}<br>
<b>Log level:</b> ${EHLogLevel.currentLogLevel.name.toLowerCase(Locale.getDefault())}<br> <b>Log level:</b> ${EHLogLevel.currentLogLevel.name.toLowerCase(Locale.getDefault())}<br>
<b>Source blacklist:</b> ${prefs.enableSourceBlacklist().get().asEnabledString()} <b>Source blacklist:</b> ${preferences.enableSourceBlacklist().get().asEnabledString()}
""".trimIndent() """.trimIndent()
private fun Boolean.asEnabledString() = if (this) "enabled" else "disabled" private fun Boolean.asEnabledString() = if (this) "enabled" else "disabled"

View File

@ -21,12 +21,11 @@ class SimilarHandler(val preferences: PreferencesHelper, private val useLowQuali
// Parse the Mangadex id from the URL // Parse the Mangadex id from the URL
return Observable.just(MdUtil.getMangaId(manga.url).toLong()) return Observable.just(MdUtil.getMangaId(manga.url).toLong())
.flatMap { mangaId -> .flatMap { mangaId ->
val db = Injekt.get<DatabaseHelper>() Injekt.get<DatabaseHelper>().getSimilar(mangaId).asRxObservable()
db.getSimilar(mangaId).asRxObservable()
}.map { similarMangaDb: MangaSimilar? -> }.map { similarMangaDb: MangaSimilar? ->
similarMangaDb?.let { mangaSimilar -> if (similarMangaDb != null) {
val similarMangaTitles = mangaSimilar.matched_titles.split(MangaSimilarImpl.DELIMITER) val similarMangaTitles = similarMangaDb.matched_titles.split(MangaSimilarImpl.DELIMITER)
val similarMangaIds = mangaSimilar.matched_ids.split(MangaSimilarImpl.DELIMITER) val similarMangaIds = similarMangaDb.matched_ids.split(MangaSimilarImpl.DELIMITER)
val similarMangas = similarMangaIds.mapIndexed { index, similarId -> val similarMangas = similarMangaIds.mapIndexed { index, similarId ->
SManga.create().apply { SManga.create().apply {
title = similarMangaTitles[index] title = similarMangaTitles[index]
@ -35,7 +34,7 @@ class SimilarHandler(val preferences: PreferencesHelper, private val useLowQuali
} }
} }
MangasPage(similarMangas, false) MangasPage(similarMangas, false)
} ?: MangasPage(mutableListOf(), false) } else MangasPage(mutableListOf(), false)
} }
} }
} }

View File

@ -1,21 +1,24 @@
package exh.util package exh.util
import android.database.Cursor
import com.pushtorefresh.storio.operations.PreparedOperation import com.pushtorefresh.storio.operations.PreparedOperation
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetCursor
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetObject import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetObject
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutCollectionOfObjects import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutCollectionOfObjects
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutObject import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutObject
import com.pushtorefresh.storio.sqlite.operations.put.PutResult import com.pushtorefresh.storio.sqlite.operations.put.PutResult
import com.pushtorefresh.storio.sqlite.operations.put.PutResults import com.pushtorefresh.storio.sqlite.operations.put.PutResults
import kotlinx.coroutines.Dispatchers import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.coroutines.withContext
suspend fun <T> PreparedGetListOfObjects<T>.executeOnIO(): List<T> = withContext(Dispatchers.IO) { executeAsBlocking() } suspend fun <T> PreparedGetListOfObjects<T>.executeOnIO(): List<T> = withIOContext { executeAsBlocking() }
suspend fun <T> PreparedGetObject<T>.executeOnIO(): T? = withContext(Dispatchers.IO) { executeAsBlocking() } suspend fun <T> PreparedGetObject<T>.executeOnIO(): T? = withIOContext { executeAsBlocking() }
suspend fun <T> PreparedPutObject<T>.executeOnIO(): PutResult = withContext(Dispatchers.IO) { executeAsBlocking() } suspend fun <T> PreparedPutObject<T>.executeOnIO(): PutResult = withIOContext { executeAsBlocking() }
suspend fun <T> PreparedPutCollectionOfObjects<T>.executeOnIO(): PutResults<T> = withContext(Dispatchers.IO) { executeAsBlocking() } suspend fun <T> PreparedPutCollectionOfObjects<T>.executeOnIO(): PutResults<T> = withIOContext { executeAsBlocking() }
suspend fun <T> PreparedOperation<T>.executeOnIO(): T? = withContext(Dispatchers.IO) { executeAsBlocking() } suspend fun PreparedGetCursor.executeOnIO(): Cursor = withIOContext { executeAsBlocking() }
suspend fun <T> PreparedOperation<T>.executeOnIO(): T? = withIOContext { executeAsBlocking() }

View File

@ -8,7 +8,7 @@ import org.jsoup.nodes.Document
fun Response.interceptAsHtml(block: (Document) -> Unit): Response { fun Response.interceptAsHtml(block: (Document) -> Unit): Response {
val body = body val body = body
if (body?.contentType()?.type == "text" && return if (body?.contentType()?.type == "text" &&
body.contentType()?.subtype == "html" body.contentType()?.subtype == "html"
) { ) {
val bodyString = body.string() val bodyString = body.string()
@ -26,7 +26,6 @@ fun Response.interceptAsHtml(block: (Document) -> Unit): Response {
close() close()
} }
return rebuiltResponse rebuiltResponse
} } else this
return this
} }