Cleanup
This commit is contained in:
parent
166aebdf25
commit
80960d87f2
@ -51,7 +51,7 @@ class MangaDex(delegate: HttpSource, val context: Context) :
|
||||
val lcFirstPathSegment = uri.pathSegments.firstOrNull()?.toLowerCase() ?: return null
|
||||
|
||||
return if (lcFirstPathSegment == "title" || lcFirstPathSegment == "manga") {
|
||||
"/manga/${uri.pathSegments[1]}"
|
||||
"/manga/${uri.pathSegments[1]}/"
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import exh.util.DeferredField
|
||||
import exh.util.await
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@ -28,7 +29,7 @@ class MigratingManga(
|
||||
@Volatile
|
||||
private var manga: Manga? = null
|
||||
suspend fun manga(): Manga? {
|
||||
if (manga == null) manga = db.getManga(mangaId).executeAsBlocking()
|
||||
if (manga == null) manga = db.getManga(mangaId).await()
|
||||
return manga
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ import eu.kanade.tachiyomi.databinding.MigrationListControllerBinding
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationMangaDialog
|
||||
@ -39,7 +38,6 @@ import exh.util.RecyclerWindowInsetsListener
|
||||
import exh.util.await
|
||||
import exh.util.executeOnIO
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -56,8 +54,7 @@ import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class MigrationListController(bundle: Bundle? = null) :
|
||||
BaseController<MigrationListControllerBinding>(bundle),
|
||||
MigrationProcessAdapter.MigrationProcessInterface,
|
||||
CoroutineScope {
|
||||
MigrationProcessAdapter.MigrationProcessInterface {
|
||||
|
||||
init {
|
||||
setHasOptionsMenu(true)
|
||||
@ -65,7 +62,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
private var adapter: MigrationProcessAdapter? = null
|
||||
|
||||
override val coroutineContext: CoroutineContext = Job() + Dispatchers.Default
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
|
||||
val config: MigrationProcedureConfig? = args.getParcelable(CONFIG_EXTRA)
|
||||
|
||||
@ -73,7 +70,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
|
||||
private val smartSearchEngine = SmartSearchEngine(coroutineContext, config?.extraSearchParams)
|
||||
private val smartSearchEngine = SmartSearchEngine(config?.extraSearchParams)
|
||||
|
||||
var migrationsJob: Job? = null
|
||||
private set
|
||||
@ -99,7 +96,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
val newMigratingManga = migratingManga ?: run {
|
||||
val new = config.mangaIds.map {
|
||||
MigratingManga(db, sourceManager, it, coroutineContext)
|
||||
MigratingManga(db, sourceManager, it, scope.coroutineContext)
|
||||
}
|
||||
migratingManga = new.toMutableList()
|
||||
new
|
||||
@ -115,13 +112,14 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
adapter?.updateDataSet(newMigratingManga.map { it.toModal() })
|
||||
|
||||
if (migrationsJob == null) {
|
||||
migrationsJob = launch {
|
||||
migrationsJob = scope.launch {
|
||||
runMigrations(newMigratingManga)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun runMigrations(mangas: List<MigratingManga>) {
|
||||
if (config == null) return
|
||||
val useSourceWithMost = preferences.useSourceWithMost().get()
|
||||
val useSmartSearch = preferences.smartMigration().get()
|
||||
|
||||
@ -129,7 +127,6 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
val value = it.toLongOrNull() ?: return
|
||||
sourceManager.get(value) as? CatalogueSource
|
||||
}
|
||||
if (config == null) return
|
||||
for (manga in mangas) {
|
||||
if (migrationsJob?.isCancelled == true) {
|
||||
break
|
||||
@ -164,40 +161,20 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
sourceSemaphore.withPermit {
|
||||
try {
|
||||
val searchResult = if (useSmartSearch) {
|
||||
smartSearchEngine.smartSearch(
|
||||
source,
|
||||
mangaObj.originalTitle
|
||||
)
|
||||
smartSearchEngine.smartSearch(source, mangaObj.originalTitle)
|
||||
} else {
|
||||
smartSearchEngine.normalSearch(
|
||||
source,
|
||||
mangaObj.originalTitle
|
||||
)
|
||||
smartSearchEngine.normalSearch(source, mangaObj.originalTitle)
|
||||
}
|
||||
|
||||
if (searchResult != null &&
|
||||
!(
|
||||
searchResult.url == mangaObj.url &&
|
||||
source.id == mangaObj.source
|
||||
)
|
||||
) {
|
||||
if (searchResult != null && (searchResult.url == mangaObj.url && source.id == mangaObj.source)) {
|
||||
val localManga =
|
||||
smartSearchEngine.networkToLocalManga(
|
||||
searchResult,
|
||||
source.id
|
||||
)
|
||||
val chapters =
|
||||
source.fetchChapterList(localManga).toSingle()
|
||||
.await(
|
||||
Schedulers.io()
|
||||
)
|
||||
val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io())
|
||||
try {
|
||||
syncChaptersWithSource(
|
||||
db,
|
||||
chapters,
|
||||
localManga,
|
||||
source
|
||||
)
|
||||
syncChaptersWithSource(db, chapters, localManga, source)
|
||||
} catch (e: Exception) {
|
||||
return@async null
|
||||
}
|
||||
@ -214,34 +191,24 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
}
|
||||
}
|
||||
}
|
||||
}.mapNotNull { it.await() }.maxBy { it.second }?.first
|
||||
}.mapNotNull { it.await() }.maxByOrNull { it.second }?.first
|
||||
} else {
|
||||
validSources.forEachIndexed { index, source ->
|
||||
val searchResult = try {
|
||||
val searchResult = if (useSmartSearch) {
|
||||
smartSearchEngine.smartSearch(
|
||||
source,
|
||||
mangaObj.originalTitle
|
||||
)
|
||||
smartSearchEngine.smartSearch(source, mangaObj.originalTitle)
|
||||
} else {
|
||||
smartSearchEngine.normalSearch(
|
||||
source,
|
||||
mangaObj.originalTitle
|
||||
)
|
||||
smartSearchEngine.normalSearch(source, mangaObj.originalTitle)
|
||||
}
|
||||
|
||||
if (searchResult != null) {
|
||||
val localManga = smartSearchEngine.networkToLocalManga(
|
||||
searchResult,
|
||||
source.id
|
||||
)
|
||||
val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id)
|
||||
val chapters = try {
|
||||
source.fetchChapterList(localManga).toSingle()
|
||||
.await(Schedulers.io())
|
||||
source.fetchChapterList(localManga).toSingle().await(Schedulers.io()) ?: emptyList()
|
||||
} catch (e: java.lang.Exception) {
|
||||
Timber.e(e)
|
||||
emptyList<SChapter>()
|
||||
} ?: emptyList()
|
||||
emptyList()
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
syncChaptersWithSource(db, chapters, localManga, source)
|
||||
}
|
||||
@ -253,9 +220,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
manga.progress.send(validSources.size to (index + 1))
|
||||
|
||||
if (searchResult != null) return@async searchResult
|
||||
}
|
||||
|
||||
@ -269,12 +234,10 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
if (result != null && result.thumbnail_url == null) {
|
||||
try {
|
||||
val newManga =
|
||||
sourceManager.getOrStub(result.source).fetchMangaDetails(result)
|
||||
.toSingle().await()
|
||||
val newManga = sourceManager.getOrStub(result.source).fetchMangaDetails(result).toSingle().await()
|
||||
result.copyFrom(newManga)
|
||||
|
||||
db.insertManga(result).executeAsBlocking()
|
||||
db.insertManga(result).await()
|
||||
} catch (e: CancellationException) {
|
||||
// Ignore cancellations
|
||||
throw e
|
||||
@ -282,8 +245,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
}
|
||||
}
|
||||
|
||||
manga.migrationStatus =
|
||||
if (result == null) MigrationStatus.MANGA_NOT_FOUND else MigrationStatus.MANGA_FOUND
|
||||
manga.migrationStatus = if (result == null) MigrationStatus.MANGA_NOT_FOUND else MigrationStatus.MANGA_FOUND
|
||||
adapter?.sourceFinished()
|
||||
manga.searchResult.initialize(result?.id)
|
||||
}
|
||||
@ -374,9 +336,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
val result = CoroutineScope(migratingManga.manga.migrationJob).async {
|
||||
val localManga = smartSearchEngine.networkToLocalManga(manga, source.id)
|
||||
try {
|
||||
val chapters = source.fetchChapterList(localManga).toSingle().await(
|
||||
Schedulers.io()
|
||||
)
|
||||
val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io())
|
||||
syncChaptersWithSource(db, chapters, localManga, source)
|
||||
} catch (e: Exception) {
|
||||
return@async null
|
||||
@ -386,12 +346,10 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
if (result != null) {
|
||||
try {
|
||||
val newManga =
|
||||
sourceManager.getOrStub(result.source).fetchMangaDetails(result).toSingle()
|
||||
.await()
|
||||
val newManga = sourceManager.getOrStub(result.source).fetchMangaDetails(result).toSingle().await()
|
||||
result.copyFrom(newManga)
|
||||
|
||||
db.insertManga(result).executeAsBlocking()
|
||||
db.insertManga(result).await()
|
||||
} catch (e: CancellationException) {
|
||||
// Ignore cancellations
|
||||
throw e
|
||||
|
@ -107,7 +107,7 @@ class MigrationProcessAdapter(
|
||||
if (MigrationFlags.hasChapters(flags)) {
|
||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||
val maxChapterRead =
|
||||
prevMangaChapters.filter { it.read }.maxBy { it.chapter_number }?.chapter_number
|
||||
prevMangaChapters.filter { it.read }.maxByOrNull { it.chapter_number }?.chapter_number
|
||||
if (maxChapterRead != null) {
|
||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||
for (chapter in dbChapters) {
|
||||
|
@ -181,7 +181,7 @@ class MigrationProcessHolder(
|
||||
val mangaChapters = db.getChapters(manga).executeAsBlocking()
|
||||
manga_chapters.isVisible = true
|
||||
manga_chapters.text = mangaChapters.size.toString()
|
||||
val latestChapter = mangaChapters.maxBy { it.chapter_number }?.chapter_number ?: -1f
|
||||
val latestChapter = mangaChapters.maxByOrNull { it.chapter_number }?.chapter_number ?: -1f
|
||||
|
||||
if (latestChapter > 0f) {
|
||||
manga_last_chapter_label.text = context.getString(
|
||||
|
@ -73,7 +73,7 @@ class MigrationMangaPresenter(
|
||||
|
||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||
val maxChapterRead =
|
||||
prevMangaChapters.filter { it.read }.maxBy { it.chapter_number }?.chapter_number
|
||||
prevMangaChapters.filter { it.read }.maxByOrNull { it.chapter_number }?.chapter_number
|
||||
if (maxChapterRead != null) {
|
||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||
for (chapter in dbChapters) {
|
||||
|
@ -62,8 +62,6 @@ class SourceFilterController : SettingsController() {
|
||||
sourcesByLang.keys.filterNot { it in activeLangsCodes }
|
||||
|
||||
orderedLangs.forEach { lang ->
|
||||
val sources = sourcesByLang[lang].orEmpty().sortedBy { it.name }
|
||||
|
||||
// Create a preference group and set initial state and change listener
|
||||
langPrefs.add(
|
||||
Pair(
|
||||
|
@ -7,6 +7,7 @@ import android.widget.AutoCompleteTextView
|
||||
import android.widget.TextView
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
@ -16,7 +17,6 @@ import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.widget.AutoCompleteAdapter
|
||||
import timber.log.Timber
|
||||
|
||||
open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem<AutoComplete.Holder>() {
|
||||
|
||||
@ -43,8 +43,6 @@ open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem<
|
||||
)
|
||||
holder.autoComplete.threshold = 3
|
||||
|
||||
var text: String = ""
|
||||
|
||||
// select from auto complete
|
||||
holder.autoComplete.setOnItemClickListener { adapterView, _, chipPosition, _ ->
|
||||
val name = adapterView.getItemAtPosition(chipPosition) as String
|
||||
@ -55,7 +53,7 @@ open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem<
|
||||
}
|
||||
|
||||
// done keyboard button is pressed
|
||||
holder.autoComplete.setOnEditorActionListener { textView, actionId, keyEvent ->
|
||||
holder.autoComplete.setOnEditorActionListener { textView, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE && textView.text.toString() !in if (filter.excludePrefix != null && textView.text.toString().startsWith(filter.excludePrefix)) filter.skipAutoFillTags.map { filter.excludePrefix + it } else filter.skipAutoFillTags) {
|
||||
textView.text = null
|
||||
addTag(textView.text.toString(), holder)
|
||||
@ -69,14 +67,12 @@ open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem<
|
||||
if (it == null || it.isEmpty()) {
|
||||
return@addTextChangedListener
|
||||
}
|
||||
text = it.toString()
|
||||
|
||||
if (it.last() == ',') {
|
||||
val name = it.substring(0, it.length - 1)
|
||||
addTag(name, holder)
|
||||
|
||||
holder.autoComplete.text = null
|
||||
// mainTagAutoCompleteTextView.removeTextChangedListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,7 +97,7 @@ open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem<
|
||||
addChipToGroup(name, holder)
|
||||
filter.state += name
|
||||
} else {
|
||||
Timber.d("Invalid tag: $name")
|
||||
XLog.d("Invalid tag: $name")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,7 +455,7 @@ class LibraryPresenter(
|
||||
mangas.forEach { manga ->
|
||||
launchIO {
|
||||
/* SY --> */ val chapters = if (manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID) {
|
||||
val chapter = db.getChapters(manga).executeAsBlocking().minBy { it.source_order }
|
||||
val chapter = db.getChapters(manga).executeAsBlocking().minByOrNull { it.source_order }
|
||||
if (chapter != null && !chapter.read) listOf(chapter) else emptyList()
|
||||
} else /* SY <-- */ db.getChapters(manga).executeAsBlocking()
|
||||
.filter { !it.read }
|
||||
|
@ -54,7 +54,7 @@ class EHentaiUpdateHelper(context: Context) {
|
||||
|
||||
// Accept oldest chain
|
||||
val chainsWithAccepted = chainsObservable.map { chains ->
|
||||
val acceptedChain = chains.minBy { it.manga.id!! }!!
|
||||
val acceptedChain = chains.minByOrNull { it.manga.id!! }!!
|
||||
|
||||
acceptedChain to chains
|
||||
}
|
||||
@ -91,7 +91,7 @@ class EHentaiUpdateHelper(context: Context) {
|
||||
.fold(accepted.chapters) { curChapters, chapter ->
|
||||
val existing = curChapters.find { it.url == chapter.url }
|
||||
|
||||
val newLastPageRead = chainsAsChapters.maxBy { it.last_page_read }?.last_page_read
|
||||
val newLastPageRead = chainsAsChapters.maxByOrNull { it.last_page_read }?.last_page_read
|
||||
|
||||
when {
|
||||
existing != null -> {
|
||||
|
@ -151,7 +151,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
val chapter = db.getChaptersByMangaId(manga.id!!).asRxSingle().await().minBy {
|
||||
val chapter = db.getChaptersByMangaId(manga.id!!).asRxSingle().await().minByOrNull {
|
||||
it.date_upload
|
||||
}
|
||||
|
||||
|
@ -7,21 +7,15 @@ import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.util.await
|
||||
import info.debatty.java.stringsimilarity.NormalizedLevenshtein
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import rx.schedulers.Schedulers
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class SmartSearchEngine(
|
||||
parentContext: CoroutineContext,
|
||||
private val extraSearchParams: String? = null
|
||||
) : CoroutineScope {
|
||||
override val coroutineContext: CoroutineContext = parentContext + Job() + Dispatchers.Default
|
||||
|
||||
) {
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
|
||||
private val normalizedLevenshtein = NormalizedLevenshtein()
|
||||
@ -52,7 +46,7 @@ class SmartSearchEngine(
|
||||
}.flatMap { it.await() }
|
||||
}
|
||||
|
||||
return eligibleManga.maxBy { it.dist }?.manga
|
||||
return eligibleManga.maxByOrNull { it.dist }?.manga
|
||||
}
|
||||
|
||||
suspend fun normalSearch(source: CatalogueSource, title: String): SManga? {
|
||||
@ -74,7 +68,7 @@ class SmartSearchEngine(
|
||||
}
|
||||
}
|
||||
|
||||
return eligibleManga.maxBy { it.dist }?.manga
|
||||
return eligibleManga.maxByOrNull { it.dist }?.manga
|
||||
}
|
||||
|
||||
private fun getSmartSearchQueries(cleanedTitle: String): List<String> {
|
||||
|
@ -21,7 +21,7 @@ class SmartSearchPresenter(private val source: CatalogueSource?, private val con
|
||||
|
||||
val smartSearchChannel = Channel<SearchResults>()
|
||||
|
||||
private val smartSearchEngine = SmartSearchEngine(scope.coroutineContext)
|
||||
private val smartSearchEngine = SmartSearchEngine()
|
||||
|
||||
override fun onCreate(savedState: Bundle?) {
|
||||
super.onCreate(savedState)
|
||||
|
@ -3,7 +3,7 @@ package exh.util
|
||||
import com.elvishew.xlog.XLog
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
import org.jsoup.nodes.Document
|
||||
|
||||
fun Response.interceptAsHtml(block: (Document) -> Unit): Response {
|
||||
@ -13,7 +13,7 @@ fun Response.interceptAsHtml(block: (Document) -> Unit): Response {
|
||||
) {
|
||||
val bodyString = body.string()
|
||||
val rebuiltResponse = newBuilder()
|
||||
.body(ResponseBody.create(body.contentType(), bodyString))
|
||||
.body(bodyString.toResponseBody(body.contentType()))
|
||||
.build()
|
||||
try {
|
||||
// Search for captcha
|
||||
|
Loading…
x
Reference in New Issue
Block a user