Remove 1.x source models (#7781)

(cherry picked from commit e36e9d9d5c1b2a7b55f28f2bf0ef064880cbac8f)

# Conflicts:
#	app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt
#	app/src/main/java/eu/kanade/domain/manga/model/Manga.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/Source.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
This commit is contained in:
stevenyomi 2022-08-19 02:07:13 +08:00 committed by Jobobby04
parent fff031cf1c
commit 39e0d7f4e8
58 changed files with 414 additions and 509 deletions

View File

@ -160,9 +160,6 @@ dependencies {
implementation(kotlinx.reflect)
implementation(kotlinx.bundles.coroutines)
// Source models and interfaces from Tachiyomi 1.x
implementation(libs.tachiyomi.api)
// AndroidX libraries
implementation(androidx.annotation)
implementation(androidx.appcompat)

View File

@ -2,7 +2,6 @@ package eu.kanade.domain.manga.interactor
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.PagePreview
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.data.cache.PagePreviewCache
import eu.kanade.tachiyomi.source.PagePreviewSource
import eu.kanade.tachiyomi.source.Source
@ -19,7 +18,7 @@ class GetPagePreviews(
val pagePreviews = try {
pagePreviewCache.getPageListFromCache(manga, page)
} catch (e: Exception) {
source.getPagePreviewList(manga.toMangaInfo(), page).also {
source.getPagePreviewList(manga.toSManga(), page).also {
pagePreviewCache.putPageListToCache(manga, it)
}
}

View File

@ -8,7 +8,7 @@ import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.download.DownloadManager
import tachiyomi.source.model.MangaInfo
import eu.kanade.tachiyomi.source.model.SManga
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
@ -27,7 +27,7 @@ class UpdateManga(
suspend fun awaitUpdateFromSource(
localManga: Manga,
remoteManga: MangaInfo,
remoteManga: SManga,
manualFetch: Boolean,
coverCache: CoverCache = Injekt.get(),
// SY -->
@ -41,10 +41,11 @@ class UpdateManga(
} else null
// SY <--
// Never refresh covers if the url is empty to avoid "losing" existing covers
val updateCover = remoteManga.cover.isNotEmpty() && (manualFetch || localManga.thumbnailUrl != remoteManga.cover)
val coverLastModified = if (updateCover) {
val coverLastModified =
when {
// Never refresh covers if the url is empty to avoid "losing" existing covers
remoteManga.thumbnail_url.isNullOrEmpty() -> null
!manualFetch && localManga.thumbnailUrl == remoteManga.thumbnail_url -> null
localManga.isLocal() -> Date().time
localManga.hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(localManga.toDbManga(), false)
@ -55,7 +56,6 @@ class UpdateManga(
Date().time
}
}
} else null
return mangaRepository.update(
MangaUpdate(
@ -65,8 +65,8 @@ class UpdateManga(
author = remoteManga.author,
artist = remoteManga.artist,
description = remoteManga.description,
genre = remoteManga.genres,
thumbnailUrl = remoteManga.cover.takeIf { it.isNotEmpty() },
genre = remoteManga.getGenres(),
thumbnailUrl = remoteManga.thumbnail_url?.takeIf { it.isNotEmpty() },
status = remoteManga.status.toLong(),
initialized = true,
),

View File

@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@ -119,12 +118,14 @@ data class Manga(
fun toSManga(): SManga = SManga.create().also {
it.url = url
it.title = title
it.artist = artist
it.author = author
it.description = description
it.genre = genre.orEmpty().joinToString()
it.status = status.toInt()
// SY -->
it.title = ogTitle
it.artist = ogArtist
it.author = ogAuthor
it.description = ogDescription
it.genre = ogGenre.orEmpty().joinToString()
it.status = ogStatus.toInt()
// SY <--
it.thumbnail_url = thumbnailUrl
it.initialized = initialized
}
@ -228,19 +229,6 @@ fun Manga.toDbManga(): DbManga = MangaImpl().also {
it.initialized = initialized
}
fun Manga.toMangaInfo(): MangaInfo = MangaInfo(
// SY -->
artist = ogArtist ?: "",
author = ogAuthor ?: "",
cover = thumbnailUrl ?: "",
description = ogDescription ?: "",
genres = ogGenre ?: emptyList(),
key = url,
status = ogStatus.toInt(),
title = ogTitle,
// SY <--
)
fun Manga.toMangaUpdate(): MangaUpdate {
return MangaUpdate(
id = id,
@ -252,12 +240,14 @@ fun Manga.toMangaUpdate(): MangaUpdate {
chapterFlags = chapterFlags,
coverLastModified = coverLastModified,
url = url,
title = title,
artist = artist,
author = author,
description = description,
genre = genre,
status = status,
// SY -->
title = ogTitle,
artist = ogArtist,
author = ogAuthor,
description = ogDescription,
genre = ogGenre,
status = ogStatus,
// SY <--
thumbnailUrl = thumbnailUrl,
initialized = initialized,
)

View File

@ -24,6 +24,7 @@ import androidx.compose.ui.unit.dp
import com.google.accompanist.flowlayout.FlowRow
import eu.kanade.presentation.components.SuggestionChip
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.online.all.EHentai
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.base.RaisedSearchMetadata
@ -31,7 +32,6 @@ import exh.metadata.metadata.base.RaisedTag
import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID
import exh.util.SourceTagsUtil
import tachiyomi.source.Source
@Immutable
data class DisplayTag(

View File

@ -4,7 +4,6 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import exh.md.utils.MdUtil
import tachiyomi.source.model.MangaInfo
import eu.kanade.domain.manga.model.Manga as DomainManga
interface Manga : SManga {
@ -84,19 +83,6 @@ interface Manga : SManga {
}
}
fun Manga.toMangaInfo(): MangaInfo {
return MangaInfo(
artist = this.artist ?: "",
author = this.author ?: "",
cover = this.thumbnail_url ?: "",
description = this.description ?: "",
genres = this.getGenres() ?: emptyList(),
key = this.url,
status = this.status,
title = this.title,
)
}
fun Manga.toDomainManga(): DomainManga? {
val mangaId = id ?: return null
return DomainManga(

View File

@ -21,7 +21,6 @@ import eu.kanade.domain.manga.interactor.InsertFlatMetadata
import eu.kanade.domain.manga.interactor.InsertManga
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.domain.manga.model.toMangaUpdate
import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack
@ -34,7 +33,6 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainChapter
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
@ -51,9 +49,6 @@ import eu.kanade.tachiyomi.data.track.TrackStatus
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.ui.library.LibraryGroup
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
@ -88,7 +83,6 @@ import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import logcat.LogPriority
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File
@ -532,12 +526,10 @@ class LibraryUpdateService(
private suspend fun updateManga(manga: DomainManga, loggedServices: List<TrackService>): List<DomainChapter> {
val source = sourceManager.getOrStub(manga.source)
val mangaInfo: MangaInfo = manga.toMangaInfo()
// Update manga metadata if needed
if (preferences.autoUpdateMetadata()) {
val updatedMangaInfo = source.getMangaDetails(manga.toMangaInfo())
updateManga.awaitUpdateFromSource(manga, updatedMangaInfo, manualFetch = false, coverCache)
val networkManga = source.getMangaDetails(manga.toSManga())
updateManga.awaitUpdateFromSource(manga, networkManga, manualFetch = false, coverCache)
}
// SY -->
@ -559,8 +551,7 @@ class LibraryUpdateService(
}
// SY <--
val chapters = source.getChapterList(mangaInfo)
.map { it.toSChapter() }
val chapters = source.getChapterList(manga.toSManga())
// Get manga from database to account for if it was removed during the update
val dbManga = getManga.await(manga.id)
@ -592,27 +583,19 @@ class LibraryUpdateService(
progressCount,
manga,
) { mangaWithNotif ->
sourceManager.get(mangaWithNotif.source)?.let { source ->
val source = sourceManager.get(mangaWithNotif.source) ?: return@withUpdateNotification
try {
val networkManga = source.getMangaDetails(mangaWithNotif.copy())
mangaWithNotif.prepUpdateCover(coverCache, networkManga, true)
mangaWithNotif.copyFrom(networkManga)
try {
val networkManga =
source.getMangaDetails(mangaWithNotif.toMangaInfo())
val sManga = networkManga.toSManga()
mangaWithNotif.prepUpdateCover(coverCache, sManga, true)
sManga.thumbnail_url?.let {
mangaWithNotif.thumbnail_url = it
try {
updateManga.await(
mangaWithNotif.toDomainManga()!!
.toMangaUpdate(),
)
} catch (e: Exception) {
logcat(LogPriority.ERROR) { "Manga don't exist anymore" }
}
}
} catch (e: Throwable) {
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
updateManga.await(mangaWithNotif.toDomainManga()!!.toMangaUpdate())
} catch (e: Exception) {
logcat(LogPriority.ERROR) { "Manga doesn't exist anymore" }
}
} catch (e: Throwable) {
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
}
}
}
@ -697,7 +680,7 @@ class LibraryUpdateService(
}
updatingManga.remove(manga)
completed.andIncrement
completed.getAndIncrement()
notifier.showProgressNotification(
updatingManga,
completed.get(),
@ -748,7 +731,7 @@ class LibraryUpdateService(
updateManga.awaitUpdateFavorite(dbManga.id, true)
}
updateManga.awaitUpdateFromSource(dbManga, networkManga.toMangaInfo(), true)
updateManga.awaitUpdateFromSource(dbManga, networkManga, true)
metadata.mangaId = dbManga.id
insertFlatMetadata.await(metadata)
}

View File

@ -10,13 +10,12 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.lang.awaitSingle
import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.utils.FollowStatus
import exh.md.utils.MdUtil
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -134,7 +133,7 @@ class MdList(private val context: Context, id: Long) : TrackService(id) {
.flatMap { page ->
runAsObservable {
page.mangas.map {
toTrackSearch(mdex.getMangaDetails(it.toMangaInfo()))
toTrackSearch(mdex.getMangaDetails(it))
}
}
}
@ -142,11 +141,11 @@ class MdList(private val context: Context, id: Long) : TrackService(id) {
}
}
private fun toTrackSearch(mangaInfo: MangaInfo): TrackSearch = TrackSearch.create(TrackManager.MDLIST).apply {
tracking_url = MdUtil.baseUrl + mangaInfo.key
private fun toTrackSearch(mangaInfo: SManga): TrackSearch = TrackSearch.create(TrackManager.MDLIST).apply {
tracking_url = MdUtil.baseUrl + mangaInfo.url
title = mangaInfo.title
cover_url = mangaInfo.cover
summary = mangaInfo.description
cover_url = mangaInfo.thumbnail_url.orEmpty()
summary = mangaInfo.description.orEmpty()
}
override suspend fun login(username: String, password: String): Unit = throw Exception("not used")

View File

@ -10,10 +10,6 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toChapterInfo
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.util.chapter.ChapterRecognition
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
import eu.kanade.tachiyomi.util.storage.DiskUtil
@ -27,8 +23,6 @@ import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import logcat.LogPriority
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.io.FileInputStream
@ -125,11 +119,10 @@ class LocalSource(
// Fetch chapters of all the manga
mangas.forEach { manga ->
val mangaInfo = manga.toMangaInfo()
runBlocking {
val chapters = getChapterList(mangaInfo)
val chapters = getChapterList(manga)
if (chapters.isNotEmpty()) {
val chapter = chapters.last().toSChapter()
val chapter = chapters.last()
val format = getFormat(chapter)
if (format is Format.Epub) {
@ -161,12 +154,37 @@ class LocalSource(
}
}
private fun SManga.toJson(): MangaJson {
return MangaJson(title, author, artist, description, genre?.split(", "), status)
private fun SManga.toJson(): MangaDetails {
return MangaDetails(title, author, artist, description, genre?.split(", "), status)
}
// SY <--
// Manga details related
override suspend fun getMangaDetails(manga: SManga): SManga {
val baseDirsFile = getBaseDirectoriesFiles(context)
getCoverFile(manga.url, baseDirsFile)?.let {
manga.thumbnail_url = it.absolutePath
}
getMangaDirsFiles(manga.url, baseDirsFile)
.firstOrNull { it.extension.equals("json", ignoreCase = true) }
?.let { file ->
json.decodeFromStream<MangaDetails>(file.inputStream()).run {
title?.let { manga.title = it }
author?.let { manga.author = it }
artist?.let { manga.artist = it }
description?.let { manga.description = it }
genre?.let { manga.genre = it.joinToString() }
status?.let { manga.status = it }
}
}
return manga
}
@Serializable
data class MangaJson(
data class MangaDetails(
val title: String? = null,
val author: String? = null,
val artist: String? = null,
@ -174,50 +192,16 @@ class LocalSource(
val genre: List<String>? = null,
val status: Int? = null,
)
// SY <--
// Manga details related
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
var mangaInfo = manga
val baseDirsFile = getBaseDirectoriesFiles(context)
val coverFile = getCoverFile(manga.key, baseDirsFile)
coverFile?.let {
mangaInfo = mangaInfo.copy(cover = it.absolutePath)
}
val localDetails = getMangaDirsFiles(manga.key, baseDirsFile)
.firstOrNull { it.extension.equals("json", ignoreCase = true) }
if (localDetails != null) {
val mangaJson = json.decodeFromStream<MangaJson>(localDetails.inputStream())
mangaInfo = mangaInfo.copy(
title = mangaJson.title ?: mangaInfo.title,
author = mangaJson.author ?: mangaInfo.author,
artist = mangaJson.artist ?: mangaInfo.artist,
description = mangaJson.description ?: mangaInfo.description,
genres = mangaJson.genre ?: mangaInfo.genres,
status = mangaJson.status ?: mangaInfo.status,
)
}
return mangaInfo
}
// Chapters
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
val sManga = manga.toSManga()
override suspend fun getChapterList(manga: SManga): List<SChapter> {
val baseDirsFile = getBaseDirectoriesFiles(context)
return getMangaDirsFiles(manga.key, baseDirsFile)
return getMangaDirsFiles(manga.url, baseDirsFile)
// Only keep supported formats
.filter { it.isDirectory || isSupportedFile(it.extension) }
.map { chapterFile ->
SChapter.create().apply {
url = "${manga.key}/${chapterFile.name}"
url = "${manga.url}/${chapterFile.name}"
name = if (chapterFile.isDirectory) {
chapterFile.name
} else {
@ -225,7 +209,7 @@ class LocalSource(
}
date_upload = chapterFile.lastModified()
chapter_number = ChapterRecognition.parseChapterNumber(sManga.title, this.name, this.chapter_number)
chapter_number = ChapterRecognition.parseChapterNumber(manga.title, this.name, this.chapter_number)
val format = getFormat(chapterFile)
if (format is Format.Epub) {
@ -235,9 +219,8 @@ class LocalSource(
}
}
}
.map { it.toChapterInfo() }
.sortedWith { c1, c2 ->
val c = c2.number.compareTo(c1.number)
val c = c2.chapter_number.compareTo(c1.chapter_number)
if (c == 0) c2.name.compareToCaseInsensitiveNaturalOrder(c1.name) else c
}
.toList()
@ -256,7 +239,7 @@ class LocalSource(
)
// Unused stuff
override suspend fun getPageList(chapter: ChapterInfo) = throw UnsupportedOperationException("Unused")
override suspend fun getPageList(chapter: SChapter) = throw UnsupportedOperationException("Unused")
// Miscellaneous
private fun isSupportedFile(extension: String): Boolean {

View File

@ -1,17 +1,17 @@
package eu.kanade.tachiyomi.source
import eu.kanade.tachiyomi.network.ProgressListener
import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import okhttp3.CacheControl
import okhttp3.Response
import tachiyomi.source.model.MangaInfo
interface PagePreviewSource : Source {
suspend fun getPagePreviewList(manga: MangaInfo, page: Int): PagePreviewPage
suspend fun getPagePreviewList(manga: SManga, page: Int): PagePreviewPage
suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl? = null): Response
}

View File

@ -7,35 +7,28 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toChapterInfo
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toPageUrl
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.manga.MergedMangaData
import eu.kanade.tachiyomi.util.lang.awaitSingle
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/**
* A basic interface for creating a source. It could be an online source, a local source, etc...
*/
interface Source : tachiyomi.source.Source {
interface Source {
/**
* Id for the source. Must be unique.
*/
override val id: Long
val id: Long
/**
* Name of the source.
*/
override val name: String
val name: String
override val lang: String
val lang: String
get() = ""
/**
@ -76,29 +69,24 @@ interface Source : tachiyomi.source.Source {
* [1.x API] Get the updated details for a manga.
*/
@Suppress("DEPRECATION")
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val sManga = manga.toSManga()
val networkManga = fetchMangaDetails(sManga).awaitSingle()
sManga.copyFrom(networkManga)
return sManga.toMangaInfo()
suspend fun getMangaDetails(manga: SManga): SManga {
return fetchMangaDetails(manga).awaitSingle()
}
/**
* [1.x API] Get all the available chapters for a manga.
*/
@Suppress("DEPRECATION")
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
return fetchChapterList(manga.toSManga()).awaitSingle()
.map { it.toChapterInfo() }
suspend fun getChapterList(manga: SManga): List<SChapter> {
return fetchChapterList(manga).awaitSingle()
}
/**
* [1.x API] Get the list of pages a chapter has.
*/
@Suppress("DEPRECATION")
override suspend fun getPageList(chapter: ChapterInfo): List<tachiyomi.source.model.Page> {
return fetchPageList(chapter.toSChapter()).awaitSingle()
.map { it.toPageUrl() }
suspend fun getPageList(chapter: SChapter): List<Page> {
return fetchPageList(chapter).awaitSingle()
}
}

View File

@ -45,8 +45,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.injectLazy
import kotlin.reflect.KClass
@ -208,7 +206,7 @@ class SourceManager(
override val lang: String = sourceData.lang
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
override suspend fun getMangaDetails(manga: SManga): SManga {
throw getSourceNotInstalledException()
}
@ -216,7 +214,7 @@ class SourceManager(
return Observable.error(getSourceNotInstalledException())
}
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
override suspend fun getChapterList(manga: SManga): List<SChapter> {
throw getSourceNotInstalledException()
}
@ -224,7 +222,7 @@ class SourceManager(
return Observable.error(getSourceNotInstalledException())
}
override suspend fun getPageList(chapter: ChapterInfo): List<tachiyomi.source.model.Page> {
override suspend fun getPageList(chapter: SChapter): List<Page> {
throw getSourceNotInstalledException()
}

View File

@ -5,7 +5,6 @@ import eu.kanade.tachiyomi.network.ProgressListener
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import rx.subjects.Subject
import tachiyomi.source.model.PageUrl
@Serializable
open class Page(
@ -66,16 +65,3 @@ open class Page(
const val ERROR = 4
}
}
fun Page.toPageUrl(): PageUrl {
return PageUrl(
url = this.imageUrl ?: this.url,
)
}
fun PageUrl.toPage(index: Int): Page {
return Page(
index = index,
imageUrl = this.url,
)
}

View File

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.source.model
import data.Chapters
import tachiyomi.source.model.ChapterInfo
import java.io.Serializable
interface SChapter : Serializable {
@ -36,26 +35,23 @@ interface SChapter : Serializable {
fun create(): SChapter {
return SChapterImpl()
}
}
}
fun SChapter.toChapterInfo(): ChapterInfo {
return ChapterInfo(
dateUpload = this.date_upload,
key = this.url,
name = this.name,
number = this.chapter_number,
scanlator = this.scanlator ?: "",
)
}
fun ChapterInfo.toSChapter(): SChapter {
val chapter = this
return SChapter.create().apply {
url = chapter.key
name = chapter.name
date_upload = chapter.dateUpload
chapter_number = chapter.number
scanlator = chapter.scanlator
// SY -->
operator fun invoke(
name: String,
url: String,
date_upload: Long = 0,
chapter_number: Float = -1F,
scanlator: String? = null,
): SChapter {
return create().apply {
this.name = name
this.url = url
this.date_upload = date_upload
this.chapter_number = chapter_number
this.scanlator = scanlator
}
}
// SY <--
}
}

View File

@ -4,7 +4,6 @@ import data.Mangas
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.download.DownloadManager
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.Serializable
@ -127,6 +126,20 @@ interface SManga : Serializable {
}
}
fun copy() = create().also {
it.url = url
// SY -->
it.title = originalTitle
it.artist = originalArtist
it.author = originalAuthor
it.description = originalDescription
it.genre = originalGenre
it.status = originalStatus
// SY <--
it.thumbnail_url = thumbnail_url
it.initialized = initialized
}
companion object {
const val UNKNOWN = 0
const val ONGOING = 1
@ -139,32 +152,55 @@ interface SManga : Serializable {
fun create(): SManga {
return SMangaImpl()
}
// SY -->
operator fun invoke(
url: String,
title: String,
artist: String? = null,
author: String? = null,
description: String? = null,
genre: String? = null,
status: Int = 0,
thumbnail_url: String? = null,
initialized: Boolean = false,
): SManga {
return create().also {
it.url = url
it.title = title
it.artist = artist
it.author = author
it.description = description
it.genre = genre
it.status = status
it.thumbnail_url = thumbnail_url
it.initialized = initialized
}
}
// SY <--
}
}
fun SManga.toMangaInfo(): MangaInfo {
return MangaInfo(
key = this.url,
title = this.title,
artist = this.artist ?: "",
author = this.author ?: "",
description = this.description ?: "",
genres = this.getGenres() ?: emptyList(),
status = this.status,
cover = this.thumbnail_url ?: "",
)
}
fun MangaInfo.toSManga(): SManga {
val mangaInfo = this
return SManga.create().apply {
url = mangaInfo.key
title = mangaInfo.title
artist = mangaInfo.artist
author = mangaInfo.author
description = mangaInfo.description
genre = mangaInfo.genres.joinToString(", ")
status = mangaInfo.status
thumbnail_url = mangaInfo.cover
}
// SY -->
fun SManga.copy(
url: String = this.url,
title: String = this.originalTitle,
artist: String? = this.originalArtist,
author: String? = this.originalAuthor,
description: String? = this.originalDescription,
genre: String? = this.originalGenre,
status: Int = this.status,
thumbnail_url: String? = this.thumbnail_url,
initialized: Boolean = this.initialized,
) = SManga.create().also {
it.url = url
it.title = title
it.artist = artist
it.author = author
it.description = description
it.genre = genre
it.status = status
it.thumbnail_url = thumbnail_url
it.initialized = initialized
}
// SY <--

View File

@ -6,14 +6,12 @@ import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.InsertFlatMetadata
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
import eu.kanade.tachiyomi.util.lang.awaitSingle
import eu.kanade.tachiyomi.util.lang.runAsObservable
import exh.metadata.metadata.base.RaisedSearchMetadata
import rx.Completable
import rx.Single
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.reflect.KClass
@ -51,11 +49,11 @@ interface MetadataSource<M : RaisedSearchMetadata, I> : CatalogueSource {
*/
@Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated("Use the MangaInfo variant")
fun parseToManga(manga: SManga, input: I): Completable = runAsObservable {
parseToManga(manga.toMangaInfo(), input)
fun parseToMangaCompletable(manga: SManga, input: I): Completable = runAsObservable {
parseToManga(manga, input)
}.toCompletable()
suspend fun parseToManga(manga: MangaInfo, input: I): MangaInfo {
suspend fun parseToManga(manga: SManga, input: I): SManga {
val mangaId = manga.id()
val metadata = if (mangaId != null) {
val flatMetadata = getFlatMetadataById.await(mangaId)
@ -114,5 +112,5 @@ interface MetadataSource<M : RaisedSearchMetadata, I> : CatalogueSource {
@Composable
fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit)
suspend fun MangaInfo.id() = getManga.await(key, id)?.id
suspend fun SManga.id() = getManga.await(url, id)?.id
}

View File

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.source.online
import tachiyomi.source.Source
import eu.kanade.tachiyomi.source.Source
interface RandomMangaSource : Source {
suspend fun fetchRandomMangaUrl(): String

View File

@ -23,9 +23,7 @@ import eu.kanade.tachiyomi.source.model.MetadataMangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.copy
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -92,8 +90,6 @@ import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.nodes.TextNode
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.injectLazy
import java.io.ByteArrayOutputStream
import java.io.IOException
@ -306,13 +302,13 @@ class EHentai(
MetadataMangasPage(mangaFromSource.first.map { it.manga }, mangaFromSource.second, mangaFromSource.first.map { it.metadata })
}
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> = getChapterList(manga) {}
override suspend fun getChapterList(manga: SManga): List<SChapter> = getChapterList(manga) {}
suspend fun getChapterList(manga: MangaInfo, throttleFunc: suspend () -> Unit): List<ChapterInfo> {
suspend fun getChapterList(manga: SManga, throttleFunc: suspend () -> Unit): List<SChapter> {
// Pull all the way to the root gallery
// We can't do this with RxJava or we run into stack overflows on shit like this:
// https://exhentai.org/g/1073061/f9345f1c12/
var url = manga.key
var url = manga.url
var doc: Document
while (true) {
@ -348,11 +344,11 @@ class EHentai(
}
val newDisplay = doc.select("#gnd a")
// Build chapter for root gallery
val self = ChapterInfo(
key = EHentaiSearchMetadata.normalizeUrl(doc.location()),
val self = SChapter(
url = EHentaiSearchMetadata.normalizeUrl(doc.location()),
name = "v1: " + doc.selectFirst("#gn")!!.text(),
number = 1f,
dateUpload = MetadataUtil.EX_DATE_FORMAT.parse(
chapter_number = 1f,
date_upload = MetadataUtil.EX_DATE_FORMAT.parse(
doc.select("#gdd .gdt1").find { el ->
el.text().lowercase() == "posted:"
}!!.nextElementSibling()!!.text(),
@ -366,26 +362,28 @@ class EHentai(
val link = newGallery.attr("href")
val name = newGallery.text()
val posted = (newGallery.nextSibling() as TextNode).text().removePrefix(", added ")
ChapterInfo(
key = EHentaiSearchMetadata.normalizeUrl(link),
SChapter(
url = EHentaiSearchMetadata.normalizeUrl(link),
name = "v${index + 2}: $name",
number = index + 2f,
dateUpload = MetadataUtil.EX_DATE_FORMAT.parse(posted)!!.time,
chapter_number = index + 2f,
date_upload = MetadataUtil.EX_DATE_FORMAT.parse(posted)!!.time,
)
}.reversed() + self
}
}
@Suppress("OverridingDeprecatedMember", "DEPRECATION")
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
@Suppress("DEPRECATION")
override fun fetchChapterList(manga: SManga) = fetchChapterList(manga) {}
@Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated("Use getChapterList instead")
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
fun fetchChapterList(manga: SManga, throttleFunc: suspend () -> Unit) = runAsObservable {
getChapterList(manga.toMangaInfo(), throttleFunc).map { it.toSChapter() }
getChapterList(manga, throttleFunc)
}
override fun fetchPageList(chapter: SChapter) = fetchChapterPage(chapter, baseUrl + chapter.url)
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> = fetchChapterPage(chapter, baseUrl + chapter.url)
.map {
it.mapIndexed { i, s ->
Page(i, s)
@ -541,6 +539,7 @@ class EHentai(
*
* @param manga the manga to be updated.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return client.newCall(mangaDetailsRequest(manga))
.asObservableWithAsyncStacktrace()
@ -556,7 +555,8 @@ class EHentai(
} else Observable.just(doc)
pre.flatMap {
parseToManga(manga, it).andThen(
@Suppress("DEPRECATION")
parseToMangaCompletable(manga, it).andThen(
Observable.just(
manga.apply {
initialized = true
@ -576,17 +576,17 @@ class EHentai(
}
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
override suspend fun getMangaDetails(manga: SManga): SManga {
val exception = Exception("Async stacktrace")
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).awaitResponse()
val response = client.newCall(mangaDetailsRequest(manga)).awaitResponse()
if (response.isSuccessful) {
// Pull to most recent
val doc = response.asJsoup()
val newerGallery = doc.select("#gnd a").lastOrNull()
val pre = if (newerGallery != null && DebugToggles.PULL_TO_ROOT_WHEN_LOADING_EXH_MANGA_DETAILS.enabled) {
val sManga = manga.toSManga().apply {
url = EHentaiSearchMetadata.normalizeUrl(newerGallery.attr("href"))
}
val sManga = manga.copy(
url = EHentaiSearchMetadata.normalizeUrl(newerGallery.attr("href")),
)
client.newCall(mangaDetailsRequest(sManga)).await().asJsoup()
} else doc
return parseToManga(manga, pre)
@ -1097,12 +1097,12 @@ class EHentai(
}
override suspend fun getPagePreviewList(
manga: MangaInfo,
manga: SManga,
page: Int,
): PagePreviewPage {
val doc = client.newCall(
exGet(
(baseUrl + manga.key)
(baseUrl + manga.url)
.toHttpUrl()
.newBuilder()
.removeAllQueryParameters("nw")

View File

@ -6,7 +6,7 @@ import android.os.Build
import androidx.compose.runtime.Composable
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -20,7 +20,6 @@ import exh.source.DelegatedHttpSource
import exh.ui.metadata.adapters.HitomiDescription
import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import tachiyomi.source.model.MangaInfo
import java.text.SimpleDateFormat
import java.util.Locale
@ -38,8 +37,8 @@ class Hitomi(delegate: HttpSource, val context: Context) :
super.fetchSearchManga(page, query, filters)
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response.asJsoup())
}

View File

@ -14,7 +14,6 @@ import eu.kanade.tachiyomi.source.model.MetadataMangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toChapterInfo
import eu.kanade.tachiyomi.source.online.BrowseSourceFilterHeader
import eu.kanade.tachiyomi.source.online.FollowsSource
import eu.kanade.tachiyomi.source.online.HttpSource
@ -54,8 +53,6 @@ import exh.ui.metadata.adapters.MangaDexDescription
import okhttp3.OkHttpClient
import okhttp3.Response
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.reflect.KClass
@ -182,24 +179,27 @@ class MangaDex(delegate: HttpSource, val context: Context) :
}
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return mangaHandler.fetchMangaDetailsObservable(manga, id)
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
override suspend fun getMangaDetails(manga: SManga): SManga {
return mangaHandler.getMangaDetails(manga, id)
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return mangaHandler.fetchChapterListObservable(manga, blockedGroups(), blockedUploaders())
}
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
override suspend fun getChapterList(manga: SManga): List<SChapter> {
return mangaHandler.getChapterList(manga, blockedGroups(), blockedUploaders())
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return runAsObservable { pageHandler.fetchPageList(chapter.toChapterInfo(), isLogged(), usePort443Only(), dataSaver(), delegate) }
return runAsObservable { pageHandler.fetchPageList(chapter, isLogged(), usePort443Only(), dataSaver(), delegate) }
}
override fun fetchImage(page: Page): Observable<Response> {
@ -301,11 +301,11 @@ class MangaDex(delegate: HttpSource, val context: Context) :
return mangaHandler.fetchRandomMangaId()
}
suspend fun getMangaSimilar(manga: MangaInfo): MetadataMangasPage {
suspend fun getMangaSimilar(manga: SManga): MetadataMangasPage {
return similarHandler.getSimilar(manga)
}
suspend fun getMangaRelated(manga: MangaInfo): MetadataMangasPage {
suspend fun getMangaRelated(manga: SManga): MetadataMangasPage {
return similarHandler.getRelated(manga)
}

View File

@ -10,7 +10,6 @@ import eu.kanade.domain.manga.interactor.GetMergedReferencesById
import eu.kanade.domain.manga.interactor.InsertManga
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.Source
@ -19,7 +18,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.copy
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
@ -33,8 +32,6 @@ import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import okhttp3.Response
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@ -64,18 +61,20 @@ class MergedSource : HttpSource() {
override fun chapterListParse(response: Response) = throw UnsupportedOperationException()
override fun pageListParse(response: Response) = throw UnsupportedOperationException()
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException()
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga) = throw UnsupportedOperationException()
override suspend fun getChapterList(manga: MangaInfo) = throw UnsupportedOperationException()
override suspend fun getChapterList(manga: SManga) = throw UnsupportedOperationException()
override fun fetchImage(page: Page) = throw UnsupportedOperationException()
override fun fetchImageUrl(page: Page) = throw UnsupportedOperationException()
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter) = throw UnsupportedOperationException()
override suspend fun getPageList(chapter: ChapterInfo) = throw UnsupportedOperationException()
override suspend fun getPageList(chapter: SChapter) = throw UnsupportedOperationException()
override fun fetchLatestUpdates(page: Int) = throw UnsupportedOperationException()
override fun fetchPopularManga(page: Int) = throw UnsupportedOperationException()
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
override suspend fun getMangaDetails(manga: SManga): SManga {
return withIOContext {
val mergedManga = getManga.await(manga.key, id) ?: throw Exception("merged manga not in db")
val mergedManga = getManga.await(manga.url, id) ?: throw Exception("merged manga not in db")
val mangaReferences = getMergedReferencesById.await(mergedManga.id)
.apply {
if (isEmpty()) {
@ -93,10 +92,10 @@ class MergedSource : HttpSource() {
val mangaInfoReference = mangaReferences.firstOrNull { it.isInfoManga }
?: mangaReferences.firstOrNull { it.mangaId != it.mergeId }
val dbManga = mangaInfoReference?.run {
getManga.await(mangaUrl, mangaSourceId)?.toMangaInfo()
getManga.await(mangaUrl, mangaSourceId)?.toSManga()
}
(dbManga ?: mergedManga.toMangaInfo()).copy(
key = manga.key,
(dbManga ?: mergedManga.toSManga()).copy(
url = manga.url,
)
}
}
@ -185,8 +184,7 @@ class MergedSource : HttpSource() {
val (source, loadedManga, reference) =
it.load(sourceManager, getManga, insertManga, updateManga)
if (loadedManga != null && reference.getChapterUpdates) {
val chapterList = source.getChapterList(loadedManga.toMangaInfo())
.map(ChapterInfo::toSChapter)
val chapterList = source.getChapterList(loadedManga.toSManga())
val results =
syncChaptersWithSource.await(chapterList, loadedManga, source)
if (ifDownloadNewChapters && reference.downloadChapters) {
@ -226,7 +224,7 @@ class MergedSource : HttpSource() {
),
)!!
val newManga = getManga.await(id)!!
updateManga.awaitUpdateFromSource(newManga, source.getMangaDetails(newManga.toMangaInfo()), false)
updateManga.awaitUpdateFromSource(newManga, source.getMangaDetails(newManga.toSManga()), false)
manga = getManga.await(id)!!
}
return LoadedMangaSource(source, manga, this)

View File

@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.PagePreviewInfo
import eu.kanade.tachiyomi.source.PagePreviewPage
import eu.kanade.tachiyomi.source.PagePreviewSource
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -30,7 +30,6 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.CacheControl
import okhttp3.Response
import tachiyomi.source.model.MangaInfo
class NHentai(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
@ -57,8 +56,8 @@ class NHentai(delegate: HttpSource, val context: Context) :
super.fetchSearchManga(page, query, filters)
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response)
}
@ -181,9 +180,9 @@ class NHentai(delegate: HttpSource, val context: Context) :
NHentaiDescription(state, openMetadataViewer)
}
override suspend fun getPagePreviewList(manga: MangaInfo, page: Int): PagePreviewPage {
override suspend fun getPagePreviewList(manga: SManga, page: Int): PagePreviewPage {
val metadata = fetchOrLoadMetadata(manga.id()) {
client.newCall(mangaDetailsRequest(manga.toSManga())).await()
client.newCall(mangaDetailsRequest(manga)).await()
}
return PagePreviewPage(
page,

View File

@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.UrlImportableSource
@ -21,7 +21,6 @@ import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.nodes.TextNode
import tachiyomi.source.model.MangaInfo
class PervEden(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
@ -36,8 +35,8 @@ class PervEden(delegate: HttpSource, val context: Context) :
super.fetchSearchManga(page, query, filters)
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response.asJsoup())
}

View File

@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -20,7 +20,6 @@ import exh.ui.metadata.adapters.EightMusesDescription
import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import tachiyomi.source.model.MangaInfo
class EightMuses(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
@ -36,8 +35,8 @@ class EightMuses(delegate: HttpSource, val context: Context) :
super.fetchSearchManga(page, query, filters)
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response.asJsoup())
}

View File

@ -5,7 +5,7 @@ import android.net.Uri
import androidx.compose.runtime.Composable
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -19,7 +19,6 @@ import exh.ui.metadata.adapters.HBrowseDescription
import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import tachiyomi.source.model.MangaInfo
class HBrowse(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
@ -35,8 +34,8 @@ class HBrowse(delegate: HttpSource, val context: Context) :
super.fetchSearchManga(page, query, filters)
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response.asJsoup())
}

View File

@ -7,7 +7,7 @@ import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -24,7 +24,6 @@ import exh.util.trimAll
import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import rx.Observable
import tachiyomi.source.model.MangaInfo
class Pururin(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
@ -53,8 +52,8 @@ class Pururin(delegate: HttpSource, val context: Context) :
}
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response.asJsoup())
}

View File

@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.NamespaceSource
@ -24,7 +24,6 @@ import exh.util.trimAll
import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import rx.Observable
import tachiyomi.source.model.MangaInfo
import java.text.SimpleDateFormat
import java.util.Locale
@ -50,8 +49,8 @@ class Tsumino(delegate: HttpSource, val context: Context) :
return "https://tsumino.com/Book/Info/${uri.lastPathSegment}"
}
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await()
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
return parseToManga(manga, response.asJsoup())
}

View File

@ -14,7 +14,6 @@ import eu.kanade.domain.source.interactor.GetSavedSearchGlobalFeed
import eu.kanade.domain.source.interactor.InsertFeedSavedSearch
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.Source
@ -22,7 +21,6 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.runAsObservable
@ -272,8 +270,8 @@ open class FeedPresenter(
*/
private fun getMangaDetailsObservable(manga: Manga, source: Source): Observable<Manga> {
return runAsObservable {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
manga.copyFrom(networkManga.toSManga())
val networkManga = source.getMangaDetails(manga.copy())
manga.copyFrom(networkManga)
manga.initialized = true
updateManga.await(manga.toDomainManga()!!.toMangaUpdate())
manga

View File

@ -20,14 +20,12 @@ import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
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.toSChapter
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.ui.base.changehandler.OneWayFadeChangeHandler
import eu.kanade.tachiyomi.ui.base.controller.BaseController
@ -186,13 +184,13 @@ class MigrationListController(bundle: Bundle? = null) :
)
val chapters = if (source is EHentai) {
source.getChapterList(localManga.toMangaInfo(), throttleManager::throttle)
source.getChapterList(localManga.toSManga(), throttleManager::throttle)
} else {
source.getChapterList(localManga.toMangaInfo())
source.getChapterList(localManga.toSManga())
}
try {
syncChaptersWithSource.await(chapters.map { it.toSChapter() }, localManga, source)
syncChaptersWithSource.await(chapters, localManga, source)
} catch (e: Exception) {
return@async2 null
}
@ -223,10 +221,10 @@ class MigrationListController(bundle: Bundle? = null) :
val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id)
val chapters = try {
if (source is EHentai) {
source.getChapterList(localManga.toMangaInfo(), throttleManager::throttle)
source.getChapterList(localManga.toSManga(), throttleManager::throttle)
} else {
source.getChapterList(localManga.toMangaInfo())
}.map { it.toSChapter() }
source.getChapterList(localManga.toSManga())
}
} catch (e: Exception) {
this@MigrationListController.logcat(LogPriority.ERROR, e)
emptyList()
@ -254,7 +252,7 @@ class MigrationListController(bundle: Bundle? = null) :
if (result != null && result.thumbnailUrl == null) {
try {
val newManga = sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
val newManga = sourceManager.getOrStub(result.source).getMangaDetails(result.toSManga())
updateManga.awaitUpdateFromSource(result, newManga, true)
} catch (e: CancellationException) {
// Ignore cancellations
@ -359,8 +357,7 @@ class MigrationListController(bundle: Bundle? = null) :
val result = CoroutineScope(migratingManga.manga.migrationJob).async {
val localManga = smartSearchEngine.networkToLocalManga(manga.toDbManga(), source.id)
try {
val chapters = source.getChapterList(localManga.toMangaInfo())
.map { it.toSChapter() }
val chapters = source.getChapterList(localManga.toSManga())
syncChaptersWithSource.await(chapters, localManga, source)
} catch (e: Exception) {
return@async null
@ -370,7 +367,7 @@ class MigrationListController(bundle: Bundle? = null) :
if (result != null) {
try {
val newManga = sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
val newManga = sourceManager.getOrStub(result.source).getMangaDetails(result.toSManga())
updateManga.awaitUpdateFromSource(result, newManga, true)
} catch (e: CancellationException) {
// Ignore cancellations

View File

@ -20,7 +20,6 @@ import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
@ -30,7 +29,6 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.filter.AutoComplete
import eu.kanade.tachiyomi.ui.browse.source.filter.AutoCompleteSectionItem
@ -331,8 +329,8 @@ open class BrowseSourcePresenter(
*/
private suspend fun getMangaDetails(manga: Manga): Manga {
try {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
manga.copyFrom(networkManga.toSManga())
val networkManga = source.getMangaDetails(manga.copy())
manga.copyFrom(networkManga)
manga.initialized = true
updateManga.await(
manga

View File

@ -16,14 +16,12 @@ import eu.kanade.domain.source.interactor.GetSavedSearchBySourceIdFeed
import eu.kanade.domain.source.interactor.InsertFeedSavedSearch
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter.Companion.toItems
import eu.kanade.tachiyomi.util.lang.launchIO
@ -289,8 +287,8 @@ open class SourceFeedPresenter(
*/
private fun getMangaDetailsObservable(manga: Manga, source: Source): Observable<Manga> {
return runAsObservable {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
manga.copyFrom(networkManga.toSManga())
val networkManga = source.getMangaDetails(manga.copy())
manga.copyFrom(networkManga)
manga.initialized = true
updateManga.await(manga.toDomainManga()!!.toMangaUpdate())
manga

View File

@ -8,7 +8,6 @@ import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.model.toMangaUpdate
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.CatalogueSource
@ -16,7 +15,6 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
import eu.kanade.tachiyomi.util.lang.runAsObservable
@ -247,8 +245,8 @@ open class GlobalSearchPresenter(
* @return The initialized manga.
*/
private suspend fun getMangaDetails(manga: Manga, source: Source): Manga {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
manga.copyFrom(networkManga.toSManga())
val networkManga = source.getMangaDetails(manga.copy())
manga.copyFrom(networkManga)
manga.initialized = true
updateManga.await(manga.toDomainManga()!!.toMangaUpdate())
return manga

View File

@ -35,7 +35,6 @@ import eu.kanade.domain.manga.model.PagePreview
import eu.kanade.domain.manga.model.TriStateFilter
import eu.kanade.domain.manga.model.isLocal
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.domain.track.interactor.DeleteTrack
import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack
@ -55,7 +54,6 @@ import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.PagePreviewSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
@ -416,7 +414,7 @@ class MangaPresenter(
updateSuccessState { it.copy(isRefreshingInfo = true) }
try {
successState?.let {
val networkManga = it.source.getMangaDetails(it.manga.toMangaInfo())
val networkManga = it.source.getMangaDetails(it.manga.toSManga())
updateManga.awaitUpdateFromSource(it.manga, networkManga, manualFetch)
}
} catch (e: Throwable) {
@ -964,8 +962,7 @@ class MangaPresenter(
try {
successState?.let { successState ->
if (successState.source !is MergedSource) {
val chapters = successState.source.getChapterList(successState.manga.toMangaInfo())
.map { it.toSChapter() }
val chapters = successState.source.getChapterList(successState.manga.toSManga())
val newChapters = syncChaptersWithSource.await(
chapters,

View File

@ -29,11 +29,12 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
if (!refreshSameUrl && thumbnail_url == newUrl) return
val domainManga = toDomainManga()!!
when {
toDomainManga()!!.isLocal() -> {
domainManga.isLocal() -> {
cover_last_modified = Date().time
}
toDomainManga()!!.hasCustomCover(coverCache) -> {
domainManga.hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(this, false)
}
else -> {

View File

@ -9,11 +9,9 @@ import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.InsertManga
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.online.UrlImportableSource
import eu.kanade.tachiyomi.source.online.all.EHentai
import exh.log.xLogStack
@ -135,7 +133,7 @@ class GalleryAdder(
}
// Fetch and copy details
val newManga = source.getMangaDetails(manga.toMangaInfo())
val newManga = source.getMangaDetails(manga.toSManga())
updateManga.awaitUpdateFromSource(manga, newManga, false)
manga = getManga.await(manga.id)!!
@ -147,10 +145,10 @@ class GalleryAdder(
// Fetch and copy chapters
try {
val chapterList = if (source is EHentai) {
source.getChapterList(manga.toMangaInfo(), throttleFunc)
source.getChapterList(manga.toSManga(), throttleFunc)
} else {
source.getChapterList(manga.toMangaInfo())
}.map { it.toSChapter() }
source.getChapterList(manga.toSManga())
}
if (chapterList.isNotEmpty()) {
syncChaptersWithSource.await(chapterList, manga, source)

View File

@ -10,7 +10,6 @@ import eu.kanade.domain.manga.interactor.GetFlatMetadataById
import eu.kanade.domain.manga.interactor.GetSearchMetadata
import eu.kanade.domain.manga.interactor.InsertFlatMetadata
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.NHentai
@ -79,7 +78,7 @@ object DebugFunctions {
EH_SOURCE_ID -> eh
EXH_SOURCE_ID -> ex
else -> return@forEach
}?.getMangaDetails(manga.toMangaInfo()) ?: return@forEach
}?.getMangaDetails(manga.toSManga()) ?: return@forEach
updateManga.awaitUpdateFromSource(manga, networkManga, true)
}

View File

@ -19,13 +19,11 @@ import eu.kanade.domain.manga.interactor.GetFlatMetadataById
import eu.kanade.domain.manga.interactor.InsertFlatMetadata
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
import exh.debug.DebugToggles
@ -203,11 +201,10 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
?: throw GalleryNotUpdatedException(false, IllegalStateException("Missing EH-based source (${manga.source})!"))
try {
val updatedManga = source.getMangaDetails(manga.toMangaInfo())
val updatedManga = source.getMangaDetails(manga.toSManga())
updateManga.awaitUpdateFromSource(manga, updatedManga, false)
val newChapters = source.getChapterList(manga.toMangaInfo())
.map { it.toSChapter() }
val newChapters = source.getChapterList(manga.toSManga())
val new = syncChaptersWithSource.await(newChapters, manga, source)
return new to getChapterByMangaId.await(manga.id)

View File

@ -3,6 +3,7 @@ package exh.md.handlers
import eu.kanade.domain.manga.interactor.GetFlatMetadataById
import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.InsertFlatMetadata
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import exh.log.xLogE
import exh.md.dto.ChapterDataDto
@ -17,8 +18,6 @@ import exh.metadata.metadata.base.RaisedTag
import exh.util.capitalize
import exh.util.floor
import exh.util.nullIfEmpty
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.injectLazy
import java.util.Locale
@ -40,13 +39,13 @@ class ApiMangaParser(
?: error("Could not find no-args constructor for meta class: ${metaClass.qualifiedName}!")
suspend fun parseToManga(
manga: MangaInfo,
manga: SManga,
sourceId: Long,
input: MangaDto,
simpleChapters: List<String>,
statistics: StatisticsMangaDto?,
): MangaInfo {
val mangaId = getManga.await(manga.key, sourceId)?.id
): SManga {
val mangaId = getManga.await(manga.url, sourceId)?.id
val metadata = if (mangaId != null) {
val flatMetadata = getFlatMetadataById.await(mangaId)
flatMetadata?.raise(metaClass) ?: newMetaInstance()
@ -184,7 +183,7 @@ class ApiMangaParser(
else -> SManga.UNKNOWN
}
fun chapterListParse(chapterListResponse: List<ChapterDataDto>, groupMap: Map<String, String>): List<ChapterInfo> {
fun chapterListParse(chapterListResponse: List<ChapterDataDto>, groupMap: Map<String, String>): List<SChapter> {
val now = System.currentTimeMillis()
return chapterListResponse
.filterNot { MdUtil.parseDate(it.attributes.publishAt) > now && it.attributes.externalUrl == null }
@ -202,7 +201,7 @@ class ApiMangaParser(
private fun mapChapter(
networkChapter: ChapterDataDto,
groups: Map<String, String>,
): ChapterInfo {
): SChapter {
val attributes = networkChapter.attributes
val key = MdUtil.chapterSuffix + networkChapter.id
val chapterName = StringBuilder()
@ -265,11 +264,11 @@ class ApiMangaParser(
// chapter.language = MdLang.fromIsoCode(attributes.translatedLanguage)?.prettyPrint ?: ""
return ChapterInfo(
key = key,
return SChapter(
url = key,
name = name,
scanlator = scanlator,
dateUpload = dateUpload,
date_upload = dateUpload,
)
}
}

View File

@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import exh.log.xLogD
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@ -20,7 +21,6 @@ import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import java.util.concurrent.TimeUnit
class BilibiliHandler(currentClient: OkHttpClient) {
@ -44,9 +44,9 @@ class BilibiliHandler(currentClient: OkHttpClient) {
val mangaUrl = getMangaUrl(externalUrl)
val chapters = getChapterList(mangaUrl)
val chapter = chapters
.find { it.number == chapterNumber.toFloatOrNull() }
.find { it.chapter_number == chapterNumber.toFloatOrNull() }
?: throw Exception("Unknown chapter $chapterNumber")
chapter.key
chapter.url
}
return fetchPageList(chapterUrl)
@ -91,12 +91,12 @@ class BilibiliHandler(currentClient: OkHttpClient) {
)
}
suspend fun getChapterList(mangaUrl: String): List<ChapterInfo> {
suspend fun getChapterList(mangaUrl: String): List<SChapter> {
val response = client.newCall(mangaDetailsApiRequest(mangaUrl)).await()
return chapterListParse(response)
}
fun chapterListParse(response: Response): List<ChapterInfo> {
fun chapterListParse(response: Response): List<SChapter> {
val result = response.parseAs<BilibiliResultDto<BilibiliComicDto>>()
if (result.code != 0) {
@ -108,10 +108,10 @@ class BilibiliHandler(currentClient: OkHttpClient) {
.map { ep -> chapterFromObject(ep, result.data.id) }
}
private fun chapterFromObject(episode: BilibiliEpisodeDto, comicId: Int): ChapterInfo = ChapterInfo(
key = "/mc$comicId/${episode.id}",
private fun chapterFromObject(episode: BilibiliEpisodeDto, comicId: Int): SChapter = SChapter(
url = "/mc$comicId/${episode.id}",
name = "Ep. " + episode.order.toString().removeSuffix(".0") + " - " + episode.title,
number = episode.order,
chapter_number = episode.order,
)
private suspend fun fetchPageList(chapterUrl: String): List<Page> {

View File

@ -4,7 +4,6 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.dto.MangaDataDto
import exh.md.dto.PersonalRatingDto
@ -57,7 +56,7 @@ class FollowsHandler(
MdUtil.createMangaEntry(
it,
lang,
).toSManga() to MangaDexSearchMetadata().apply {
) to MangaDexSearchMetadata().apply {
followStatus = FollowStatus.fromDex(statuses[it.id]).int
}
}.sortedWith(comparator)

View File

@ -3,9 +3,6 @@ package exh.md.handlers
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.dto.ChapterDataDto
@ -19,8 +16,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
class MangaHandler(
private val lang: String,
@ -28,9 +23,9 @@ class MangaHandler(
private val apiMangaParser: ApiMangaParser,
private val followsHandler: FollowsHandler,
) {
suspend fun getMangaDetails(manga: MangaInfo, sourceId: Long): MangaInfo {
suspend fun getMangaDetails(manga: SManga, sourceId: Long): SManga {
return coroutineScope {
val mangaId = MdUtil.getMangaId(manga.key)
val mangaId = MdUtil.getMangaId(manga.url)
val response = async(Dispatchers.IO) { service.viewManga(mangaId) }
val simpleChapters = async(Dispatchers.IO) { getSimpleChapters(manga) }
val statistics = async(Dispatchers.IO) { service.mangasRating(mangaId).statistics[mangaId] }
@ -46,19 +41,19 @@ class MangaHandler(
fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long): Observable<SManga> {
return runAsObservable {
getMangaDetails(manga.toMangaInfo(), sourceId).toSManga()
getMangaDetails(manga, sourceId)
}
}
fun fetchChapterListObservable(manga: SManga, blockedGroups: String, blockedUploaders: String): Observable<List<SChapter>> = runAsObservable {
getChapterList(manga.toMangaInfo(), blockedGroups, blockedUploaders).map { it.toSChapter() }
getChapterList(manga, blockedGroups, blockedUploaders)
}
suspend fun getChapterList(manga: MangaInfo, blockedGroups: String, blockedUploaders: String): List<ChapterInfo> {
suspend fun getChapterList(manga: SManga, blockedGroups: String, blockedUploaders: String): List<SChapter> {
return withIOContext {
val results = mdListCall {
service.viewChapters(
MdUtil.getMangaId(manga.key),
MdUtil.getMangaId(manga.url),
lang,
it,
blockedGroups,
@ -109,8 +104,8 @@ class MangaHandler(
}
}
private suspend fun getSimpleChapters(manga: MangaInfo): List<String> {
return runCatching { service.aggregateChapters(MdUtil.getMangaId(manga.key), lang) }
private suspend fun getSimpleChapters(manga: SManga): List<String> {
return runCatching { service.aggregateChapters(MdUtil.getMangaId(manga.url), lang) }
.onFailure {
if (it is CancellationException) throw it
}

View File

@ -4,7 +4,9 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.mdlist.MdList
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.log.xLogD
import exh.md.dto.AtHomeDto
@ -14,8 +16,6 @@ import exh.md.utils.MdUtil
import okhttp3.Headers
import okhttp3.Response
import rx.Observable
import tachiyomi.source.Source
import tachiyomi.source.model.ChapterInfo
import kotlin.reflect.full.superclasses
import kotlin.reflect.jvm.isAccessible
@ -31,9 +31,9 @@ class PageHandler(
private val mdList: MdList,
) {
suspend fun fetchPageList(chapter: ChapterInfo, isLogged: Boolean, usePort443Only: Boolean, dataSaver: Boolean, mangadex: Source): List<Page> {
suspend fun fetchPageList(chapter: SChapter, isLogged: Boolean, usePort443Only: Boolean, dataSaver: Boolean, mangadex: Source): List<Page> {
return withIOContext {
val chapterResponse = service.viewChapter(MdUtil.getChapterId(chapter.key))
val chapterResponse = service.viewChapter(MdUtil.getChapterId(chapter.url))
if (chapterResponse.data.attributes.externalUrl != null && chapterResponse.data.attributes.pages == 0) {
when {
@ -63,9 +63,9 @@ class PageHandler(
}
val atHomeRequestUrl = if (usePort443Only) {
"${MdApi.atHomeServer}/${MdUtil.getChapterId(chapter.key)}?forcePort443=true"
"${MdApi.atHomeServer}/${MdUtil.getChapterId(chapter.url)}?forcePort443=true"
} else {
"${MdApi.atHomeServer}/${MdUtil.getChapterId(chapter.key)}"
"${MdApi.atHomeServer}/${MdUtil.getChapterId(chapter.url)}"
}
updateExtensionVariable(mangadex, atHomeRequestUrl)

View File

@ -1,7 +1,7 @@
package exh.md.handlers
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.dto.RelationListDto
import exh.md.dto.SimilarMangaDto
@ -10,7 +10,6 @@ import exh.md.service.SimilarService
import exh.md.utils.MangaDexRelation
import exh.md.utils.MdUtil
import exh.metadata.metadata.MangaDexSearchMetadata
import tachiyomi.source.model.MangaInfo
class SimilarHandler(
private val lang: String,
@ -18,8 +17,8 @@ class SimilarHandler(
private val similarService: SimilarService,
) {
suspend fun getSimilar(manga: MangaInfo): MetadataMangasPage {
val similarDto = withIOContext { similarService.getSimilarManga(MdUtil.getMangaId(manga.key)) }
suspend fun getSimilar(manga: SManga): MetadataMangasPage {
val similarDto = withIOContext { similarService.getSimilarManga(MdUtil.getMangaId(manga.url)) }
return similarDtoToMangaListPage(similarDto)
}
@ -31,14 +30,14 @@ class SimilarHandler(
}
val mangaList = service.viewMangas(ids).data.map {
MdUtil.createMangaEntry(it, lang).toSManga()
MdUtil.createMangaEntry(it, lang)
}
return MetadataMangasPage(mangaList, false, List(mangaList.size) { MangaDexSearchMetadata().also { it.relation = MangaDexRelation.SIMILAR } })
}
suspend fun getRelated(manga: MangaInfo): MetadataMangasPage {
val relatedListDto = withIOContext { service.relatedManga(MdUtil.getMangaId(manga.key)) }
suspend fun getRelated(manga: SManga): MetadataMangasPage {
val relatedListDto = withIOContext { service.relatedManga(MdUtil.getMangaId(manga.url)) }
return relatedDtoToMangaListPage(relatedListDto)
}
@ -50,7 +49,7 @@ class SimilarHandler(
.map { it.id }
val mangaList = service.viewMangas(ids).data.map {
MdUtil.createMangaEntry(it, lang).toSManga()
MdUtil.createMangaEntry(it, lang)
}
return MetadataMangasPage(

View File

@ -1,7 +1,6 @@
package exh.md.similar
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
import eu.kanade.tachiyomi.source.online.all.MangaDex
import eu.kanade.tachiyomi.ui.browse.source.browse.NoResultsException
@ -16,8 +15,8 @@ class MangaDexSimilarPager(val manga: Manga, val source: MangaDex) : Pager() {
override suspend fun requestNextPage() {
val mangasPage = coroutineScope {
val similarPageDef = async { source.getMangaSimilar(manga.toMangaInfo()) }
val relatedPageDef = async { source.getMangaRelated(manga.toMangaInfo()) }
val similarPageDef = async { source.getMangaSimilar(manga.toSManga()) }
val relatedPageDef = async { source.getMangaRelated(manga.toSManga()) }
val similarPage = similarPageDef.await()
val relatedPage = relatedPageDef.await()

View File

@ -3,6 +3,7 @@ package exh.md.utils
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.mdlist.MdList
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.all.MangaDex
import exh.log.xLogD
@ -24,8 +25,6 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.jsoup.parser.Parser
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat
@ -233,7 +232,7 @@ class MdUtil {
return scanlators.sorted().joinToString(scanlatorSeparator)
}
fun getMissingChapterCount(chapters: List<ChapterInfo>, mangaStatus: Int): String? {
fun getMissingChapterCount(chapters: List<SChapter>, mangaStatus: Int): String? {
if (mangaStatus == SManga.COMPLETED) return null
val remove0ChaptersFromCount = chapters.distinctBy {
@ -242,14 +241,14 @@ class MdUtil {
} else {*/
it.name
/*}*/
}.sortedByDescending { it.number }
}.sortedByDescending { it.chapter_number }
remove0ChaptersFromCount.firstOrNull()?.let { chapter ->
val chpNumber = chapter.number.floor()
val chpNumber = chapter.chapter_number.floor()
val allChapters = (1..chpNumber).toMutableSet()
remove0ChaptersFromCount.forEach {
allChapters.remove(it.number.floor())
allChapters.remove(it.chapter_number.floor())
}
if (allChapters.isEmpty()) return null
@ -264,11 +263,11 @@ class MdUtil {
fun parseDate(dateAsString: String): Long =
dateFormatter.parse(dateAsString)?.time ?: 0
fun createMangaEntry(json: MangaDataDto, lang: String): MangaInfo {
return MangaInfo(
key = buildMangaUrl(json.id),
fun createMangaEntry(json: MangaDataDto, lang: String): SManga {
return SManga(
url = buildMangaUrl(json.id),
title = cleanString(getTitleFromManga(json.attributes, lang)),
cover = json.relationships
thumbnail_url = json.relationships
.firstOrNull { relationshipDto -> relationshipDto.type == MdConstants.Types.coverArt }
?.attributes
?.fileName

View File

@ -4,10 +4,11 @@ import android.content.Context
import androidx.core.net.toUri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.MetadataUtil
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
@ -42,7 +43,7 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
var aged: Boolean = false
var lastUpdateCheck: Long = 0
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = gId?.let { gId ->
gToken?.let { gToken ->
idAndTokenToUrl(gId, gToken)
@ -61,29 +62,29 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
?.joinToString { it.name }
// Copy tags -> genres
val genres = tagsToGenreList()
val genres = tagsToGenreString()
// Try to automatically identify if it is ongoing, we try not to be too lenient here to avoid making mistakes
// We default to completed
var status = MangaInfo.COMPLETED
var status = SManga.COMPLETED
title?.let { t ->
MetadataUtil.ONGOING_SUFFIX.find {
t.endsWith(it, ignoreCase = true)
}?.let {
status = MangaInfo.ONGOING
status = SManga.ONGOING
}
}
val description = "meta"
return manga.copy(
key = key ?: manga.key,
url = key ?: manga.url,
title = title ?: manga.title,
artist = artist ?: manga.artist,
description = description,
genres = genres,
genre = genres,
status = status,
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
)
}

View File

@ -2,10 +2,11 @@ package exh.metadata.metadata
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.util.nullIfEmpty
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
@Serializable
class EightMusesSearchMetadata : RaisedSearchMetadata() {
@ -15,7 +16,7 @@ class EightMusesSearchMetadata : RaisedSearchMetadata() {
var thumbnailUrl: String? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = path.joinToString("/", prefix = "/")
val title = title
@ -24,16 +25,16 @@ class EightMusesSearchMetadata : RaisedSearchMetadata() {
val artist = tags.ofNamespace(ARTIST_NAMESPACE).joinToString { it.name }
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val description = "meta"
return manga.copy(
key = key,
url = key,
title = title ?: manga.title,
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
artist = artist,
genres = genres,
genre = genres,
description = description,
)
}

View File

@ -2,9 +2,10 @@ package exh.metadata.metadata
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
@Serializable
class HBrowseSearchMetadata : RaisedSearchMetadata() {
@ -19,28 +20,28 @@ class HBrowseSearchMetadata : RaisedSearchMetadata() {
// Length in pages
var length: Int? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = hbUrl
val title = title
// Guess thumbnail URL if manga does not have thumbnail URL
val cover = if (manga.cover.isBlank()) {
val cover = if (manga.thumbnail_url.isNullOrBlank()) {
guessThumbnailUrl(hbId.toString())
} else null
val artist = tags.ofNamespace(ARTIST_NAMESPACE).joinToString { it.name }
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val description = "meta"
return manga.copy(
key = key ?: manga.key,
url = key ?: manga.url,
title = title ?: manga.title,
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
artist = artist,
genres = genres,
genre = genres,
description = description,
)
}

View File

@ -2,11 +2,12 @@ package exh.metadata.metadata
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.MetadataUtil
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.util.nullIfEmpty
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
import java.util.Date
@Serializable
@ -32,24 +33,24 @@ class HitomiSearchMetadata : RaisedSearchMetadata() {
var uploadDate: Long? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val cover = thumbnailUrl
val title = title
// Copy tags -> genres
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val artist = artists.joinToString()
val status = MangaInfo.UNKNOWN
val status = SManga.UNKNOWN
val description = "meta"
return manga.copy(
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
title = title ?: manga.title,
genres = genres,
genre = genres,
artist = artist,
status = status,
description = description,

View File

@ -2,11 +2,12 @@ package exh.metadata.metadata
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.md.utils.MangaDexRelation
import exh.md.utils.MdUtil
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
@Serializable
class MangaDexSearchMetadata : RaisedSearchMetadata() {
@ -45,7 +46,7 @@ class MangaDexSearchMetadata : RaisedSearchMetadata() {
// var maxChapterNumber: Int? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = mdUuid?.let { MdUtil.buildMangaUrl(it) }
val title = title
@ -58,18 +59,18 @@ class MangaDexSearchMetadata : RaisedSearchMetadata() {
val status = status
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val description = description
return manga.copy(
key = key ?: manga.key,
url = key ?: manga.url,
title = title ?: manga.title,
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
author = author ?: manga.author,
artist = artist ?: manga.artist,
status = status ?: manga.status,
genres = genres,
genre = genres,
description = description ?: manga.description,
)
}

View File

@ -3,10 +3,10 @@ package exh.metadata.metadata
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.MetadataUtil
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
import java.util.Date
@Serializable
@ -38,7 +38,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
var preferredTitle: Int? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = nhId?.let { nhIdToPath(it) }
val cover = if (mediaId != null) {
@ -59,7 +59,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
}
// Copy tags -> genres
val genres = tagsToGenreList()
val genres = tagsToGenreString()
// Try to automatically identify if it is ongoing, we try not to be too lenient here to avoid making mistakes
// We default to completed
@ -75,11 +75,11 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
val description = "meta"
return manga.copy(
key = key ?: manga.key,
cover = cover ?: manga.cover,
url = key ?: manga.url,
thumbnail_url = cover ?: manga.thumbnail_url,
title = title,
artist = artist ?: manga.artist,
genres = genres,
genre = genres,
status = status,
description = description,
)

View File

@ -3,11 +3,12 @@ package exh.metadata.metadata
import android.content.Context
import androidx.core.net.toUri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.metadata.metadata.base.RaisedTitle
import exh.util.nullIfEmpty
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
@Serializable
class PervEdenSearchMetadata : RaisedSearchMetadata() {
@ -34,7 +35,7 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
var lang: String? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = url
val cover = thumbnailUrl
@ -43,23 +44,23 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
val artist = artist
val status = when (status) {
"Ongoing" -> MangaInfo.ONGOING
"Completed", "Suspended" -> MangaInfo.COMPLETED
else -> MangaInfo.UNKNOWN
"Ongoing" -> SManga.ONGOING
"Completed", "Suspended" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
// Copy tags -> genres
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val description = "meta"
return manga.copy(
key = key ?: manga.key,
cover = cover ?: manga.cover,
url = key ?: manga.url,
thumbnail_url = cover ?: manga.thumbnail_url,
title = title ?: manga.title,
artist = artist ?: manga.artist,
status = status,
genres = genres,
genre = genres,
description = description,
)
}

View File

@ -2,9 +2,10 @@ package exh.metadata.metadata
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
@Serializable
class PururinSearchMetadata : RaisedSearchMetadata() {
@ -26,7 +27,7 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
var ratingCount: Int? = null
var averageRating: Double? = null
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val key = prId?.let { prId ->
prShortLink?.let { prShortLink ->
"/gallery/$prId/$prShortLink"
@ -39,16 +40,16 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
val artist = tags.ofNamespace(TAG_NAMESPACE_ARTIST).joinToString { it.name }
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val description = "meta"
return manga.copy(
key = key ?: manga.key,
url = key ?: manga.url,
title = title ?: manga.title,
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
artist = artist,
genres = genres,
genre = genres,
description = description,
)
}

View File

@ -4,11 +4,11 @@ import android.content.Context
import androidx.core.net.toUri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.copy
import exh.metadata.MetadataUtil
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.util.nullIfEmpty
import kotlinx.serialization.Serializable
import tachiyomi.source.model.MangaInfo
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@ -43,7 +43,7 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
var character: List<String> = emptyList()
override fun createMangaInfo(manga: MangaInfo): MangaInfo {
override fun createMangaInfo(manga: SManga): SManga {
val title = title
val cover = tmId?.let { BASE_URL.replace("www", "content") + thumbUrlFromId(it.toString()) }
@ -52,16 +52,16 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
val status = SManga.UNKNOWN
// Copy tags -> genres
val genres = tagsToGenreList()
val genres = tagsToGenreString()
val description = "meta"
return manga.copy(
title = title ?: manga.title,
cover = cover ?: manga.cover,
thumbnail_url = cover ?: manga.thumbnail_url,
artist = artist ?: manga.artist,
status = status,
genres = genres,
genre = genres,
description = description,
)
}

View File

@ -2,8 +2,6 @@ package exh.metadata.metadata.base
import android.content.Context
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toSManga
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.EightMusesSearchMetadata
import exh.metadata.metadata.HBrowseSearchMetadata
@ -25,7 +23,6 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import tachiyomi.source.model.MangaInfo
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
@ -64,11 +61,11 @@ abstract class RaisedSearchMetadata {
}
open fun copyTo(manga: SManga) {
val infoManga = createMangaInfo(manga.toMangaInfo()).toSManga()
val infoManga = createMangaInfo(manga.copy())
manga.copyFrom(infoManga)
}
abstract fun createMangaInfo(manga: MangaInfo): MangaInfo
abstract fun createMangaInfo(manga: SManga): SManga
fun tagsToGenreString() = tags.toGenreString()

View File

@ -10,8 +10,6 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
@Suppress("OverridingDeprecatedMember", "DEPRECATION")
abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
@ -183,6 +181,7 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
*
* @param manga the manga to be updated.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
ensureDelegateCompatible()
return delegate.fetchMangaDetails(manga)
@ -191,7 +190,7 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
/**
* [1.x API] Get the updated details for a manga.
*/
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
override suspend fun getMangaDetails(manga: SManga): SManga {
ensureDelegateCompatible()
return delegate.getMangaDetails(manga)
}
@ -213,6 +212,7 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
*
* @param manga the manga to look for chapters.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
ensureDelegateCompatible()
return delegate.fetchChapterList(manga)
@ -221,7 +221,7 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
/**
* [1.x API] Get all the available chapters for a manga.
*/
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
override suspend fun getChapterList(manga: SManga): List<SChapter> {
ensureDelegateCompatible()
return delegate.getChapterList(manga)
}
@ -231,6 +231,7 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
*
* @param chapter the chapter whose page list has to be fetched.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
ensureDelegateCompatible()
return delegate.fetchPageList(chapter)
@ -239,7 +240,7 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
/**
* [1.x API] Get the list of pages a chapter has.
*/
override suspend fun getPageList(chapter: ChapterInfo): List<tachiyomi.source.model.Page> {
override suspend fun getPageList(chapter: SChapter): List<Page> {
ensureDelegateCompatible()
return delegate.getPageList(chapter)
}

View File

@ -8,8 +8,6 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Response
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.injectLazy
@Suppress("OverridingDeprecatedMember", "DEPRECATION")
@ -177,12 +175,13 @@ class EnhancedHttpSource(
*
* @param manga the manga to be updated.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga) = source().fetchMangaDetails(manga)
/**
* [1.x API] Get the updated details for a manga.
*/
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo = source().getMangaDetails(manga)
override suspend fun getMangaDetails(manga: SManga): SManga = source().getMangaDetails(manga)
/**
* Returns the request for the details of a manga. Override only if it's needed to change the
@ -198,24 +197,26 @@ class EnhancedHttpSource(
*
* @param manga the manga to look for chapters.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga) = source().fetchChapterList(manga)
/**
* [1.x API] Get all the available chapters for a manga.
*/
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> = source().getChapterList(manga)
override suspend fun getChapterList(manga: SManga): List<SChapter> = source().getChapterList(manga)
/**
* Returns an observable with the page list for a chapter.
*
* @param chapter the chapter whose page list has to be fetched.
*/
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter) = source().fetchPageList(chapter)
/**
* [1.x API] Get the list of pages a chapter has.
*/
override suspend fun getPageList(chapter: ChapterInfo): List<tachiyomi.source.model.Page> = source().getPageList(chapter)
override suspend fun getPageList(chapter: SChapter): List<Page> = source().getPageList(chapter)
/**
* Returns an observable with the page containing the source url of the image. If there's any

View File

@ -13,8 +13,6 @@ leakcanary = "2.9.1"
android-shortcut-gradle = "com.github.zellius:android-shortcut-gradle-plugin:0.1.2"
google-services-gradle = "com.google.gms:google-services:4.3.10"
tachiyomi-api = "org.tachiyomi:source-api:1.1"
rxandroid = "io.reactivex:rxandroid:1.2.1"
rxjava = "io.reactivex:rxjava:1.3.8"
rxrelay = "com.jakewharton.rxrelay:rxrelay:1.2.0"