Lanraragi delegation
This commit is contained in:
@@ -61,6 +61,7 @@ Additional features for some extensions, features include custom description, op
|
||||
* NHentai
|
||||
* Puruin
|
||||
* Tsumino
|
||||
* LANraragi
|
||||
|
||||
## Download
|
||||
Get the app from our [releases page](https://github.com/jobobby04/tachiyomisy/releases/latest).
|
||||
|
||||
@@ -69,6 +69,7 @@ import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.getNameForMangaInfo
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.Lanraragi
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
import eu.kanade.tachiyomi.source.online.english.EightMuses
|
||||
@@ -87,6 +88,7 @@ import exh.source.isEhBasedManga
|
||||
import exh.ui.metadata.adapters.EHentaiDescription
|
||||
import exh.ui.metadata.adapters.EightMusesDescription
|
||||
import exh.ui.metadata.adapters.HBrowseDescription
|
||||
import exh.ui.metadata.adapters.LanraragiDescription
|
||||
import exh.ui.metadata.adapters.MangaDexDescription
|
||||
import exh.ui.metadata.adapters.NHentaiDescription
|
||||
import exh.ui.metadata.adapters.PururinDescription
|
||||
@@ -1089,6 +1091,9 @@ fun metadataDescription(source: Source): MetadataDescriptionComposable? {
|
||||
is Tsumino -> { state, openMetadataViewer, _ ->
|
||||
TsuminoDescription(state, openMetadataViewer)
|
||||
}
|
||||
is Lanraragi -> { state, openMetadataViewer, _ ->
|
||||
LanraragiDescription(state, openMetadataViewer)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.data.cache.PagePreviewCache
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.source.PagePreviewSource
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import exh.source.getMainSource
|
||||
import logcat.LogPriority
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.Call
|
||||
@@ -249,7 +250,7 @@ class PagePreviewFetcher(
|
||||
isInCache = { pagePreviewCache.isImageInCache(data.imageUrl) },
|
||||
writeToCache = { pagePreviewCache.putImageToCache(data.imageUrl, it) },
|
||||
diskCacheKeyLazy = lazy { imageLoader.components.key(data, options)!! },
|
||||
sourceLazy = lazy { sourceManager.get(data.source) as? PagePreviewSource },
|
||||
sourceLazy = lazy { sourceManager.get(data.source)?.getMainSource<PagePreviewSource>() },
|
||||
callFactoryLazy = callFactoryLazy,
|
||||
imageLoader = imageLoader,
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.Lanraragi
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.source.online.all.MergedSource
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
@@ -277,6 +278,13 @@ class AndroidSourceManager(
|
||||
NHentai::class,
|
||||
true,
|
||||
),
|
||||
DelegatedSource(
|
||||
"LANraragi",
|
||||
fillInSourceId,
|
||||
"eu.kanade.tachiyomi.extension.all.lanraragi.LANraragi",
|
||||
Lanraragi::class,
|
||||
true,
|
||||
),
|
||||
).associateBy { it.originalSourceQualifiedClassName }
|
||||
|
||||
val currentDelegatedSources: MutableMap<Long, DelegatedSource> =
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
package eu.kanade.tachiyomi.source.online.all
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.network.newCachelessCallWithProgress
|
||||
import eu.kanade.tachiyomi.network.parseAs
|
||||
import eu.kanade.tachiyomi.source.PagePreviewInfo
|
||||
import eu.kanade.tachiyomi.source.PagePreviewPage
|
||||
import eu.kanade.tachiyomi.source.PagePreviewSource
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.NamespaceSource
|
||||
import exh.metadata.MetadataUtil
|
||||
import exh.metadata.metadata.LanraragiSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedTag
|
||||
import exh.source.DelegatedHttpSource
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
import java.time.Instant
|
||||
import java.time.ZoneOffset
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
class Lanraragi(delegate: HttpSource, val context: Context) :
|
||||
DelegatedHttpSource(delegate),
|
||||
MetadataSource<LanraragiSearchMetadata, Response>,
|
||||
NamespaceSource,
|
||||
PagePreviewSource {
|
||||
override val metaClass = LanraragiSearchMetadata::class
|
||||
override fun newMetaInstance() = LanraragiSearchMetadata()
|
||||
override val lang = delegate.lang
|
||||
|
||||
private fun getApiUriBuilder(path: String): Uri.Builder {
|
||||
return LanraragiSearchMetadata.getApiUriBuilder(baseUrl, path)
|
||||
}
|
||||
|
||||
private fun getReaderId(url: String): String {
|
||||
return READER_ID_REGEX.find(url)?.groupValues?.get(1) ?: ""
|
||||
}
|
||||
|
||||
private fun getThumbnailId(url: String): String {
|
||||
return THUMBNAIL_ID_REGEX.find(url)?.groupValues?.get(1) ?: ""
|
||||
}
|
||||
|
||||
// Helper
|
||||
private suspend fun getRandomID(query: String): String {
|
||||
val searchRandom = client.newCall(GET("$baseUrl/api/search/random?count=1&$query", headers)).awaitSuccess()
|
||||
val data = jsonParser.parseToJsonElement(searchRandom.body.string()).jsonObject["data"]
|
||||
val archive = data!!.jsonArray.firstOrNull()?.jsonObject
|
||||
|
||||
// 0.8.2~0.8.7 = id, 0.8.8+ = arcid
|
||||
return (archive?.get("arcid") ?: archive?.get("id"))?.jsonPrimitive?.content ?: ""
|
||||
}
|
||||
|
||||
private suspend fun customMangaDetailsRequest(manga: SManga): Request {
|
||||
val id = if (manga.url.startsWith("/api/search/random")) {
|
||||
getRandomID(Uri.parse(manga.url).encodedQuery.toString())
|
||||
} else {
|
||||
getReaderId(manga.url)
|
||||
}
|
||||
val uri = getApiUriBuilder("/api/archives/$id/metadata").build()
|
||||
|
||||
return GET(uri.toString(), headers)
|
||||
}
|
||||
|
||||
override suspend fun getMangaDetails(manga: SManga): SManga {
|
||||
val response = client.newCall(customMangaDetailsRequest(manga)).awaitSuccess()
|
||||
return parseToManga(manga, response)
|
||||
}
|
||||
|
||||
override suspend fun parseIntoMetadata(metadata: LanraragiSearchMetadata, input: Response) {
|
||||
val archive = with(jsonParser) { input.parseAs<Archive>() }
|
||||
|
||||
with(metadata) {
|
||||
arcId = archive.arcid
|
||||
|
||||
title = archive.title
|
||||
|
||||
summary = archive.summary
|
||||
|
||||
tags.clear()
|
||||
archive.tags?.split(',')
|
||||
?.mapTo(tags) {
|
||||
val tag = it.trim()
|
||||
if (
|
||||
tag.startsWith(LanraragiSearchMetadata.LANRARAGI_NAMESPACE_DATE_ADDED) ||
|
||||
tag.startsWith(LanraragiSearchMetadata.LANRARAGI_NAMESPACE_TIMESTAMP)
|
||||
) {
|
||||
val second = tag.substringAfter(':').trim().toLongOrNull()
|
||||
if (second != null) {
|
||||
val formattedTag = MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC)
|
||||
.format(Instant.ofEpochSecond(second))
|
||||
RaisedTag(
|
||||
tag.substringBefore(':'),
|
||||
formattedTag,
|
||||
LanraragiSearchMetadata.TAG_TYPE_DEFAULT
|
||||
)
|
||||
} else {
|
||||
RaisedTag(
|
||||
tag.substringBefore(':'),
|
||||
tag.substringAfter(':'),
|
||||
LanraragiSearchMetadata.TAG_TYPE_DEFAULT
|
||||
)
|
||||
}
|
||||
} else {
|
||||
RaisedTag(
|
||||
tag.substringBefore(':', LanraragiSearchMetadata.LANRARAGI_NAMESPACE_OTHER),
|
||||
tag.substringAfter(':'),
|
||||
LanraragiSearchMetadata.TAG_TYPE_DEFAULT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pageCount = archive.pagecount
|
||||
|
||||
filename = archive.filename
|
||||
|
||||
extension = archive.extension
|
||||
|
||||
baseUrl = this@Lanraragi.baseUrl
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Archive(
|
||||
val arcid: String,
|
||||
val isnew: String,
|
||||
val tags: String?,
|
||||
val summary: String?,
|
||||
val title: String,
|
||||
val pagecount: Int,
|
||||
val filename: String,
|
||||
val extension: String,
|
||||
)
|
||||
|
||||
|
||||
override suspend fun getPagePreviewList(manga: SManga, chapters: List<SChapter>, page: Int): PagePreviewPage {
|
||||
val metadata = fetchOrLoadMetadata(manga.id()) {
|
||||
client.newCall(customMangaDetailsRequest(manga)).awaitSuccess()
|
||||
}
|
||||
return PagePreviewPage(
|
||||
page,
|
||||
(1..(metadata.pageCount ?: 1)).map { index ->
|
||||
PagePreviewInfo(
|
||||
index,
|
||||
imageUrl = LanraragiSearchMetadata.getThumbnailUri(baseUrl, metadata.arcId!!, index),
|
||||
)
|
||||
},
|
||||
false,
|
||||
1,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private suspend fun requestPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response {
|
||||
return client.newCachelessCallWithProgress(
|
||||
if (cacheControl != null) {
|
||||
GET(page.imageUrl, cache = cacheControl, headers = headers)
|
||||
} else {
|
||||
GET(page.imageUrl, headers = headers)
|
||||
},
|
||||
page,
|
||||
).awaitSuccess()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ThumbnailTask(
|
||||
val job: Int,
|
||||
val operation: String,
|
||||
val success: Int,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class TaskProgress(
|
||||
val state: String,
|
||||
)
|
||||
|
||||
suspend fun minionJobDone(jobId: Int): Boolean {
|
||||
return client.newCall(
|
||||
GET(
|
||||
getApiUriBuilder("/api/minion/$jobId").build().toString(),
|
||||
headers = headers
|
||||
)
|
||||
).awaitSuccess().let {
|
||||
with(jsonParser) {
|
||||
it.parseAs<TaskProgress>().state == "finished"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response {
|
||||
return requestPreviewImage(page, cacheControl).let {
|
||||
if (it.code == 202) {
|
||||
val task = with(jsonParser) {
|
||||
it.parseAs<ThumbnailTask>()
|
||||
}
|
||||
var tries = 0
|
||||
do {
|
||||
if (tries > 1) {
|
||||
delay(200.milliseconds)
|
||||
}
|
||||
val jobDone = minionJobDone(task.job)
|
||||
} while (!jobDone && tries++ < 3)
|
||||
requestPreviewImage(page, cacheControl).apply {
|
||||
if (code == 202) {
|
||||
throw IOException("Thumbnail not ready")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val jsonParser = Json {
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
|
||||
private val READER_ID_REGEX = Regex("""/reader\?id=(\w{40})""")
|
||||
private val THUMBNAIL_ID_REGEX = Regex("""/(\w{40})/thumbnail""")
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package exh.source
|
||||
|
||||
import eu.kanade.tachiyomi.source.AndroidSourceManager
|
||||
import eu.kanade.tachiyomi.source.online.all.Lanraragi
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
import eu.kanade.tachiyomi.source.online.english.EightMuses
|
||||
@@ -19,6 +20,7 @@ private val DELEGATED_METADATA_SOURCES by lazy {
|
||||
HBrowse::class,
|
||||
EightMuses::class,
|
||||
NHentai::class,
|
||||
Lanraragi::class,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,6 +46,13 @@ fun handleSourceLibrary() {
|
||||
.map { it.value.sourceId }
|
||||
.sorted()
|
||||
|
||||
lanraragiSourceIds = AndroidSourceManager.currentDelegatedSources
|
||||
.filter {
|
||||
it.value.newSourceClass == Lanraragi::class
|
||||
}
|
||||
.map { it.value.sourceId }
|
||||
.sorted()
|
||||
|
||||
LIBRARY_UPDATE_EXCLUDED_SOURCES = listOf(
|
||||
EH_SOURCE_ID,
|
||||
EXH_SOURCE_ID,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterLaBinding
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.metadata.LanraragiSearchMetadata
|
||||
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
|
||||
import tachiyomi.core.common.i18n.pluralStringResource
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
|
||||
@Composable
|
||||
fun LanraragiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
DescriptionAdapterLaBinding.inflate(LayoutInflater.from(factoryContext)).root
|
||||
},
|
||||
update = {
|
||||
val meta = state.meta
|
||||
if (meta == null || meta !is LanraragiSearchMetadata) return@AndroidView
|
||||
val binding = DescriptionAdapterLaBinding.bind(it)
|
||||
|
||||
binding.ext.text = meta.extension?.uppercase().orEmpty()
|
||||
|
||||
binding.pages.text = context.pluralStringResource(
|
||||
SYMR.plurals.num_pages,
|
||||
meta.pageCount ?: 1,
|
||||
meta.pageCount ?: 1,
|
||||
)
|
||||
binding.pages.bindDrawable(context, R.drawable.ic_baseline_menu_book_24)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp)
|
||||
|
||||
listOf(
|
||||
binding.pages,
|
||||
binding.ext,
|
||||
).forEach { textView ->
|
||||
textView.setOnLongClickListener {
|
||||
context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString(),
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.setOnClickListener {
|
||||
openMetadataViewer()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/ext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/pages"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/more_info"
|
||||
style="?attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/more_info"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -8,6 +8,8 @@ var metadataDelegatedSourceIds: List<Long> = emptyList()
|
||||
|
||||
var nHentaiSourceIds: List<Long> = emptyList()
|
||||
|
||||
var lanraragiSourceIds: List<Long> = emptyList()
|
||||
|
||||
var mangaDexSourceIds: List<Long> = emptyList()
|
||||
|
||||
var LIBRARY_UPDATE_EXCLUDED_SOURCES = listOf(
|
||||
|
||||
@@ -667,6 +667,9 @@
|
||||
<string name="manga_updates_id">Manga updates id</string>
|
||||
<string name="anime_planet_id">Anime planet id</string>
|
||||
<string name="translated">Translated</string>
|
||||
<string name="filename">File name</string>
|
||||
<string name="file_extension">File extension</string>
|
||||
<string name="base_url">Base url</string>
|
||||
|
||||
<!-- Extra gallery info -->
|
||||
<string name="is_visible">Visible: %1$s</string>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.model.copy
|
||||
import kotlinx.serialization.Serializable
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
|
||||
@Serializable
|
||||
class LanraragiSearchMetadata : RaisedSearchMetadata() {
|
||||
var url get() = arcId?.let { "/reader?id=$it" }
|
||||
set(a) {
|
||||
a?.let {
|
||||
arcId = a
|
||||
}
|
||||
}
|
||||
|
||||
var arcId: String? = null
|
||||
|
||||
var title: String? = null
|
||||
|
||||
var summary: String? = null
|
||||
|
||||
var pageCount: Int? = null
|
||||
|
||||
var baseUrl: String? = null
|
||||
|
||||
var filename: String? = null
|
||||
|
||||
var extension: String? = null
|
||||
|
||||
override fun createMangaInfo(manga: SManga): SManga {
|
||||
val key = url
|
||||
|
||||
val cover = if (baseUrl != null && arcId != null) {
|
||||
getThumbnailUri(baseUrl!!, arcId!!, 1)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val title = title
|
||||
// Set artist (if we can find one)
|
||||
val artist = tags.ofNamespace(LANRARAGI_NAMESPACE_ARTIST).let { tags ->
|
||||
if (tags.isNotEmpty()) tags.joinToString(transform = { it.name }) else null
|
||||
}
|
||||
|
||||
// Copy tags -> genres
|
||||
val genres = tagsToGenreString()
|
||||
|
||||
// We default to completed
|
||||
val status = SManga.COMPLETED
|
||||
|
||||
return manga.copy(
|
||||
url = key ?: manga.url,
|
||||
thumbnail_url = cover ?: manga.thumbnail_url,
|
||||
title = title ?: manga.title,
|
||||
artist = artist ?: manga.artist,
|
||||
author = artist ?: manga.artist,
|
||||
genre = genres,
|
||||
status = status,
|
||||
description = summary ?: manga.description,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
return with(context) {
|
||||
listOfNotNull(
|
||||
getItem(arcId) { stringResource(SYMR.strings.id) },
|
||||
getItem(pageCount) { stringResource(SYMR.strings.page_count) },
|
||||
getItem(filename) { stringResource(SYMR.strings.filename) },
|
||||
getItem(extension) { stringResource(SYMR.strings.file_extension) },
|
||||
getItem(baseUrl) { stringResource(SYMR.strings.base_url) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG_TYPE_DEFAULT = 0
|
||||
|
||||
const val LANRARAGI_NAMESPACE_OTHER = "other"
|
||||
|
||||
const val LANRARAGI_NAMESPACE_DATE_ADDED = "date_added"
|
||||
|
||||
const val LANRARAGI_NAMESPACE_TIMESTAMP = "timestamp"
|
||||
|
||||
const val LANRARAGI_NAMESPACE_ARTIST = "artist"
|
||||
|
||||
fun getApiUriBuilder(baseUrl: String, path: String): Uri.Builder {
|
||||
return Uri.parse("$baseUrl$path").buildUpon()
|
||||
}
|
||||
|
||||
fun getThumbnailUri(baseUrl: String, id: String, page: Int): String {
|
||||
val uri = getApiUriBuilder(baseUrl, "/api/archives/$id/thumbnail")
|
||||
|
||||
if (page > 1) {
|
||||
uri.appendQueryParameter("page", page.toString())
|
||||
uri.appendQueryParameter("no_fallback", "true")
|
||||
}
|
||||
|
||||
return uri.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user