UnattendedTrackService -> EnhancedTrackService

This commit is contained in:
Jays2Kings 2022-04-03 21:13:43 -04:00
parent a39510d08e
commit ad8871aff5
8 changed files with 106 additions and 20 deletions

View file

@ -25,8 +25,8 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
@ -524,7 +524,7 @@ class LibraryUpdateService(
val newTrack = service.refresh(track)
db.insertTrack(newTrack).executeAsBlocking()
if (service is UnattendedTrackService) {
if (service is EnhancedTrackService) {
syncChaptersWithTrackServiceTwoWay(db, db.getChapters(manga).executeAsBlocking(), track, service)
}
} catch (e: Exception) {

View file

@ -0,0 +1,39 @@
package eu.kanade.tachiyomi.data.track
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.source.Source
/**
* An Enhanced Track Service will never prompt the user to match a manga with the remote.
* It is expected that such Track Service can only work with specific sources and unique IDs.
*/
interface EnhancedTrackService {
/**
* This TrackService will only work with the sources that are accepted by this filter function.
*/
fun accept(source: Source): Boolean {
return source::class.qualifiedName in getAcceptedSources()
}
/**
* Fully qualified source classes that this track service is compatible with.
*/
fun getAcceptedSources(): List<String>
/**
* match is similar to TrackService.search, but only return zero or one match.
*/
suspend fun match(manga: Manga): TrackSearch?
/**
* Checks whether the provided source/track/manga triplet is from this TrackService
*/
fun isTrackFrom(track: Track, manga: Manga, source: Source?): Boolean
/**
* Migrates the given track for the manga to the newSource, if possible
*/
fun migrateTrack(track: Track, manga: Manga, newSource: Source): Track?
}

View file

@ -6,16 +6,16 @@ import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.NoLoginTrackService
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.data.track.updateNewTrackInfo
import eu.kanade.tachiyomi.source.Source
import okhttp3.Dns
import okhttp3.OkHttpClient
class Komga(private val context: Context, id: Int) : TrackService(id), UnattendedTrackService, NoLoginTrackService {
class Komga(private val context: Context, id: Int) : TrackService(id), EnhancedTrackService, NoLoginTrackService {
companion object {
const val UNREAD = 1
@ -107,6 +107,18 @@ class Komga(private val context: Context, id: Int) : TrackService(id), Unattende
override fun accept(source: Source): Boolean = source::class.qualifiedName == ACCEPTED_SOURCE
override fun getAcceptedSources() = listOf("eu.kanade.tachiyomi.extension.all.komga.Komga")
override fun isTrackFrom(track: Track, manga: Manga, source: Source?): Boolean =
track.tracking_url == manga.url && source?.let { accept(it) } == true
override fun migrateTrack(track: Track, manga: Manga, newSource: Source): Track? =
if (accept(newSource)) {
track.also { track.tracking_url = manga.url }
} else {
null
}
override suspend fun match(manga: Manga): TrackSearch? =
try {
api.getTrackSearch(manga.url)

View file

@ -27,9 +27,9 @@ import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.data.library.LibraryServiceListener
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceNotFoundException
@ -879,7 +879,7 @@ class MangaDetailsPresenter(
}
if (trackItem != null) {
db.insertTrack(trackItem).executeAsBlocking()
if (item.service is UnattendedTrackService) {
if (item.service is EnhancedTrackService) {
syncChaptersWithTrackServiceTwoWay(db, chapters, trackItem, item.service)
}
trackItem
@ -922,7 +922,7 @@ class MangaDetailsPresenter(
db.insertTrack(binding).executeAsBlocking()
}
if (service is UnattendedTrackService) {
if (service is EnhancedTrackService) {
syncChaptersWithTrackServiceTwoWay(db, chapters, item, service)
}
}

View file

@ -29,8 +29,8 @@ import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.adapters.ItemAdapter
import com.mikepenz.fastadapter.listeners.addClickListener
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.databinding.TrackChaptersDialogBinding
import eu.kanade.tachiyomi.databinding.TrackScoreDialogBinding
@ -202,7 +202,7 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
return
}
if (item.service is UnattendedTrackService) {
if (item.service is EnhancedTrackService) {
if (item.track != null) {
controller.presenter.removeTracker(item, false)
return

View file

@ -6,6 +6,8 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
@ -34,6 +36,8 @@ class MigrationPresenter(
private val stateRelay = BehaviorRelay.create(state)
private val enhancedServices by lazy { Injekt.get<TrackManager>().services.filterIsInstance<EnhancedTrackService>() }
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
@ -76,17 +80,19 @@ class MigrationPresenter(
fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean) {
val source = sourceManager.get(manga.source) ?: return
val prevSource = sourceManager.get(prevManga.source)
state = state.copy(isReplacingManga = true)
Observable.defer { source.fetchChapterList(manga) }.onErrorReturn { emptyList() }
.doOnNext { migrateMangaInternal(source, it, prevManga, manga, replace) }
.doOnNext { migrateMangaInternal(prevSource, source, it, prevManga, manga, replace) }
.onErrorReturn { emptyList() }.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnUnsubscribe { state = state.copy(isReplacingManga = false) }.subscribe()
}
private fun migrateMangaInternal(
prevSource: Source?,
source: Source,
sourceChapters: List<SChapter>,
prevManga: Manga,
@ -128,12 +134,16 @@ class MigrationPresenter(
}
// Update track
if (migrateTracks) {
val tracks = db.getTracks(prevManga).executeAsBlocking()
for (track in tracks) {
val tracksToUpdate = db.getTracks(prevManga).executeAsBlocking().mapNotNull { track ->
track.id = null
track.manga_id = manga.id!!
val service = enhancedServices
.firstOrNull { it.isTrackFrom(track, prevManga, prevSource) }
if (service != null) service.migrateTrack(track, manga, source)
else track
}
db.insertTracks(tracks).executeAsBlocking()
db.insertTracks(tracksToUpdate).executeAsBlocking()
}
// Update favorite status
if (replace) {

View file

@ -7,11 +7,17 @@ import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
import eu.kanade.tachiyomi.util.system.launchUI
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.withContext
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.Date
@ -22,10 +28,13 @@ class MigrationProcessAdapter(
private val db: DatabaseHelper by injectLazy()
var items: List<MigrationProcessItem> = emptyList()
val preferences: PreferencesHelper by injectLazy()
val sourceManager: SourceManager by injectLazy()
var showOutline = preferences.outlineOnCovers().get()
val menuItemListener: MigrationProcessInterface = controller
private val enhancedServices by lazy { Injekt.get<TrackManager>().services.filterIsInstance<EnhancedTrackService>() }
override fun updateDataSet(items: List<MigrationProcessItem>?) {
this.items = items ?: emptyList()
super.updateDataSet(items)
@ -63,8 +72,13 @@ class MigrationProcessAdapter(
val toMangaObj =
db.getManga(manga.searchResult.get() ?: return@forEach).executeAsBlocking()
?: return@forEach
val prevManga = manga.manga() ?: return@forEach
val source = sourceManager.get(toMangaObj.source) ?: return@forEach
val prevSource = sourceManager.get(prevManga.source)
migrateMangaInternal(
manga.manga() ?: return@forEach,
prevSource,
source,
prevManga,
toMangaObj,
!copy
)
@ -81,8 +95,13 @@ class MigrationProcessAdapter(
val toMangaObj =
db.getManga(manga.searchResult.get() ?: return@launchUI).executeAsBlocking()
?: return@launchUI
val prevManga = manga.manga() ?: return@launchUI
val source = sourceManager.get(toMangaObj.source) ?: return@launchUI
val prevSource = sourceManager.get(prevManga.source)
migrateMangaInternal(
manga.manga() ?: return@launchUI,
prevSource,
source,
prevManga,
toMangaObj,
!copy
)
@ -101,6 +120,8 @@ class MigrationProcessAdapter(
}
private fun migrateMangaInternal(
prevSource: Source?,
source: Source,
prevManga: Manga,
manga: Manga,
replace: Boolean
@ -143,12 +164,16 @@ class MigrationProcessAdapter(
}
// Update track
if (MigrationFlags.hasTracks(flags)) {
val tracks = db.getTracks(prevManga).executeAsBlocking()
for (track in tracks) {
val tracksToUpdate = db.getTracks(prevManga).executeAsBlocking().mapNotNull { track ->
track.id = null
track.manga_id = manga.id!!
val service = enhancedServices
.firstOrNull { it.isTrackFrom(track, prevManga, prevSource) }
if (service != null) service.migrateTrack(track, manga, source)
else track
}
db.insertTracks(tracks).executeAsBlocking()
db.insertTracks(tracksToUpdate).executeAsBlocking()
}
// Update favorite status
if (replace) {

View file

@ -10,9 +10,9 @@ import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.category.addtolibrary.SetCategoriesSheet
@ -192,7 +192,7 @@ fun Manga.autoAddTrack(db: DatabaseHelper, onMangaMoved: () -> Unit) {
val loggedServices = Injekt.get<TrackManager>().services.filter { it.isLogged }
val source = Injekt.get<SourceManager>().getOrStub(this.source)
loggedServices
.filterIsInstance<UnattendedTrackService>()
.filterIsInstance<EnhancedTrackService>()
.filter { it.accept(source) }
.forEach { service ->
launchIO {