Refactor some tracking-related logic

This commit is contained in:
arkon
2023-08-27 10:41:58 -04:00
parent 7644d7c31e
commit 98d6ce2eaf
28 changed files with 104 additions and 151 deletions

View File

@@ -52,7 +52,7 @@ class BackupFileValidator(
val missingTrackers = trackers
.mapNotNull { trackManager.getService(it.toLong()) }
.filter { !it.isLoggedIn }
.map { context.getString(it.nameRes()) }
.map { it.name }
.sorted()
return Results(missingSources, missingTrackers)

View File

@@ -283,7 +283,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
}
if (libraryPreferences.autoUpdateTrackers().get()) {
refreshTracks.await(manga.id)
refreshTracks(manga.id)
}
}
}
@@ -409,13 +409,20 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
val manga = libraryManga.manga
notifier.showProgressNotification(listOf(manga), progressCount++, mangaToUpdate.size)
refreshTracks.await(manga.id)
refreshTracks(manga.id)
}
notifier.cancelProgressNotification()
}
}
private suspend fun refreshTracks(mangaId: Long) {
refreshTracks.await(mangaId).forEach { (_, e) ->
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
}
}
private suspend fun withUpdateNotification(
updatingManga: CopyOnWriteArrayList<Manga>,
completed: AtomicInteger,

View File

@@ -30,7 +30,7 @@ class TrackManager(context: Context) {
val kitsu = Kitsu(KITSU)
val shikimori = Shikimori(SHIKIMORI)
val bangumi = Bangumi(BANGUMI)
val komga = Komga(context, KOMGA)
val komga = Komga(KOMGA)
val mangaUpdates = MangaUpdates(MANGA_UPDATES)
val kavita = Kavita(context, KAVITA)
val suwayomi = Suwayomi(SUWAYOMI)

View File

@@ -5,7 +5,7 @@ import androidx.annotation.CallSuper
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.interactor.SyncChapterProgressWithTrack
import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.domain.track.service.TrackPreferences
@@ -28,20 +28,16 @@ import uy.kohesive.injekt.injectLazy
import java.time.ZoneOffset
import tachiyomi.domain.track.model.Track as DomainTrack
abstract class TrackService(val id: Long) {
abstract class TrackService(val id: Long, val name: String) {
val trackPreferences: TrackPreferences by injectLazy()
val networkService: NetworkHelper by injectLazy()
private val insertTrack: InsertTrack by injectLazy()
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay by injectLazy()
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack by injectLazy()
open val client: OkHttpClient
get() = networkService.client
// Name of the manga sync service to display
@StringRes
abstract fun nameRes(): Int
// Application and remote support for reading dates
open val supportsReadingDates: Boolean = false
@@ -103,7 +99,7 @@ abstract class TrackService(val id: Long) {
}
// TODO: move this to an interactor, and update all trackers based on common data
suspend fun registerTracking(item: Track, mangaId: Long) {
suspend fun register(item: Track, mangaId: Long) {
item.manga_id = mangaId
try {
withIOContext {
@@ -147,7 +143,7 @@ abstract class TrackService(val id: Long) {
}
}
syncChaptersWithTrackServiceTwoWay.await(mangaId, track, this@TrackService)
syncChapterProgressWithTrack.await(mangaId, track, this@TrackService)
}
} catch (e: Throwable) {
withUIContext { Injekt.get<Application>().toast(e.message) }

View File

@@ -12,7 +12,7 @@ import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
import tachiyomi.domain.track.model.Track as DomainTrack
class Anilist(id: Long) : TrackService(id), DeletableTrackService {
class Anilist(id: Long) : TrackService(id, "AniList"), DeletableTrackService {
companion object {
const val READING = 1
@@ -49,9 +49,6 @@ class Anilist(id: Long) : TrackService(id), DeletableTrackService {
}
}
@StringRes
override fun nameRes() = R.string.tracker_anilist
override fun getLogo() = R.drawable.ic_tracker_anilist
override fun getLogoColor() = Color.rgb(18, 25, 35)

View File

@@ -10,7 +10,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
class Bangumi(id: Long) : TrackService(id) {
class Bangumi(id: Long) : TrackService(id, "Bangumi") {
private val json: Json by injectLazy()
@@ -18,9 +18,6 @@ class Bangumi(id: Long) : TrackService(id) {
private val api by lazy { BangumiApi(client, interceptor) }
@StringRes
override fun nameRes() = R.string.tracker_bangumi
override fun getScoreList(): List<String> {
return IntRange(0, 10).map(Int::toString)
}

View File

@@ -14,7 +14,7 @@ import tachiyomi.domain.manga.model.Manga
import java.security.MessageDigest
import tachiyomi.domain.track.model.Track as DomainTrack
class Kavita(private val context: Context, id: Long) : TrackService(id), EnhancedTrackService {
class Kavita(private val context: Context, id: Long) : TrackService(id, "Kavita"), EnhancedTrackService {
companion object {
const val UNREAD = 1
@@ -27,9 +27,6 @@ class Kavita(private val context: Context, id: Long) : TrackService(id), Enhance
private val interceptor by lazy { KavitaInterceptor(this) }
val api by lazy { KavitaApi(client, interceptor) }
@StringRes
override fun nameRes() = R.string.tracker_kavita
override fun getLogo(): Int = R.drawable.ic_tracker_kavita
override fun getLogoColor() = Color.rgb(74, 198, 148)

View File

@@ -115,8 +115,8 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
}
private fun getLatestChapterRead(url: String): Float {
val serieId = getIdFromUrl(url)
val requestUrl = "${getApiFromUrl(url)}/Tachiyomi/latest-chapter?seriesId=$serieId"
val seriesId = getIdFromUrl(url)
val requestUrl = "${getApiFromUrl(url)}/Tachiyomi/latest-chapter?seriesId=$seriesId"
try {
with(json) {
authClient.newCall(GET(requestUrl)).execute().use {
@@ -137,21 +137,21 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
suspend fun getTrackSearch(url: String): TrackSearch = withIOContext {
try {
val serieDto: SeriesDto = with(json) {
val seriesDto: SeriesDto = with(json) {
authClient.newCall(GET(url))
.awaitSuccess()
.parseAs()
}
val track = serieDto.toTrack()
val track = seriesDto.toTrack()
track.apply {
cover_url = serieDto.thumbnail_url.toString()
cover_url = seriesDto.thumbnail_url.toString()
tracking_url = url
total_chapters = getTotalChapters(url)
title = serieDto.name
status = when (serieDto.pagesRead) {
serieDto.pages -> Kavita.COMPLETED
title = seriesDto.name
status = when (seriesDto.pagesRead) {
seriesDto.pages -> Kavita.COMPLETED
0 -> Kavita.UNREAD
else -> Kavita.READING
}

View File

@@ -12,7 +12,7 @@ import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
import java.text.DecimalFormat
class Kitsu(id: Long) : TrackService(id), DeletableTrackService {
class Kitsu(id: Long) : TrackService(id, "Kitsu"), DeletableTrackService {
companion object {
const val READING = 1
@@ -22,9 +22,6 @@ class Kitsu(id: Long) : TrackService(id), DeletableTrackService {
const val PLAN_TO_READ = 5
}
@StringRes
override fun nameRes() = R.string.tracker_kitsu
override val supportsReadingDates: Boolean = true
private val json: Json by injectLazy()

View File

@@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.data.track.komga
import android.content.Context
import android.graphics.Color
import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R
@@ -14,7 +13,7 @@ import okhttp3.OkHttpClient
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.track.model.Track as DomainTrack
class Komga(private val context: Context, id: Long) : TrackService(id), EnhancedTrackService {
class Komga(id: Long) : TrackService(id, "Komga"), EnhancedTrackService {
companion object {
const val UNREAD = 1
@@ -29,9 +28,6 @@ class Komga(private val context: Context, id: Long) : TrackService(id), Enhanced
val api by lazy { KomgaApi(client) }
@StringRes
override fun nameRes() = R.string.tracker_komga
override fun getLogo() = R.drawable.ic_tracker_komga
override fun getLogoColor() = Color.rgb(51, 37, 50)

View File

@@ -17,7 +17,7 @@ import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.system.logcat
import uy.kohesive.injekt.injectLazy
const val READLIST_API = "/api/v1/readlists"
private const val READLIST_API = "/api/v1/readlists"
class KomgaApi(private val client: OkHttpClient) {

View File

@@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch
import eu.kanade.tachiyomi.data.track.model.TrackSearch
class MangaUpdates(id: Long) : TrackService(id), DeletableTrackService {
class MangaUpdates(id: Long) : TrackService(id, "MangaUpdates"), DeletableTrackService {
companion object {
const val READING_LIST = 0
@@ -24,9 +24,6 @@ class MangaUpdates(id: Long) : TrackService(id), DeletableTrackService {
private val api by lazy { MangaUpdatesApi(interceptor, client) }
@StringRes
override fun nameRes(): Int = R.string.tracker_manga_updates
override fun getLogo(): Int = R.drawable.ic_manga_updates
override fun getLogoColor(): Int = Color.rgb(146, 160, 173)

View File

@@ -11,7 +11,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
class MyAnimeList(id: Long) : TrackService(id), DeletableTrackService {
class MyAnimeList(id: Long) : TrackService(id, "MyAnimeList"), DeletableTrackService {
companion object {
const val READING = 1
@@ -30,9 +30,6 @@ class MyAnimeList(id: Long) : TrackService(id), DeletableTrackService {
private val interceptor by lazy { MyAnimeListInterceptor(this, getPassword()) }
private val api by lazy { MyAnimeListApi(client, interceptor) }
@StringRes
override fun nameRes() = R.string.tracker_myanimelist
override val supportsReadingDates: Boolean = true
override fun getLogo() = R.drawable.ic_tracker_mal

View File

@@ -11,7 +11,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
class Shikimori(id: Long) : TrackService(id), DeletableTrackService {
class Shikimori(id: Long) : TrackService(id, "Shikimori"), DeletableTrackService {
companion object {
const val READING = 1
@@ -28,9 +28,6 @@ class Shikimori(id: Long) : TrackService(id), DeletableTrackService {
private val api by lazy { ShikimoriApi(client, interceptor) }
@StringRes
override fun nameRes() = R.string.tracker_shikimori
override fun getScoreList(): List<String> {
return IntRange(0, 10).map(Int::toString)
}

View File

@@ -122,7 +122,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
}
}
suspend fun findLibManga(track: Track, user_id: String): Track? {
suspend fun findLibManga(track: Track, userId: String): Track? {
return withIOContext {
val urlMangas = "$apiUrl/mangas".toUri().buildUpon()
.appendPath(track.media_id.toString())
@@ -134,7 +134,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
}
val url = "$apiUrl/v2/user_rates".toUri().buildUpon()
.appendQueryParameter("user_id", user_id)
.appendQueryParameter("user_id", userId)
.appendQueryParameter("target_id", track.media_id.toString())
.appendQueryParameter("target_type", "Manga")
.build()

View File

@@ -11,13 +11,10 @@ import eu.kanade.tachiyomi.source.Source
import tachiyomi.domain.manga.model.Manga as DomainManga
import tachiyomi.domain.track.model.Track as DomainTrack
class Suwayomi(id: Long) : TrackService(id), EnhancedTrackService {
class Suwayomi(id: Long) : TrackService(id, "Suwayomi"), EnhancedTrackService {
val api by lazy { TachideskApi() }
@StringRes
override fun nameRes() = R.string.tracker_suwayomi
override fun getLogo() = R.drawable.ic_tracker_suwayomi
override fun getLogoColor() = Color.rgb(255, 35, 35) // TODO

View File

@@ -28,19 +28,19 @@ class TachideskApi {
private val network: NetworkHelper by injectLazy()
private val json: Json by injectLazy()
val client: OkHttpClient =
private val client: OkHttpClient =
network.client.newBuilder()
.dns(Dns.SYSTEM) // don't use DNS over HTTPS as it breaks IP addressing
.build()
fun headersBuilder(): Headers.Builder = Headers.Builder().apply {
private fun headersBuilder(): Headers.Builder = Headers.Builder().apply {
if (basePassword.isNotEmpty() && baseLogin.isNotEmpty()) {
val credentials = Credentials.basic(baseLogin, basePassword)
add("Authorization", credentials)
}
}
val headers: Headers by lazy { headersBuilder().build() }
private val headers: Headers by lazy { headersBuilder().build() }
private val baseUrl by lazy { getPrefBaseUrl() }
private val baseLogin by lazy { getPrefBaseLogin() }
@@ -100,7 +100,7 @@ class TachideskApi {
return getTrackSearch(track.tracking_url)
}
val tachideskExtensionId by lazy {
private val tachideskExtensionId by lazy {
val key = "tachidesk/en/1"
val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray())
(0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE
@@ -110,6 +110,10 @@ class TachideskApi {
Injekt.get<Application>().getSharedPreferences("source_$tachideskExtensionId", 0x0000)
}
private fun getPrefBaseUrl(): String = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!!
private fun getPrefBaseLogin(): String = preferences.getString(LOGIN_TITLE, LOGIN_DEFAULT)!!
private fun getPrefBasePassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!!
companion object {
private const val ADDRESS_TITLE = "Server URL Address"
private const val ADDRESS_DEFAULT = ""
@@ -118,8 +122,4 @@ class TachideskApi {
private const val PASSWORD_TITLE = "Password (Basic Auth)"
private const val PASSWORD_DEFAULT = ""
}
private fun getPrefBaseUrl(): String = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!!
private fun getPrefBaseLogin(): String = preferences.getString(LOGIN_TITLE, LOGIN_DEFAULT)!!
private fun getPrefBasePassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!!
}