mirror of
https://github.com/Suwayomi/Tachidesk.git
synced 2025-12-10 06:42:07 +01:00
Feature/tracking gql add option to delete remote binding on tracker (#919)
* Extract unbinding track into function * Introduce new unbind mutation * Add option to delete track binding on track service --------- Co-authored-by: Mitchell Syer <Syer10@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package suwayomi.tachidesk.graphql.mutations
|
||||
|
||||
import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated
|
||||
import com.expediagroup.graphql.generator.annotations.GraphQLDescription
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
@@ -133,6 +135,36 @@ class TrackMutation {
|
||||
}
|
||||
}
|
||||
|
||||
data class UnbindTrackInput(
|
||||
val clientMutationId: String? = null,
|
||||
val recordId: Int,
|
||||
@GraphQLDescription("This will only work if the tracker of the track record supports deleting tracks")
|
||||
val deleteRemoteTrack: Boolean? = null,
|
||||
)
|
||||
|
||||
data class UnbindTrackPayload(
|
||||
val clientMutationId: String?,
|
||||
val trackRecord: TrackRecordType?,
|
||||
)
|
||||
|
||||
fun unbindTrack(input: UnbindTrackInput): CompletableFuture<UnbindTrackPayload> {
|
||||
val (clientMutationId, recordId, deleteRemoteTrack) = input
|
||||
|
||||
return future {
|
||||
Track.unbind(recordId, deleteRemoteTrack)
|
||||
val trackRecord =
|
||||
transaction {
|
||||
TrackRecordTable.select {
|
||||
TrackRecordTable.id eq recordId
|
||||
}.firstOrNull()
|
||||
}
|
||||
UnbindTrackPayload(
|
||||
clientMutationId,
|
||||
trackRecord?.let { TrackRecordType(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class TrackProgressInput(
|
||||
val clientMutationId: String? = null,
|
||||
val mangaId: Int,
|
||||
@@ -168,6 +200,7 @@ class TrackMutation {
|
||||
val scoreString: String? = null,
|
||||
val startDate: Long? = null,
|
||||
val finishDate: Long? = null,
|
||||
@GraphQLDeprecated("Replaced with \"unbindTrack\" mutation", replaceWith = ReplaceWith("unbindTrack"))
|
||||
val unbind: Boolean? = null,
|
||||
)
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ class TrackerType(
|
||||
val icon: String,
|
||||
val isLoggedIn: Boolean,
|
||||
val authUrl: String?,
|
||||
val supportsTrackDeletion: Boolean?,
|
||||
) : Node {
|
||||
constructor(tracker: Tracker) : this(
|
||||
tracker.isLoggedIn,
|
||||
@@ -36,6 +37,7 @@ class TrackerType(
|
||||
} else {
|
||||
tracker.authUrl()
|
||||
},
|
||||
tracker.supportsTrackDeletion,
|
||||
)
|
||||
|
||||
fun statuses(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<TrackStatusType>> {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.exposed.sql.insertAndGetId
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.DeletableTrackService
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.TrackerManager
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.model.Track
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.model.toTrack
|
||||
@@ -186,11 +187,29 @@ object Track {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun unbind(
|
||||
recordId: Int,
|
||||
deleteRemoteTrack: Boolean? = false,
|
||||
) {
|
||||
val recordDb =
|
||||
transaction {
|
||||
TrackRecordTable.select { TrackRecordTable.id eq recordId }.first()
|
||||
}
|
||||
|
||||
val tracker = TrackerManager.getTracker(recordDb[TrackRecordTable.trackerId])!!
|
||||
|
||||
if (deleteRemoteTrack == true && tracker is DeletableTrackService) {
|
||||
tracker.delete(recordDb.toTrack())
|
||||
}
|
||||
|
||||
transaction {
|
||||
TrackRecordTable.deleteWhere { TrackRecordTable.id eq recordId }
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun update(input: UpdateInput) {
|
||||
if (input.unbind == true) {
|
||||
transaction {
|
||||
TrackRecordTable.deleteWhere { TrackRecordTable.id eq input.recordId }
|
||||
}
|
||||
unbind(input.recordId)
|
||||
return
|
||||
}
|
||||
val recordDb =
|
||||
|
||||
@@ -6,5 +6,5 @@ import suwayomi.tachidesk.manga.impl.track.tracker.model.Track
|
||||
* For track services api that support deleting a manga entry for a user's list
|
||||
*/
|
||||
interface DeletableTrackService {
|
||||
suspend fun delete(track: Track): Track
|
||||
suspend fun delete(track: Track)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ abstract class Tracker(val id: Int, val name: String) {
|
||||
// Application and remote support for reading dates
|
||||
open val supportsReadingDates: Boolean = false
|
||||
|
||||
abstract val supportsTrackDeletion: Boolean
|
||||
|
||||
override fun toString() = "$name ($id) (isLoggedIn= $isLoggedIn, isAuthExpired= ${getIfAuthExpired()})"
|
||||
|
||||
abstract fun getLogo(): String
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package suwayomi.tachidesk.manga.impl.track.tracker.anilist
|
||||
|
||||
import android.annotation.StringRes
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import mu.KotlinLogging
|
||||
@@ -29,6 +28,8 @@ class Anilist(id: Int) : Tracker(id, "AniList"), DeletableTrackService {
|
||||
const val POINT_3 = "POINT_3"
|
||||
}
|
||||
|
||||
override val supportsTrackDeletion: Boolean = true
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
private val interceptor by lazy { AnilistInterceptor(this) }
|
||||
@@ -157,13 +158,13 @@ class Anilist(id: Int) : Tracker(id, "AniList"), DeletableTrackService {
|
||||
return api.updateLibManga(track)
|
||||
}
|
||||
|
||||
override suspend fun delete(track: Track): Track {
|
||||
override suspend fun delete(track: Track) {
|
||||
if (track.library_id == null || track.library_id!! == 0L) {
|
||||
val libManga = api.findLibManga(track, getUsername().toInt()) ?: return track
|
||||
val libManga = api.findLibManga(track, getUsername().toInt()) ?: return
|
||||
track.library_id = libManga.library_id
|
||||
}
|
||||
|
||||
return api.deleteLibManga(track)
|
||||
api.deleteLibManga(track)
|
||||
}
|
||||
|
||||
override suspend fun bind(
|
||||
|
||||
@@ -115,7 +115,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteLibManga(track: Track): Track {
|
||||
suspend fun deleteLibManga(track: Track) {
|
||||
return withIOContext {
|
||||
val query =
|
||||
"""
|
||||
@@ -135,7 +135,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
}
|
||||
authClient.newCall(POST(API_URL, body = payload.toString().toRequestBody(jsonMime)))
|
||||
.awaitSuccess()
|
||||
track
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package suwayomi.tachidesk.manga.impl.track.tracker.mangaupdates
|
||||
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.DeletableTrackService
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.Tracker
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.mangaupdates.dto.ListItem
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.mangaupdates.dto.Rating
|
||||
@@ -8,8 +9,7 @@ import suwayomi.tachidesk.manga.impl.track.tracker.mangaupdates.dto.toTrackSearc
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.model.Track
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.model.TrackSearch
|
||||
|
||||
class MangaUpdates(id: Int) : Tracker(id, "MangaUpdates") {
|
||||
// , DeletableTracker
|
||||
class MangaUpdates(id: Int) : Tracker(id, "MangaUpdates"), DeletableTrackService {
|
||||
companion object {
|
||||
const val READING_LIST = 0
|
||||
const val WISH_LIST = 1
|
||||
@@ -31,6 +31,8 @@ class MangaUpdates(id: Int) : Tracker(id, "MangaUpdates") {
|
||||
}
|
||||
}
|
||||
|
||||
override val supportsTrackDeletion: Boolean = true
|
||||
|
||||
private val interceptor by lazy { MangaUpdatesInterceptor(this) }
|
||||
|
||||
private val api by lazy { MangaUpdatesApi(interceptor, client) }
|
||||
@@ -74,9 +76,9 @@ class MangaUpdates(id: Int) : Tracker(id, "MangaUpdates") {
|
||||
return track
|
||||
}
|
||||
|
||||
// override suspend fun delete(track: Track) {
|
||||
// api.deleteSeriesFromList(track)
|
||||
// }
|
||||
override suspend fun delete(track: Track) {
|
||||
api.deleteSeriesFromList(track)
|
||||
}
|
||||
|
||||
override suspend fun bind(
|
||||
track: Track,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package suwayomi.tachidesk.manga.impl.track.tracker.myanimelist
|
||||
|
||||
import android.annotation.StringRes
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import mu.KotlinLogging
|
||||
@@ -26,6 +25,8 @@ class MyAnimeList(id: Int) : Tracker(id, "MyAnimeList"), DeletableTrackService {
|
||||
private const val SEARCH_LIST_PREFIX = "my:"
|
||||
}
|
||||
|
||||
override val supportsTrackDeletion: Boolean = true
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
private val interceptor by lazy { MyAnimeListInterceptor(this) }
|
||||
@@ -94,8 +95,8 @@ class MyAnimeList(id: Int) : Tracker(id, "MyAnimeList"), DeletableTrackService {
|
||||
return api.updateItem(track)
|
||||
}
|
||||
|
||||
override suspend fun delete(track: Track): Track {
|
||||
return api.deleteItem(track)
|
||||
override suspend fun delete(track: Track) {
|
||||
api.deleteItem(track)
|
||||
}
|
||||
|
||||
override suspend fun bind(
|
||||
|
||||
@@ -164,18 +164,15 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteItem(track: Track): Track {
|
||||
suspend fun deleteItem(track: Track) {
|
||||
return withIOContext {
|
||||
val request =
|
||||
Request.Builder()
|
||||
.url(mangaUrl(track.media_id).toString())
|
||||
.delete()
|
||||
.build()
|
||||
with(json) {
|
||||
authClient.newCall(request)
|
||||
.awaitSuccess()
|
||||
track
|
||||
}
|
||||
authClient.newCall(request)
|
||||
.awaitSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user