Replace DummyParser with TestMangaRepository

This commit is contained in:
Koitharu
2025-09-07 10:31:13 +03:00
parent 71a2de5358
commit 8f38b4fe30
14 changed files with 115 additions and 71 deletions

View File

@@ -0,0 +1,57 @@
package org.koitharu.kotatsu.core.parser
import org.koitharu.kotatsu.core.cache.MemoryContentCache
import org.koitharu.kotatsu.core.model.TestMangaSource
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaListFilter
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
import org.koitharu.kotatsu.parsers.model.MangaListFilterOptions
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.SortOrder
import java.util.EnumSet
/*
This class is for parser development and testing purposes
You can open it in the app via Settings -> Debug
*/
class TestMangaRepository(
@Suppress("unused") private val loaderContext: MangaLoaderContext,
cache: MemoryContentCache
) : CachingMangaRepository(cache) {
override val source = TestMangaSource
override val sortOrders: Set<SortOrder> = EnumSet.allOf(SortOrder::class.java)
override var defaultSortOrder: SortOrder
get() = sortOrders.first()
set(value) = Unit
override val filterCapabilities = MangaListFilterCapabilities()
override suspend fun getFilterOptions() = MangaListFilterOptions()
override suspend fun getList(
offset: Int,
order: SortOrder?,
filter: MangaListFilter?
): List<Manga> = TODO("Get manga list by filter")
override suspend fun getDetailsImpl(
manga: Manga
): Manga = TODO("Fetch manga details")
override suspend fun getPagesImpl(
chapter: MangaChapter
): List<MangaPage> = TODO("Get pages for specific chapter")
override suspend fun getPageUrl(
page: MangaPage
): String = TODO("Return direct url of page image or page.url if it is already a direct url")
override suspend fun getRelatedMangaImpl(
seed: Manga
): List<Manga> = TODO("Get list of related manga. This method is optional and parser library has a default implementation")
}

View File

@@ -5,6 +5,8 @@ import androidx.preference.Preference
import leakcanary.LeakCanary
import org.koitharu.kotatsu.KotatsuApp
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.TestMangaSource
import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.settings.utils.SplitSwitchPreference
import org.koitharu.workinspector.WorkInspector
@@ -35,6 +37,11 @@ class DebugSettingsFragment : BasePreferenceFragment(R.string.debug), Preference
true
}
KEY_TEST_PARSER -> {
router.openList(TestMangaSource, null, null)
true
}
else -> super.onPreferenceTreeClick(preference)
}
@@ -60,5 +67,6 @@ class DebugSettingsFragment : BasePreferenceFragment(R.string.debug), Preference
const val KEY_LEAK_CANARY = "leak_canary"
const val KEY_WORK_INSPECTOR = "work_inspector"
const val KEY_TEST_PARSER = "test_parser"
}
}

View File

@@ -1,17 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.koitharu.kotatsu.settings.utils.SplitSwitchPreference
android:id="@+id/action_leakcanary"
android:key="leak_canary"
android:persistent="false"
android:title="LeakCanary" />
<Preference
android:id="@+id/action_works"
android:key="work_inspector"
android:persistent="false"
android:title="@string/wi_lib_name" />
<Preference
android:key="test_parser"
android:persistent="false"
android:title="@string/test_parser"
app:allowDividerAbove="true" />
</androidx.preference.PreferenceScreen>

View File

