Remove 1.x source models (#7781)

This commit is contained in:
stevenyomi 2022-08-19 02:07:13 +08:00 committed by GitHub
parent 4228bbb88e
commit e36e9d9d5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 92 additions and 225 deletions

View File

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

View File

@ -7,7 +7,7 @@ import eu.kanade.domain.manga.model.isLocal
import eu.kanade.domain.manga.model.toDbManga import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.repository.MangaRepository import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import tachiyomi.source.model.MangaInfo import eu.kanade.tachiyomi.source.model.SManga
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.util.Date
@ -26,17 +26,18 @@ class UpdateManga(
suspend fun awaitUpdateFromSource( suspend fun awaitUpdateFromSource(
localManga: Manga, localManga: Manga,
remoteManga: MangaInfo, remoteManga: SManga,
manualFetch: Boolean, manualFetch: Boolean,
coverCache: CoverCache = Injekt.get(), coverCache: CoverCache = Injekt.get(),
): Boolean { ): Boolean {
// if the manga isn't a favorite, set its title from source and update in db // if the manga isn't a favorite, set its title from source and update in db
val title = if (!localManga.favorite) remoteManga.title else null val title = if (!localManga.favorite) remoteManga.title else null
// Never refresh covers if the url is empty to avoid "losing" existing covers val coverLastModified =
val updateCover = remoteManga.cover.isNotEmpty() && (manualFetch || localManga.thumbnailUrl != remoteManga.cover)
val coverLastModified = if (updateCover) {
when { 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.isLocal() -> Date().time
localManga.hasCustomCover(coverCache) -> { localManga.hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(localManga.toDbManga(), false) coverCache.deleteFromCache(localManga.toDbManga(), false)
@ -47,7 +48,6 @@ class UpdateManga(
Date().time Date().time
} }
} }
} else null
return mangaRepository.update( return mangaRepository.update(
MangaUpdate( MangaUpdate(
@ -57,8 +57,8 @@ class UpdateManga(
author = remoteManga.author, author = remoteManga.author,
artist = remoteManga.artist, artist = remoteManga.artist,
description = remoteManga.description, description = remoteManga.description,
genre = remoteManga.genres, genre = remoteManga.getGenres(),
thumbnailUrl = remoteManga.cover.takeIf { it.isNotEmpty() }, thumbnailUrl = remoteManga.thumbnail_url?.takeIf { it.isNotEmpty() },
status = remoteManga.status.toLong(), status = remoteManga.status.toLong(),
initialized = true, initialized = true,
), ),

View File

@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.widget.ExtendedNavigationView import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.Serializable import java.io.Serializable
@ -184,17 +183,6 @@ fun Manga.toDbManga(): DbManga = MangaImpl().also {
it.initialized = initialized it.initialized = initialized
} }
fun Manga.toMangaInfo(): MangaInfo = MangaInfo(
artist = artist ?: "",
author = author ?: "",
cover = thumbnailUrl ?: "",
description = description ?: "",
genres = genre ?: emptyList(),
key = url,
status = status.toInt(),
title = title,
)
fun Manga.toMangaUpdate(): MangaUpdate { fun Manga.toMangaUpdate(): MangaUpdate {
return MangaUpdate( return MangaUpdate(
id = id, id = id,

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.database.models
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import tachiyomi.source.model.MangaInfo
import eu.kanade.domain.manga.model.Manga as DomainManga import eu.kanade.domain.manga.model.Manga as DomainManga
interface Manga : SManga { interface Manga : SManga {
@ -75,19 +74,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? { fun Manga.toDomainManga(): DomainManga? {
val mangaId = id ?: return null val mangaId = id ?: return null
return DomainManga( return DomainManga(

View File

@ -16,7 +16,6 @@ import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.manga.interactor.GetLibraryManga import eu.kanade.domain.manga.interactor.GetLibraryManga
import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.domain.manga.model.toMangaUpdate import eu.kanade.domain.manga.model.toMangaUpdate
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.interactor.InsertTrack
@ -29,7 +28,6 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainChapter import eu.kanade.tachiyomi.data.database.models.toDomainChapter
import eu.kanade.tachiyomi.data.database.models.toDomainManga 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.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
@ -44,8 +42,6 @@ import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.prepUpdateCover import eu.kanade.tachiyomi.util.prepUpdateCover
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
@ -69,7 +65,6 @@ import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.sync.withPermit
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@ -428,16 +423,13 @@ class LibraryUpdateService(
private suspend fun updateManga(manga: DomainManga): List<DomainChapter> { private suspend fun updateManga(manga: DomainManga): List<DomainChapter> {
val source = sourceManager.getOrStub(manga.source) val source = sourceManager.getOrStub(manga.source)
val mangaInfo: MangaInfo = manga.toMangaInfo()
// Update manga metadata if needed // Update manga metadata if needed
if (preferences.autoUpdateMetadata()) { if (preferences.autoUpdateMetadata()) {
val updatedMangaInfo = source.getMangaDetails(manga.toMangaInfo()) val networkManga = source.getMangaDetails(manga.toSManga())
updateManga.awaitUpdateFromSource(manga, updatedMangaInfo, manualFetch = false, coverCache) updateManga.awaitUpdateFromSource(manga, networkManga, manualFetch = false, coverCache)
} }
val chapters = source.getChapterList(mangaInfo) val chapters = source.getChapterList(manga.toSManga())
.map { it.toSChapter() }
// Get manga from database to account for if it was removed during the update // Get manga from database to account for if it was removed during the update
val dbManga = getManga.await(manga.id) val dbManga = getManga.await(manga.id)
@ -469,27 +461,19 @@ class LibraryUpdateService(
progressCount, progressCount,
manga, manga,
) { mangaWithNotif -> ) { 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 { try {
val networkManga = updateManga.await(mangaWithNotif.toDomainManga()!!.toMangaUpdate())
source.getMangaDetails(mangaWithNotif.toMangaInfo()) } catch (e: Exception) {
val sManga = networkManga.toSManga() logcat(LogPriority.ERROR) { "Manga doesn't exist anymore" }
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)
} }
} catch (e: Throwable) {
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
} }
} }
} }
@ -574,7 +558,7 @@ class LibraryUpdateService(
} }
updatingManga.remove(manga) updatingManga.remove(manga)
completed.andIncrement completed.getAndIncrement()
notifier.showProgressNotification( notifier.showProgressNotification(
updatingManga.map { it.toDomainManga()!! }, updatingManga.map { it.toDomainManga()!! },
completed.get(), completed.get(),

View File

@ -9,10 +9,6 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga 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.chapter.ChapterRecognition
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
@ -20,17 +16,11 @@ import eu.kanade.tachiyomi.util.storage.EpubFile
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import logcat.LogPriority import logcat.LogPriority
import rx.Observable import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@ -120,11 +110,10 @@ class LocalSource(
// Fetch chapters of all the manga // Fetch chapters of all the manga
mangas.forEach { manga -> mangas.forEach { manga ->
val mangaInfo = manga.toMangaInfo()
runBlocking { runBlocking {
val chapters = getChapterList(mangaInfo) val chapters = getChapterList(manga)
if (chapters.isNotEmpty()) { if (chapters.isNotEmpty()) {
val chapter = chapters.last().toSChapter() val chapter = chapters.last()
val format = getFormat(chapter) val format = getFormat(chapter)
if (format is Format.Epub) { if (format is Format.Epub) {
@ -145,47 +134,48 @@ class LocalSource(
} }
// Manga details related // Manga details related
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { override suspend fun getMangaDetails(manga: SManga): SManga {
var mangaInfo = manga
val baseDirsFile = getBaseDirectoriesFiles(context) val baseDirsFile = getBaseDirectoriesFiles(context)
val coverFile = getCoverFile(manga.key, baseDirsFile) getCoverFile(manga.url, baseDirsFile)?.let {
manga.thumbnail_url = it.absolutePath
coverFile?.let {
mangaInfo = mangaInfo.copy(cover = it.absolutePath)
} }
val localDetails = getMangaDirsFiles(manga.key, baseDirsFile) getMangaDirsFiles(manga.url, baseDirsFile)
.firstOrNull { it.extension.equals("json", ignoreCase = true) } .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 }
}
}
if (localDetails != null) { return manga
val obj = json.decodeFromStream<JsonObject>(localDetails.inputStream())
mangaInfo = mangaInfo.copy(
title = obj["title"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.title,
author = obj["author"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.author,
artist = obj["artist"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.artist,
description = obj["description"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.description,
genres = obj["genre"]?.jsonArray?.map { it.jsonPrimitive.content } ?: mangaInfo.genres,
status = obj["status"]?.jsonPrimitive?.intOrNull ?: mangaInfo.status,
)
}
return mangaInfo
} }
// Chapters @Serializable
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> { class MangaDetails(
val sManga = manga.toSManga() val title: String? = null,
val author: String? = null,
val artist: String? = null,
val description: String? = null,
val genre: List<String>? = null,
val status: Int? = null,
)
// Chapters
override suspend fun getChapterList(manga: SManga): List<SChapter> {
val baseDirsFile = getBaseDirectoriesFiles(context) val baseDirsFile = getBaseDirectoriesFiles(context)
return getMangaDirsFiles(manga.key, baseDirsFile) return getMangaDirsFiles(manga.url, baseDirsFile)
// Only keep supported formats // Only keep supported formats
.filter { it.isDirectory || isSupportedFile(it.extension) } .filter { it.isDirectory || isSupportedFile(it.extension) }
.map { chapterFile -> .map { chapterFile ->
SChapter.create().apply { SChapter.create().apply {
url = "${manga.key}/${chapterFile.name}" url = "${manga.url}/${chapterFile.name}"
name = if (chapterFile.isDirectory) { name = if (chapterFile.isDirectory) {
chapterFile.name chapterFile.name
} else { } else {
@ -193,7 +183,7 @@ class LocalSource(
} }
date_upload = chapterFile.lastModified() 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) val format = getFormat(chapterFile)
if (format is Format.Epub) { if (format is Format.Epub) {
@ -203,9 +193,8 @@ class LocalSource(
} }
} }
} }
.map { it.toChapterInfo() }
.sortedWith { c1, c2 -> .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 if (c == 0) c2.name.compareToCaseInsensitiveNaturalOrder(c1.name) else c
} }
.toList() .toList()
@ -224,7 +213,7 @@ class LocalSource(
) )
// Unused stuff // Unused stuff
override suspend fun getPageList(chapter: ChapterInfo) = throw UnsupportedOperationException("Unused") override suspend fun getPageList(chapter: SChapter) = throw UnsupportedOperationException("Unused")
// Miscellaneous // Miscellaneous
private fun isSupportedFile(extension: String): Boolean { private fun isSupportedFile(extension: String): Boolean {

View File

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

View File

@ -19,8 +19,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import rx.Observable import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
class SourceManager( class SourceManager(
private val context: Context, private val context: Context,
@ -115,7 +113,7 @@ class SourceManager(
override val lang: String = sourceData.lang override val lang: String = sourceData.lang
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { override suspend fun getMangaDetails(manga: SManga): SManga {
throw getSourceNotInstalledException() throw getSourceNotInstalledException()
} }
@ -123,7 +121,7 @@ class SourceManager(
return Observable.error(getSourceNotInstalledException()) return Observable.error(getSourceNotInstalledException())
} }
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> { override suspend fun getChapterList(manga: SManga): List<SChapter> {
throw getSourceNotInstalledException() throw getSourceNotInstalledException()
} }
@ -131,7 +129,7 @@ class SourceManager(
return Observable.error(getSourceNotInstalledException()) 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() throw getSourceNotInstalledException()
} }

View File

@ -5,7 +5,6 @@ import eu.kanade.tachiyomi.network.ProgressListener
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
import rx.subjects.Subject import rx.subjects.Subject
import tachiyomi.source.model.PageUrl
@Serializable @Serializable
open class Page( open class Page(
@ -65,16 +64,3 @@ open class Page(
const val ERROR = 4 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 package eu.kanade.tachiyomi.source.model
import data.Chapters import data.Chapters
import tachiyomi.source.model.ChapterInfo
import java.io.Serializable import java.io.Serializable
interface SChapter : Serializable { interface SChapter : Serializable {
@ -38,24 +37,3 @@ interface SChapter : Serializable {
} }
} }
} }
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
}
}

View File

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.source.model package eu.kanade.tachiyomi.source.model
import data.Mangas import data.Mangas
import tachiyomi.source.model.MangaInfo
import java.io.Serializable import java.io.Serializable
interface SManga : Serializable { interface SManga : Serializable {
@ -85,6 +84,18 @@ interface SManga : Serializable {
} }
} }
fun copy() = 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
}
companion object { companion object {
const val UNKNOWN = 0 const val UNKNOWN = 0
const val ONGOING = 1 const val ONGOING = 1
@ -99,30 +110,3 @@ interface SManga : Serializable {
} }
} }
} }
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
}
}

View File

@ -13,7 +13,6 @@ import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.MangaUpdate import eu.kanade.domain.manga.model.MangaUpdate
import eu.kanade.domain.manga.model.hasCustomCover import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.domain.manga.model.toDbManga import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.model.toMangaInfo
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.interactor.InsertTrack
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
@ -23,7 +22,6 @@ import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchCardItem import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchCardItem
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItem import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItem
@ -89,8 +87,7 @@ class SearchPresenter(
presenterScope.launchIO { presenterScope.launchIO {
try { try {
val chapters = source.getChapterList(manga.toMangaInfo()) val chapters = source.getChapterList(manga.toSManga())
.map { it.toSChapter() }
migrateMangaInternal(prevSource, source, chapters, prevManga, manga, replace) migrateMangaInternal(prevSource, source, chapters, prevManga, manga, replace)
} catch (e: Throwable) { } catch (e: Throwable) {

View File

@ -17,7 +17,6 @@ import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga 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.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
@ -27,7 +26,6 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga 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.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxItem import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxItem
import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxSectionItem import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxSectionItem
@ -267,8 +265,8 @@ open class BrowseSourcePresenter(
*/ */
private suspend fun getMangaDetails(manga: Manga): Manga { private suspend fun getMangaDetails(manga: Manga): Manga {
try { try {
val networkManga = source.getMangaDetails(manga.toMangaInfo()) val networkManga = source.getMangaDetails(manga.copy())
manga.copyFrom(networkManga.toSManga()) manga.copyFrom(networkManga)
manga.initialized = true manga.initialized = true
updateManga.await( updateManga.await(
manga manga

View File

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

View File

@ -20,7 +20,6 @@ import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.TriStateFilter import eu.kanade.domain.manga.model.TriStateFilter
import eu.kanade.domain.manga.model.isLocal import eu.kanade.domain.manga.model.isLocal
import eu.kanade.domain.manga.model.toDbManga 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.DeleteTrack
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.interactor.InsertTrack
@ -36,7 +35,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.manga.track.TrackItem import eu.kanade.tachiyomi.ui.manga.track.TrackItem
import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
@ -245,7 +243,7 @@ class MangaPresenter(
updateSuccessState { it.copy(isRefreshingInfo = true) } updateSuccessState { it.copy(isRefreshingInfo = true) }
try { try {
successState?.let { successState?.let {
val networkManga = it.source.getMangaDetails(it.manga.toMangaInfo()) val networkManga = it.source.getMangaDetails(it.manga.toSManga())
updateManga.awaitUpdateFromSource(it.manga, networkManga, manualFetch) updateManga.awaitUpdateFromSource(it.manga, networkManga, manualFetch)
} }
} catch (e: Throwable) { } catch (e: Throwable) {
@ -518,8 +516,7 @@ class MangaPresenter(
updateSuccessState { it.copy(isRefreshingChapter = true) } updateSuccessState { it.copy(isRefreshingChapter = true) }
try { try {
successState?.let { successState -> successState?.let { successState ->
val chapters = successState.source.getChapterList(successState.manga.toMangaInfo()) val chapters = successState.source.getChapterList(successState.manga.toSManga())
.map { it.toSChapter() }
val newChapters = syncChaptersWithSource.await( val newChapters = syncChaptersWithSource.await(
chapters, chapters,

View File

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

View File

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