Merged source stop ddos
(cherry picked from commit 0c7ceb059e24ec6711b9d2ecec1296d56f120c7b)
This commit is contained in:
parent
b3baaa18d2
commit
505a8288be
@ -21,11 +21,12 @@ import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
|||||||
import exh.log.xLogW
|
import exh.log.xLogW
|
||||||
import exh.merged.sql.models.MergedMangaReference
|
import exh.merged.sql.models.MergedMangaReference
|
||||||
import exh.source.MERGED_SOURCE_ID
|
import exh.source.MERGED_SOURCE_ID
|
||||||
import exh.util.executeOnIO
|
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.supervisorScope
|
import kotlinx.coroutines.supervisorScope
|
||||||
|
import kotlinx.coroutines.sync.Semaphore
|
||||||
|
import kotlinx.coroutines.sync.withPermit
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import tachiyomi.source.model.ChapterInfo
|
import tachiyomi.source.model.ChapterInfo
|
||||||
@ -63,18 +64,27 @@ class MergedSource : HttpSource() {
|
|||||||
|
|
||||||
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
|
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val mergedManga = db.getManga(manga.key, id).executeAsBlocking() ?: throw Exception("merged manga not in db")
|
val mergedManga = db.getManga(manga.key, id).executeAsBlocking()
|
||||||
val mangaReferences = db.getMergedMangaReferences(mergedManga.id ?: throw Exception("merged manga id is null")).executeOnIO()
|
?: throw Exception("merged manga not in db")
|
||||||
if (mangaReferences.isEmpty()) throw IllegalArgumentException("Manga references are empty, info unavailable, merge is likely corrupted")
|
val mangaReferences = db.getMergedMangaReferences(mergedManga.id!!).executeAsBlocking()
|
||||||
if (mangaReferences.size == 1 &&
|
.apply {
|
||||||
run {
|
if (isEmpty()) {
|
||||||
val mangaReference = mangaReferences.firstOrNull()
|
throw IllegalArgumentException(
|
||||||
mangaReference == null || mangaReference.mangaSourceId == MERGED_SOURCE_ID
|
"Manga references are empty, info unavailable, merge is likely corrupted"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (size == 1 && first().mangaSourceId == MERGED_SOURCE_ID) {
|
||||||
|
throw IllegalArgumentException(
|
||||||
|
"Manga references contain only the merged reference, merge is likely corrupted"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
) throw IllegalArgumentException("Manga references contain only the merged reference, merge is likely corrupted")
|
|
||||||
|
|
||||||
val mangaInfoReference = mangaReferences.firstOrNull { it.isInfoManga } ?: mangaReferences.firstOrNull { it.mangaId != it.mergeId }
|
val mangaInfoReference = mangaReferences.firstOrNull { it.isInfoManga }
|
||||||
val dbManga = mangaInfoReference?.let { db.getManga(it.mangaUrl, it.mangaSourceId).executeOnIO()?.toMangaInfo() }
|
?: mangaReferences.firstOrNull { it.mangaId != it.mergeId }
|
||||||
|
val dbManga = mangaInfoReference?.run {
|
||||||
|
db.getManga(mangaUrl, mangaSourceId).executeAsBlocking()?.toMangaInfo()
|
||||||
|
}
|
||||||
(dbManga ?: mergedManga.toMangaInfo()).copy(
|
(dbManga ?: mergedManga.toMangaInfo()).copy(
|
||||||
key = manga.key,
|
key = manga.key,
|
||||||
)
|
)
|
||||||
@ -143,21 +153,27 @@ class MergedSource : HttpSource() {
|
|||||||
|
|
||||||
suspend fun fetchChaptersAndSync(manga: Manga, downloadChapters: Boolean = true): Pair<List<Chapter>, List<Chapter>> {
|
suspend fun fetchChaptersAndSync(manga: Manga, downloadChapters: Boolean = true): Pair<List<Chapter>, List<Chapter>> {
|
||||||
val mangaReferences = db.getMergedMangaReferences(manga.id!!).executeAsBlocking()
|
val mangaReferences = db.getMergedMangaReferences(manga.id!!).executeAsBlocking()
|
||||||
if (mangaReferences.isEmpty()) throw IllegalArgumentException("Manga references are empty, chapters unavailable, merge is likely corrupted")
|
if (mangaReferences.isEmpty()) {
|
||||||
|
throw IllegalArgumentException("Manga references are empty, chapters unavailable, merge is likely corrupted")
|
||||||
|
}
|
||||||
|
|
||||||
val ifDownloadNewChapters = downloadChapters && manga.shouldDownloadNewChapters(db, preferences)
|
val ifDownloadNewChapters = downloadChapters && manga.shouldDownloadNewChapters(db, preferences)
|
||||||
|
val semaphore = Semaphore(5)
|
||||||
var exception: Exception? = null
|
var exception: Exception? = null
|
||||||
return supervisorScope {
|
return supervisorScope {
|
||||||
mangaReferences
|
mangaReferences
|
||||||
.map {
|
.groupBy(MergedMangaReference::mangaSourceId)
|
||||||
|
.minus(MERGED_SOURCE_ID)
|
||||||
|
.map { (_, values) ->
|
||||||
async {
|
async {
|
||||||
|
semaphore.withPermit {
|
||||||
|
values.map {
|
||||||
try {
|
try {
|
||||||
if (it.mangaSourceId == MERGED_SOURCE_ID) return@async null
|
|
||||||
val (source, loadedManga, reference) =
|
val (source, loadedManga, reference) =
|
||||||
it.load(db, sourceManager)
|
it.load(db, sourceManager)
|
||||||
if (loadedManga != null && reference.getChapterUpdates) {
|
if (loadedManga != null && reference.getChapterUpdates) {
|
||||||
val chapterList = source.getChapterList(loadedManga.toMangaInfo())
|
val chapterList = source.getChapterList(loadedManga.toMangaInfo())
|
||||||
.map { it.toSChapter() }
|
.map(ChapterInfo::toSChapter)
|
||||||
val results =
|
val results =
|
||||||
syncChaptersWithSource(db, chapterList, loadedManga, source)
|
syncChaptersWithSource(db, chapterList, loadedManga, source)
|
||||||
if (ifDownloadNewChapters && reference.downloadChapters) {
|
if (ifDownloadNewChapters && reference.downloadChapters) {
|
||||||
@ -177,7 +193,10 @@ class MergedSource : HttpSource() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.awaitAll()
|
.awaitAll()
|
||||||
|
.flatten()
|
||||||
.let { pairs ->
|
.let { pairs ->
|
||||||
pairs.flatMap { it?.first.orEmpty() } to pairs.flatMap { it?.second.orEmpty() }
|
pairs.flatMap { it?.first.orEmpty() } to pairs.flatMap { it?.second.orEmpty() }
|
||||||
}
|
}
|
||||||
@ -187,7 +206,7 @@ class MergedSource : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun MergedMangaReference.load(db: DatabaseHelper, sourceManager: SourceManager): LoadedMangaSource {
|
suspend fun MergedMangaReference.load(db: DatabaseHelper, sourceManager: SourceManager): LoadedMangaSource {
|
||||||
var manga = db.getManga(mangaUrl, mangaSourceId).executeOnIO()
|
var manga = db.getManga(mangaUrl, mangaSourceId).executeAsBlocking()
|
||||||
val source = sourceManager.getOrStub(manga?.source ?: mangaSourceId)
|
val source = sourceManager.getOrStub(manga?.source ?: mangaSourceId)
|
||||||
if (manga == null) {
|
if (manga == null) {
|
||||||
manga = Manga.create(mangaSourceId).apply {
|
manga = Manga.create(mangaSourceId).apply {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user