@@ -28,11 +28,15 @@ data object UnknownMangaSource : MangaSource {
override val name = "UNKNOWN"
}
data object TestMangaSource : MangaSource {
override val name = "TEST"
}
fun MangaSource(name: String?): MangaSource {
when (name ?: return UnknownMangaSource) {
UnknownMangaSource.name -> return UnknownMangaSource
LocalMangaSource.name -> return LocalMangaSource
TestMangaSource.name -> return TestMangaSource
}
if (name.startsWith("content:")) {
val parts = name.substringAfter(':').splitTwoParts('/') ?: return UnknownMangaSource
@@ -92,6 +96,7 @@ fun MangaSource.getSummary(context: Context): String? = when (val source = unwra
fun MangaSource.getTitle(context: Context): String = when (val source = unwrap()) {
is MangaParserSource -> source.title
LocalMangaSource -> context.getString(R.string.local_storage)
TestMangaSource -> context.getString(R.string.test_parser)
is ExternalMangaSource -> source.resolveName(context)
else -> context.getString(R.string.unknown)
}

View File

@@ -1,46 +0,0 @@
package org.koitharu.kotatsu.core.parser
import org.koitharu.kotatsu.core.exceptions.UnsupportedSourceException
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.core.AbstractMangaParser
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaListFilter
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
import org.koitharu.kotatsu.parsers.model.MangaListFilterOptions
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.model.SortOrder
import java.util.EnumSet
/**
* This parser is just for parser development, it should not be used in releases
*/
class DummyParser(context: MangaLoaderContext) : AbstractMangaParser(context, MangaParserSource.DUMMY) {
override val configKeyDomain: ConfigKey.Domain
get() = ConfigKey.Domain("localhost")
override val availableSortOrders: Set<SortOrder>
get() = EnumSet.allOf(SortOrder::class.java)
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities()
override suspend fun getDetails(manga: Manga): Manga = stub(manga)
override suspend fun getFilterOptions(): MangaListFilterOptions = stub(null)
override suspend fun getList(
offset: Int,
order: SortOrder,
filter: MangaListFilter
): List<Manga> = stub(null)
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> = stub(null)
private fun stub(manga: Manga?): Nothing {
throw UnsupportedSourceException("Usage of Dummy parser", manga)
}
}

View File

@@ -11,7 +11,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.SortOrder
import java.util.EnumSet
class EmptyMangaRepository(override val source: MangaSource) : MangaRepository {
open class EmptyMangaRepository(override val source: MangaSource) : MangaRepository {
override val sortOrders: Set<SortOrder>
get() = EnumSet.allOf(SortOrder::class.java)

View File

@@ -1,12 +0,0 @@
package org.koitharu.kotatsu.core.parser
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaParser
import org.koitharu.kotatsu.parsers.model.MangaParserSource
fun MangaParser(source: MangaParserSource, loaderContext: MangaLoaderContext): MangaParser {
return when (source) {
MangaParserSource.DUMMY -> DummyParser(loaderContext)
else -> loaderContext.newParserInstance(source)
}
}

View File

@@ -7,6 +7,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import org.koitharu.kotatsu.core.cache.MemoryContentCache
import org.koitharu.kotatsu.core.model.LocalMangaSource
import org.koitharu.kotatsu.core.model.MangaSourceInfo
import org.koitharu.kotatsu.core.model.TestMangaSource
import org.koitharu.kotatsu.core.model.UnknownMangaSource
import org.koitharu.kotatsu.core.parser.external.ExternalMangaRepository
import org.koitharu.kotatsu.core.parser.external.ExternalMangaSource
@@ -85,11 +86,16 @@ interface MangaRepository {
private fun createRepository(source: MangaSource): MangaRepository? = when (source) {
is MangaParserSource -> ParserMangaRepository(
parser = MangaParser(source, loaderContext),
parser = loaderContext.newParserInstance(source),
cache = contentCache,
mirrorSwitcher = mirrorSwitcher,
)
TestMangaSource -> TestMangaRepository(
loaderContext = loaderContext,
cache = contentCache,
)
is ExternalMangaSource -> if (source.isAvailable(context)) {
ExternalMangaRepository(
contentResolver = context.contentResolver,

View File

@@ -53,11 +53,7 @@ class MangaSourcesRepository @Inject constructor(
get() = db.getSourcesDao()
val allMangaSources: Set<MangaParserSource> = Collections.unmodifiableSet(
EnumSet.allOf(MangaParserSource::class.java).apply {
if (!BuildConfig.DEBUG) {
remove(MangaParserSource.DUMMY)
}
},
EnumSet.allOf(MangaParserSource::class.java)
)
suspend fun getEnabledSources(): List<MangaSource> {

View File

@@ -879,4 +879,5 @@
<string name="no_chapters_in_manga">This manga does not contain any chapters</string>
<string name="chapters_load_failed">Failed to load chapter list</string>
<string name="telegram_integration">Telegram integration</string>
<string name="test_parser">Test manga source</string>
</resources>

View File

@@ -0,0 +1,11 @@
package org.koitharu.kotatsu.core.parser
import org.koitharu.kotatsu.core.cache.MemoryContentCache
import org.koitharu.kotatsu.core.model.TestMangaSource
import org.koitharu.kotatsu.parsers.MangaLoaderContext
@Suppress("unused")
class TestMangaRepository(
private val loaderContext: MangaLoaderContext,
cache: MemoryContentCache
) : EmptyMangaRepository(TestMangaSource)

View File

@@ -0,0 +1,11 @@
package org.koitharu.kotatsu.core.parser
import org.koitharu.kotatsu.core.cache.MemoryContentCache
import org.koitharu.kotatsu.core.model.TestMangaSource
import org.koitharu.kotatsu.parsers.MangaLoaderContext
@Suppress("unused")
class TestMangaRepository(
private val loaderContext: MangaLoaderContext,
cache: MemoryContentCache
) : EmptyMangaRepository(TestMangaSource)

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.domain
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.koitharu.kotatsu.core.model.TestMangaSource
import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
import kotlin.random.Random
@@ -73,6 +74,6 @@ class ChapterPagesTest {
preview = null,
chapterId = chapterId,
index = Random.nextInt(),
source = MangaParserSource.DUMMY,
source = TestMangaSource,
)
}

View File

@@ -35,7 +35,7 @@ material = "1.14.0-alpha04"
moshi = "1.15.2"
okhttp = "5.1.0"
okio = "3.16.0"
parsers = "19567f9642"
parsers = "fe5534b006"
preference = "1.2.1"
recyclerview = "1.4.0"
room = "2.7.2"