Remove dependency injection from core module and data module from presentation-widget module

Includes side effects:
- No longer need to restart app for user agent string change to take effect
- parseAs extension function requires a Json instance in the calling context, which doesn't necessarily need to be the default one provided by Injekt

(cherry picked from commit 93523ef50b80ef294866bfb0da54e236cdf2d9f6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
#	core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt
#	core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt
#	domain/build.gradle.kts
#	source-api/build.gradle.kts
This commit is contained in:
arkon
2023-02-20 19:02:38 -05:00
committed by Jobobby04
parent 2e1c83442e
commit 6563490513
42 changed files with 864 additions and 657 deletions
@@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import exh.log.xLogD
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.add
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject
@@ -21,6 +22,7 @@ import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.util.concurrent.TimeUnit
class BilibiliHandler(currentClient: OkHttpClient) {
@@ -35,6 +37,8 @@ class BilibiliHandler(currentClient: OkHttpClient) {
.rateLimit(1, 1, TimeUnit.SECONDS)
.build()
val json by injectLazy<Json>()
suspend fun fetchPageList(externalUrl: String, chapterNumber: String): List<Page> {
// Sometimes the urls direct it to the manga page instead, so we try to find the correct chapter
// Though these seem to be older chapters, so maybe remove this later
@@ -97,7 +101,7 @@ class BilibiliHandler(currentClient: OkHttpClient) {
}
fun chapterListParse(response: Response): List<SChapter> {
val result = response.parseAs<BilibiliResultDto<BilibiliComicDto>>()
val result = with(json) { response.parseAs<BilibiliResultDto<BilibiliComicDto>>() }
if (result.code != 0) {
return emptyList()
@@ -140,7 +144,7 @@ class BilibiliHandler(currentClient: OkHttpClient) {
}
private fun pageListParse(response: Response): List<Page> {
val result = response.parseAs<BilibiliResultDto<BilibiliReader>>()
val result = with(json) { response.parseAs<BilibiliResultDto<BilibiliReader>>() }
if (result.code != 0) {
return emptyList()
@@ -177,7 +181,9 @@ class BilibiliHandler(currentClient: OkHttpClient) {
}
private fun imageUrlParse(response: Response): String {
val result = response.parseAs<BilibiliResultDto<List<BilibiliPageDto>>>()
val result = with(json) {
response.parseAs<BilibiliResultDto<List<BilibiliPageDto>>>()
}
val page = result.data!![0]
return "${page.url}?token=${page.token}"
@@ -80,7 +80,7 @@ class MangaDexAuthInterceptor(
val oauthResponse = chain.proceed(MdUtil.refreshTokenRequest(oauth!!))
if (oauthResponse.isSuccessful) {
oauthResponse.parseAs<OAuth>()
with(MdUtil.jsonParser) { oauthResponse.parseAs<OAuth>() }
} else {
oauthResponse.close()
null
@@ -35,7 +35,11 @@ class MangaDexLoginHelper(
.build()
val error = kotlin.runCatching {
val data = client.newCall(POST(MdApi.baseAuthUrl + MdApi.token, body = loginFormBody)).awaitSuccess().parseAs<OAuth>()
val data = with(MdUtil.jsonParser) {
client.newCall(
POST(MdApi.baseAuthUrl + MdApi.token, body = loginFormBody),
).awaitSuccess().parseAs<OAuth>()
}
mangaDexAuthInterceptor.setAuth(data)
}.exceptionOrNull()
@@ -26,147 +26,173 @@ class MangaDexAuthService(
) {
suspend fun userFollowList(offset: Int): MangaListDto {
return client.newCall(
GET(
"${MdApi.userFollows}?limit=100&offset=$offset&includes[]=${MdConstants.Types.coverArt}",
headers,
CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
"${MdApi.userFollows}?limit=100&offset=$offset&includes[]=${MdConstants.Types.coverArt}",
headers,
CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun readingStatusForManga(mangaId: String): ReadingStatusDto {
return client.newCall(
GET(
"${MdApi.manga}/$mangaId/status",
headers,
CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
"${MdApi.manga}/$mangaId/status",
headers,
CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun readChaptersForManga(mangaId: String): ReadChapterDto {
return client.newCall(
GET(
"${MdApi.manga}/$mangaId/read",
headers,
CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
"${MdApi.manga}/$mangaId/read",
headers,
CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun updateReadingStatusForManga(
mangaId: String,
readingStatusDto: ReadingStatusDto,
): ResultDto {
return client.newCall(
POST(
"${MdApi.manga}/$mangaId/status",
headers,
body = MdUtil.encodeToBody(readingStatusDto),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
POST(
"${MdApi.manga}/$mangaId/status",
headers,
body = MdUtil.encodeToBody(readingStatusDto),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun readingStatusAllManga(): ReadingStatusMapDto {
return client.newCall(
GET(
MdApi.readingStatusForAllManga,
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.readingStatusForAllManga,
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun readingStatusByType(status: String): ReadingStatusMapDto {
return client.newCall(
GET(
"${MdApi.readingStatusForAllManga}?status=$status",
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
"${MdApi.readingStatusForAllManga}?status=$status",
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun markChapterRead(chapterId: String): ResultDto {
return client.newCall(
POST(
"${MdApi.chapter}/$chapterId/read",
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
POST(
"${MdApi.chapter}/$chapterId/read",
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun markChapterUnRead(chapterId: String): ResultDto {
return client.newCall(
Request.Builder()
.url("${MdApi.chapter}/$chapterId/read")
.delete()
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
Request.Builder()
.url("${MdApi.chapter}/$chapterId/read")
.delete()
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).awaitSuccess().parseAs()
}
}
suspend fun followManga(mangaId: String): ResultDto {
return client.newCall(
POST(
"${MdApi.manga}/$mangaId/follow",
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
POST(
"${MdApi.manga}/$mangaId/follow",
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun unfollowManga(mangaId: String): ResultDto {
return client.newCall(
Request.Builder()
.url("${MdApi.manga}/$mangaId/follow")
.delete()
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
Request.Builder()
.url("${MdApi.manga}/$mangaId/follow")
.delete()
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).awaitSuccess().parseAs()
}
}
suspend fun updateMangaRating(mangaId: String, rating: Int): ResultDto {
return client.newCall(
POST(
"${MdApi.rating}/$mangaId",
headers,
body = MdUtil.encodeToBody(RatingDto(rating)),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
POST(
"${MdApi.rating}/$mangaId",
headers,
body = MdUtil.encodeToBody(RatingDto(rating)),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun deleteMangaRating(mangaId: String): ResultDto {
return client.newCall(
Request.Builder()
.delete()
.url("${MdApi.rating}/$mangaId")
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
Request.Builder()
.delete()
.url("${MdApi.rating}/$mangaId")
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).awaitSuccess().parseAs()
}
}
suspend fun mangasRating(vararg mangaIds: String): RatingResponseDto {
return client.newCall(
GET(
MdApi.rating.toHttpUrl()
.newBuilder()
.apply {
mangaIds.forEach {
addQueryParameter("manga[]", it)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.rating.toHttpUrl()
.newBuilder()
.apply {
mangaIds.forEach {
addQueryParameter("manga[]", it)
}
}
}
.build(),
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
.build(),
headers,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
}
@@ -31,77 +31,85 @@ class MangaDexService(
suspend fun viewMangas(
ids: List<String>,
): MangaListDto {
return client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addQueryParameter("includes[]", MdConstants.Types.coverArt)
addQueryParameter("limit", ids.size.toString())
ids.forEach {
addQueryParameter("ids[]", it)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addQueryParameter("includes[]", MdConstants.Types.coverArt)
addQueryParameter("limit", ids.size.toString())
ids.forEach {
addQueryParameter("ids[]", it)
}
}
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun viewManga(
id: String,
): MangaDto {
return client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addPathSegment(id)
addQueryParameter("includes[]", MdConstants.Types.coverArt)
addQueryParameter("includes[]", MdConstants.Types.author)
addQueryParameter("includes[]", MdConstants.Types.artist)
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addPathSegment(id)
addQueryParameter("includes[]", MdConstants.Types.coverArt)
addQueryParameter("includes[]", MdConstants.Types.author)
addQueryParameter("includes[]", MdConstants.Types.artist)
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun mangasRating(
vararg ids: String,
): StatisticsDto {
return client.newCall(
GET(
MdApi.statistics.toHttpUrl()
.newBuilder()
.apply {
ids.forEach { id ->
addQueryParameter("manga[]", id)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.statistics.toHttpUrl()
.newBuilder()
.apply {
ids.forEach { id ->
addQueryParameter("manga[]", id)
}
}
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun aggregateChapters(
id: String,
translatedLanguage: String,
): AggregateDto {
return client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addPathSegment(id)
addPathSegment("aggregate")
addQueryParameter("translatedLanguage[]", translatedLanguage)
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addPathSegment(id)
addPathSegment("aggregate")
addQueryParameter("translatedLanguage[]", translatedLanguage)
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
private fun String.splitString() = replace("\n", "").split(',').trimAll().dropEmpty()
@@ -137,56 +145,68 @@ class MangaDexService(
}
.build()
return client.newCall(
GET(
url,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
url,
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun viewChapter(id: String): ChapterDto {
return client.newCall(GET("${MdApi.chapter}/$id", cache = CacheControl.FORCE_NETWORK))
.awaitSuccess()
.parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(GET("${MdApi.chapter}/$id", cache = CacheControl.FORCE_NETWORK))
.awaitSuccess()
.parseAs()
}
}
suspend fun randomManga(): MangaDto {
return client.newCall(GET("${MdApi.manga}/random", cache = CacheControl.FORCE_NETWORK))
.awaitSuccess()
.parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(GET("${MdApi.manga}/random", cache = CacheControl.FORCE_NETWORK))
.awaitSuccess()
.parseAs()
}
}
suspend fun atHomeImageReport(atHomeImageReportDto: AtHomeImageReportDto): ResultDto {
return client.newCall(
POST(
MdConstants.atHomeReportUrl,
body = MdUtil.encodeToBody(atHomeImageReportDto),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
POST(
MdConstants.atHomeReportUrl,
body = MdUtil.encodeToBody(atHomeImageReportDto),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
suspend fun getAtHomeServer(
atHomeRequestUrl: String,
headers: Headers,
): AtHomeDto {
return client.newCall(GET(atHomeRequestUrl, headers, CacheControl.FORCE_NETWORK))
.awaitSuccess()
.parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(GET(atHomeRequestUrl, headers, CacheControl.FORCE_NETWORK))
.awaitSuccess()
.parseAs()
}
}
suspend fun relatedManga(id: String): RelationListDto {
return client.newCall(
GET(
MdApi.manga.toHttpUrl().newBuilder()
.apply {
addPathSegment(id)
addPathSegment("relation")
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs(MdUtil.jsonParser)
return with(MdUtil.jsonParser) {
client.newCall(
GET(
MdApi.manga.toHttpUrl().newBuilder()
.apply {
addPathSegment(id)
addPathSegment("relation")
}
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).awaitSuccess().parseAs()
}
}
}
@@ -11,10 +11,12 @@ class SimilarService(
private val client: OkHttpClient,
) {
suspend fun getSimilarManga(mangaId: String): SimilarMangaDto {
return client.newCall(
GET(
"${MdUtil.similarBaseApi}$mangaId.json",
),
).awaitSuccess().parseAs()
return with(MdUtil.jsonParser) {
client.newCall(
GET(
"${MdUtil.similarBaseApi}$mangaId.json",
),
).awaitSuccess().parseAs()
}
}
}
@@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import exh.util.MangaType
import exh.util.mangaType
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
@@ -37,6 +38,7 @@ abstract class API(val endpoint: String) {
val client by lazy {
Injekt.get<NetworkHelper>().client
}
val json by injectLazy<Json>()
abstract suspend fun getRecsBySearch(search: String): List<SManga>
@@ -52,7 +54,7 @@ class MyAnimeList : API("https://api.jikan.moe/v4/") {
.addPathSegment("recommendations")
.build()
val data = client.newCall(GET(apiUrl)).awaitSuccess().parseAs<JsonObject>()
val data = with(json) { client.newCall(GET(apiUrl)).awaitSuccess().parseAs<JsonObject>() }
return data["data"]!!.jsonArray
.map { it.jsonObject["entry"]!!.jsonObject }
.map { rec ->
@@ -88,8 +90,10 @@ class MyAnimeList : API("https://api.jikan.moe/v4/") {
.addQueryParameter("q", search)
.build()
val data = client.newCall(GET(url)).awaitSuccess()
.parseAs<JsonObject>()
val data = with(json) {
client.newCall(GET(url)).awaitSuccess()
.parseAs<JsonObject>()
}
return getRecsById(data["data"]!!.jsonArray.first().jsonObject["mal_id"]!!.jsonPrimitive.content)
}
}
@@ -137,8 +141,10 @@ class Anilist : API("https://graphql.anilist.co/") {
}
val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaType())
val data = client.newCall(POST(endpoint, body = payloadBody)).awaitSuccess()
.parseAs<JsonObject>()
val data = with(json) {
client.newCall(POST(endpoint, body = payloadBody)).awaitSuccess()
.parseAs<JsonObject>()
}
val media = data["data"]!!
.jsonObject["Page"]!!