-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add trackers support * Cleanup Tracker Code * Add GraphQL support for Tracking * Fix lint and deprecation errors * remove password from logs * Fixes after merge * Disable tracking for now * More disabled --------- Co-authored-by: Syer10 <[email protected]>
- Loading branch information
1 parent
230427e
commit 5a178ad
Showing
44 changed files
with
3,726 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (C) 2017 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
@file:Suppress("NOTHING_TO_INLINE") // Aliases to public API. | ||
|
||
package androidx.core.net | ||
|
||
import android.net.Uri | ||
import java.io.File | ||
|
||
/** | ||
* Creates a Uri from the given encoded URI string. | ||
* | ||
* @see Uri.parse | ||
*/ | ||
public inline fun String.toUri(): Uri = Uri.parse(this) | ||
|
||
/** | ||
* Creates a Uri from the given file. | ||
* | ||
* @see Uri.fromFile | ||
*/ | ||
public inline fun File.toUri(): Uri = Uri.fromFile(this) | ||
|
||
/** | ||
* Creates a [File] from the given [Uri]. Note that this will throw an | ||
* [IllegalArgumentException] when invoked on a [Uri] that lacks `file` scheme. | ||
*/ | ||
public fun Uri.toFile(): File { | ||
require(scheme == "file") { "Uri lacks 'file' scheme: $this" } | ||
return File(requireNotNull(path) { "Uri path is null: $this" }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
server/src/main/kotlin/eu/kanade/tachiyomi/util/PkceUtil.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package eu.kanade.tachiyomi.util | ||
|
||
import android.util.Base64 | ||
import java.security.SecureRandom | ||
|
||
object PkceUtil { | ||
private const val PKCE_BASE64_ENCODE_SETTINGS = Base64.NO_WRAP or Base64.NO_PADDING or Base64.URL_SAFE | ||
|
||
fun generateCodeVerifier(): String { | ||
val codeVerifier = ByteArray(50) | ||
SecureRandom().nextBytes(codeVerifier) | ||
return Base64.encodeToString(codeVerifier, PKCE_BASE64_ENCODE_SETTINGS) | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
server/src/main/kotlin/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package eu.kanade.tachiyomi.util.lang | ||
|
||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.CoroutineStart | ||
import kotlinx.coroutines.DelicateCoroutinesApi | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.GlobalScope | ||
import kotlinx.coroutines.Job | ||
import kotlinx.coroutines.NonCancellable | ||
import kotlinx.coroutines.launch | ||
import kotlinx.coroutines.withContext | ||
|
||
/** | ||
* Think twice before using this. This is a delicate API. It is easy to accidentally create resource or memory leaks when GlobalScope is used. | ||
* | ||
* **Possible replacements** | ||
* - suspend function | ||
* - custom scope like view or presenter scope | ||
*/ | ||
@DelicateCoroutinesApi | ||
fun launchUI(block: suspend CoroutineScope.() -> Unit): Job = GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT, block) | ||
|
||
/** | ||
* Think twice before using this. This is a delicate API. It is easy to accidentally create resource or memory leaks when GlobalScope is used. | ||
* | ||
* **Possible replacements** | ||
* - suspend function | ||
* - custom scope like view or presenter scope | ||
*/ | ||
@DelicateCoroutinesApi | ||
fun launchIO(block: suspend CoroutineScope.() -> Unit): Job = GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT, block) | ||
|
||
/** | ||
* Think twice before using this. This is a delicate API. It is easy to accidentally create resource or memory leaks when GlobalScope is used. | ||
* | ||
* **Possible replacements** | ||
* - suspend function | ||
* - custom scope like view or presenter scope | ||
*/ | ||
@DelicateCoroutinesApi | ||
fun launchNow(block: suspend CoroutineScope.() -> Unit): Job = GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED, block) | ||
|
||
fun CoroutineScope.launchUI(block: suspend CoroutineScope.() -> Unit): Job = launch(Dispatchers.Main, block = block) | ||
|
||
fun CoroutineScope.launchIO(block: suspend CoroutineScope.() -> Unit): Job = launch(Dispatchers.IO, block = block) | ||
|
||
fun CoroutineScope.launchNonCancellable(block: suspend CoroutineScope.() -> Unit): Job = launchIO { withContext(NonCancellable, block) } | ||
|
||
suspend fun <T> withUIContext(block: suspend CoroutineScope.() -> T) = | ||
withContext( | ||
Dispatchers.Main, | ||
block, | ||
) | ||
|
||
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T) = | ||
withContext( | ||
Dispatchers.IO, | ||
block, | ||
) | ||
|
||
suspend fun <T> withNonCancellableContext(block: suspend CoroutineScope.() -> T) = withContext(NonCancellable, block) |
112 changes: 112 additions & 0 deletions
112
server/src/main/kotlin/suwayomi/tachidesk/graphql/dataLoaders/TrackDataLoader.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* Copyright (C) Contributors to the Suwayomi project | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
package suwayomi.tachidesk.graphql.dataLoaders | ||
|
||
import com.expediagroup.graphql.dataloader.KotlinDataLoader | ||
import org.dataloader.DataLoader | ||
import org.dataloader.DataLoaderFactory | ||
import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger | ||
import org.jetbrains.exposed.sql.addLogger | ||
import org.jetbrains.exposed.sql.select | ||
import org.jetbrains.exposed.sql.transactions.transaction | ||
import suwayomi.tachidesk.graphql.types.TrackRecordNodeList | ||
import suwayomi.tachidesk.graphql.types.TrackRecordNodeList.Companion.toNodeList | ||
import suwayomi.tachidesk.graphql.types.TrackRecordType | ||
import suwayomi.tachidesk.graphql.types.TrackerType | ||
import suwayomi.tachidesk.manga.impl.track.tracker.TrackerManager | ||
import suwayomi.tachidesk.manga.impl.track.tracker.model.toTrack | ||
import suwayomi.tachidesk.manga.model.table.TrackRecordTable | ||
import suwayomi.tachidesk.server.JavalinSetup.future | ||
|
||
class TrackerDataLoader : KotlinDataLoader<Int, TrackerType> { | ||
override val dataLoaderName = "TrackerDataLoader" | ||
|
||
override fun getDataLoader(): DataLoader<Int, TrackerType> = | ||
DataLoaderFactory.newDataLoader { ids -> | ||
future { | ||
ids.map { id -> | ||
TrackerManager.getTracker(id)?.let { TrackerType(it) } | ||
} | ||
} | ||
} | ||
} | ||
|
||
class TrackRecordsForMangaIdDataLoader : KotlinDataLoader<Int, TrackRecordNodeList> { | ||
override val dataLoaderName = "TrackRecordsForMangaIdDataLoader" | ||
|
||
override fun getDataLoader(): DataLoader<Int, TrackRecordNodeList> = | ||
DataLoaderFactory.newDataLoader { ids -> | ||
future { | ||
transaction { | ||
addLogger(Slf4jSqlDebugLogger) | ||
val trackRecordsByMangaId = | ||
TrackRecordTable.select { TrackRecordTable.mangaId inList ids } | ||
.map { TrackRecordType(it) } | ||
.groupBy { it.mangaId } | ||
ids.map { (trackRecordsByMangaId[it] ?: emptyList()).toNodeList() } | ||
} | ||
} | ||
} | ||
} | ||
|
||
class DisplayScoreForTrackRecordDataLoader : KotlinDataLoader<Int, String> { | ||
override val dataLoaderName = "DisplayScoreForTrackRecordDataLoader" | ||
|
||
override fun getDataLoader(): DataLoader<Int, String> = | ||
DataLoaderFactory.newDataLoader<Int, String> { ids -> | ||
future { | ||
transaction { | ||
addLogger(Slf4jSqlDebugLogger) | ||
val trackRecords = | ||
TrackRecordTable.select { TrackRecordTable.id inList ids } | ||
.toList() | ||
.map { it.toTrack() } | ||
.associateBy { it.id!! } | ||
.mapValues { TrackerManager.getTracker(it.value.sync_id)?.displayScore(it.value) } | ||
|
||
ids.map { trackRecords[it] } | ||
} | ||
} | ||
} | ||
} | ||
|
||
class TrackRecordsForTrackerIdDataLoader : KotlinDataLoader<Int, TrackRecordNodeList> { | ||
override val dataLoaderName = "TrackRecordsForTrackerIdDataLoader" | ||
|
||
override fun getDataLoader(): DataLoader<Int, TrackRecordNodeList> = | ||
DataLoaderFactory.newDataLoader { ids -> | ||
future { | ||
transaction { | ||
addLogger(Slf4jSqlDebugLogger) | ||
val trackRecordsBySyncId = | ||
TrackRecordTable.select { TrackRecordTable.syncId inList ids } | ||
.map { TrackRecordType(it) } | ||
.groupBy { it.mangaId } | ||
ids.map { (trackRecordsBySyncId[it] ?: emptyList()).toNodeList() } | ||
} | ||
} | ||
} | ||
} | ||
|
||
class TrackRecordDataLoader : KotlinDataLoader<Int, TrackRecordType> { | ||
override val dataLoaderName = "TrackRecordDataLoader" | ||
|
||
override fun getDataLoader(): DataLoader<Int, TrackRecordType> = | ||
DataLoaderFactory.newDataLoader { ids -> | ||
future { | ||
transaction { | ||
addLogger(Slf4jSqlDebugLogger) | ||
val trackRecordsId = | ||
TrackRecordTable.select { TrackRecordTable.id inList ids } | ||
.map { TrackRecordType(it) } | ||
.associateBy { it.id } | ||
ids.map { trackRecordsId[it] } | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.