From 62e43c407af6ba72e6702713d48f677ca34739ac Mon Sep 17 00:00:00 2001 From: Koitharu Date: Fri, 22 Apr 2022 20:31:54 +0300 Subject: [PATCH] Add ksp to generate MangaSource enum --- build.gradle | 20 ++- kotatsu-parsers-ksp/build.gradle | 7 + .../kotatsu/parsers/ksp/ParserProcessor.kt | 142 ++++++++++++++++++ .../parsers/ksp/ParserProcessorProvider.kt | 16 ++ ...ols.ksp.processing.SymbolProcessorProvider | 1 + settings.gradle | 19 +++ .../kotatsu/parsers/MangaParserFactory.kt | 38 ----- .../kotatsu/parsers/MangaSourceParser.kt | 8 + .../kotatsu/parsers/model/MangaSource.kt | 36 ----- .../kotatsu/parsers/site/AnibelParser.kt | 2 + .../kotatsu/parsers/site/BatoToParser.kt | 2 + .../kotatsu/parsers/site/ComickFunParser.kt | 2 + .../kotatsu/parsers/site/DesuMeParser.kt | 2 + .../kotatsu/parsers/site/ExHentaiParser.kt | 2 + .../kotatsu/parsers/site/HenChanParser.kt | 2 + .../kotatsu/parsers/site/HentaiLibParser.kt | 2 + .../kotatsu/parsers/site/MangaChanParser.kt | 2 + .../kotatsu/parsers/site/MangaDexParser.kt | 2 + .../kotatsu/parsers/site/MangaLibParser.kt | 6 +- .../kotatsu/parsers/site/MangaOwlParser.kt | 2 + .../kotatsu/parsers/site/MangaTownParser.kt | 2 + .../kotatsu/parsers/site/MangareadParser.kt | 2 + .../kotatsu/parsers/site/MintMangaParser.kt | 2 + .../kotatsu/parsers/site/NineMangaParser.kt | 8 + .../kotatsu/parsers/site/NudeMoonParser.kt | 2 + .../kotatsu/parsers/site/ReadmangaParser.kt | 2 + .../kotatsu/parsers/site/RemangaParser.kt | 2 + .../kotatsu/parsers/site/SelfMangaParser.kt | 2 + .../kotatsu/parsers/site/YaoiChanParser.kt | 2 + 29 files changed, 254 insertions(+), 83 deletions(-) create mode 100644 kotatsu-parsers-ksp/build.gradle create mode 100644 kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessor.kt create mode 100644 kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessorProvider.kt create mode 100644 kotatsu-parsers-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider delete mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParserFactory.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceParser.kt delete mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaSource.kt diff --git a/build.gradle b/build.gradle index 35cffc2b..54baa889 100644 --- a/build.gradle +++ b/build.gradle @@ -1,16 +1,12 @@ plugins { id 'java-library' - id 'org.jetbrains.kotlin.jvm' version '1.6.20-M1' + id 'org.jetbrains.kotlin.jvm' + id 'com.google.devtools.ksp' } group = 'org.koitharu' version = '1.0' -repositories { - mavenCentral() - google() -} - test { useJUnitPlatform() } @@ -33,17 +29,25 @@ compileTestKotlin { } } +kotlin { + sourceSets { + main.kotlin.srcDirs += 'build/generated/ksp/main/kotlin' + } +} + dependencies { - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1' implementation 'com.squareup.okhttp3:okhttp:4.9.3' implementation 'com.squareup.okio:okio:3.0.0' implementation 'org.jsoup:jsoup:1.14.3' implementation 'org.json:json:20220320' implementation 'androidx.collection:collection-ktx:1.2.0' + ksp project(':kotatsu-parsers-ksp') + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2' testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2' - testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0' + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.1' testImplementation 'io.webfolder:quickjs:1.1.0' } \ No newline at end of file diff --git a/kotatsu-parsers-ksp/build.gradle b/kotatsu-parsers-ksp/build.gradle new file mode 100644 index 00000000..9ae06d1d --- /dev/null +++ b/kotatsu-parsers-ksp/build.gradle @@ -0,0 +1,7 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' +} + +dependencies { + implementation 'com.google.devtools.ksp:symbol-processing-api:1.6.20-1.0.5' +} \ No newline at end of file diff --git a/kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessor.kt b/kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessor.kt new file mode 100644 index 00000000..1142fe42 --- /dev/null +++ b/kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessor.kt @@ -0,0 +1,142 @@ +package org.koitharu.kotatsu.parsers.ksp + +import com.google.devtools.ksp.isAbstract +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.ClassKind +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSVisitorVoid +import com.google.devtools.ksp.validate +import java.io.Writer + +class ParserProcessor( + private val codeGenerator: CodeGenerator, + private val logger: KSPLogger, + private val options: Map, +) : SymbolProcessor { + + override fun process(resolver: Resolver): List { + val symbols = resolver + .getSymbolsWithAnnotation("org.koitharu.kotatsu.parsers.MangaSourceParser") + val ret = symbols.filterNot { it.validate() }.toList() + if (!symbols.iterator().hasNext()) { + return ret + } + val dependencies = Dependencies.ALL_FILES + val factoryFile = try { + codeGenerator.createNewFile( + dependencies = dependencies, + packageName = "org.koitharu.kotatsu.parsers", + fileName = "MangaParserFactory", + ) + } catch (e: FileAlreadyExistsException) { + logger.warn(e.toString(), null) + null + } + val sourcesFile = try { + codeGenerator.createNewFile( + dependencies = dependencies, + packageName = "org.koitharu.kotatsu.parsers.model", + fileName = "MangaSource", + ) + } catch (e: FileAlreadyExistsException) { + logger.warn(e.toString(), null) + null + } + sourcesFile?.writer().use { sourcesWriter -> + factoryFile?.writer().use { factoryWriter -> + writeContent(sourcesWriter, factoryWriter, symbols) + } + } + return ret + } + + private fun writeContent( + sourcesWriter: Writer?, + factoryWriter: Writer?, + symbols: Sequence, + ) { + if (sourcesWriter == null && factoryWriter == null) { + return + } + factoryWriter?.write( + """ + package org.koitharu.kotatsu.parsers + + import org.koitharu.kotatsu.parsers.model.MangaSource + + fun MangaSource.newParser(context: MangaLoaderContext): MangaParser = when (this) { + + """.trimIndent(), + ) + sourcesWriter?.write( + """ + package org.koitharu.kotatsu.parsers.model + + import org.koitharu.kotatsu.parsers.model.MangaSource + + enum class MangaSource( + val title: String, + val locale: String?, + ) { + LOCAL("Local", null), + + """.trimIndent(), + ) + + val visitor = ParserVisitor(sourcesWriter, factoryWriter) + symbols + .filter { it is KSClassDeclaration && it.validate() } + .forEach { it.accept(visitor, Unit) } + + factoryWriter?.write( + """ + MangaSource.LOCAL -> throw NotImplementedError("Local manga parser is not supported") + }.also { + require(it.source == this) { + "Cannot instantiate manga parser: ${'$'}name mapped to ${'$'}{it.source}" + } + } + """.trimIndent(), + ) + sourcesWriter?.write( + """ + ; + } + """.trimIndent(), + ) + } + + private inner class ParserVisitor( + private val sourcesWriter: Writer?, + private val factoryWriter: Writer?, + ) : KSVisitorVoid() { + + override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) { + if (classDeclaration.classKind != ClassKind.CLASS || classDeclaration.isAbstract()) { + logger.error("Only non-abstract can be annotated with @MangaSourceParser", classDeclaration) + } + val annotation = classDeclaration.annotations.single { it.shortName.asString() == "MangaSourceParser" } + val name = annotation.arguments.single { it.name?.asString() == "name" }.value as String + val title = annotation.arguments.single { it.name?.asString() == "title" }.value as String + val locale = annotation.arguments.single { it.name?.asString() == "locale" }.value as String + val localeString = if (locale.isEmpty()) "null" else "\"$locale\"" + + if (name.any { it.isLowerCase() }) { + logger.error("Manga source name must be uppercase: $name") + } + + val constructor = classDeclaration.primaryConstructor + if (constructor == null || constructor.parameters.count { !it.hasDefault } != 1) { + logger.error( + "Class with @MangaSourceParser must have a primary constructor with one parameter", + classDeclaration, + ) + } + + val className = classDeclaration.qualifiedName?.asString() + factoryWriter?.write("\tMangaSource.$name -> $className(context)\n") + sourcesWriter?.write("\t$name(\"$title\", $localeString),\n") + } + } +} \ No newline at end of file diff --git a/kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessorProvider.kt b/kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessorProvider.kt new file mode 100644 index 00000000..9149e0c8 --- /dev/null +++ b/kotatsu-parsers-ksp/src/main/kotlin/org/koitharu/kotatsu/parsers/ksp/ParserProcessorProvider.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.ksp + +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider + +class ParserProcessorProvider : SymbolProcessorProvider { + + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + return ParserProcessor( + codeGenerator = environment.codeGenerator, + logger = environment.logger, + options = environment.options + ) + } +} \ No newline at end of file diff --git a/kotatsu-parsers-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/kotatsu-parsers-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 00000000..59aa499b --- /dev/null +++ b/kotatsu-parsers-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1 @@ +org.koitharu.kotatsu.parsers.ksp.ParserProcessorProvider \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 4ae5f884..2d2465a8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,22 @@ +pluginManagement { + plugins { + id 'com.google.devtools.ksp' version '1.6.21-1.0.5' + id 'org.jetbrains.kotlin.jvm' version '1.6.21' + } + repositories { + gradlePluginPortal() + google() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} rootProject.name = 'kotatsu-parsers' +include 'kotatsu-parsers-ksp' diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParserFactory.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParserFactory.kt deleted file mode 100644 index 5c8d770f..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParserFactory.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.koitharu.kotatsu.parsers - -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.* - -fun MangaSource.newParser(context: MangaLoaderContext): MangaParser = when (this) { - MangaSource.READMANGA_RU -> ReadmangaParser(context) - MangaSource.MINTMANGA -> MintMangaParser(context) - MangaSource.SELFMANGA -> SelfMangaParser(context) - MangaSource.MANGACHAN -> MangaChanParser(context) - MangaSource.DESUME -> DesuMeParser(context) - MangaSource.HENCHAN -> HenChanParser(context) - MangaSource.YAOICHAN -> YaoiChanParser(context) - MangaSource.MANGATOWN -> MangaTownParser(context) - MangaSource.MANGALIB -> MangaLibParser(context) - MangaSource.NUDEMOON -> NudeMoonParser(context) - MangaSource.MANGAREAD -> MangareadParser(context) - MangaSource.REMANGA -> RemangaParser(context) - MangaSource.HENTAILIB -> HentaiLibParser(context) - MangaSource.ANIBEL -> AnibelParser(context) - MangaSource.NINEMANGA_EN -> NineMangaParser.English(context) - MangaSource.NINEMANGA_ES -> NineMangaParser.Spanish(context) - MangaSource.NINEMANGA_RU -> NineMangaParser.Russian(context) - MangaSource.NINEMANGA_DE -> NineMangaParser.Deutsch(context) - MangaSource.NINEMANGA_IT -> NineMangaParser.Italiano(context) - MangaSource.NINEMANGA_BR -> NineMangaParser.Brazil(context) - MangaSource.NINEMANGA_FR -> NineMangaParser.Francais(context) - MangaSource.EXHENTAI -> ExHentaiParser(context) - MangaSource.MANGAOWL -> MangaOwlParser(context) - MangaSource.MANGADEX -> MangaDexParser(context) - MangaSource.BATOTO -> BatoToParser(context) - MangaSource.COMICK_FUN -> ComickFunParser(context) - MangaSource.LOCAL -> throw NotImplementedError("Local manga parser is not supported") -}.also { - require(it.source == this) { - "Cannot instantiate manga parser: $name mapped to ${it.source}" - } -} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceParser.kt new file mode 100644 index 00000000..7267256b --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceParser.kt @@ -0,0 +1,8 @@ +package org.koitharu.kotatsu.parsers + +@Target(AnnotationTarget.CLASS) +annotation class MangaSourceParser( + val name: String, + val title: String, + val locale: String = "", +) \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaSource.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaSource.kt deleted file mode 100644 index 396fff67..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaSource.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.koitharu.kotatsu.parsers.model - -@Suppress("SpellCheckingInspection") -enum class MangaSource( - val title: String, - val locale: String?, -) { - LOCAL("Local", null), - READMANGA_RU("ReadManga", "ru"), - MINTMANGA("MintManga", "ru"), - SELFMANGA("SelfManga", "ru"), - MANGACHAN("Манга-тян", "ru"), - DESUME("Desu.me", "ru"), - HENCHAN("Хентай-тян", "ru"), - YAOICHAN("Яой-тян", "ru"), - MANGATOWN("MangaTown", "en"), - MANGALIB("MangaLib", "ru"), - NUDEMOON("Nude-Moon", "ru"), - MANGAREAD("MangaRead", "en"), - REMANGA("Remanga", "ru"), - HENTAILIB("HentaiLib", "ru"), - ANIBEL("Anibel", "be"), - NINEMANGA_EN("NineManga English", "en"), - NINEMANGA_ES("NineManga Español", "es"), - NINEMANGA_RU("NineManga Русский", "ru"), - NINEMANGA_DE("NineManga Deutsch", "de"), - NINEMANGA_IT("NineManga Italiano", "it"), - NINEMANGA_BR("NineManga Brasil", "pt"), - NINEMANGA_FR("NineManga Français", "fr"), - EXHENTAI("ExHentai", null), - MANGAOWL("MangaOwl", "en"), - MANGADEX("MangaDex", null), - BATOTO("Bato.To", null), - COMICK_FUN("ComicK", null), - ; -} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt index 5f0fed4e..097df140 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt @@ -5,6 +5,7 @@ import org.json.JSONArray import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.json.mapJSON @@ -12,6 +13,7 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed import org.koitharu.kotatsu.parsers.util.json.stringIterator import java.util.* +@MangaSourceParser("ANIBEL", "Anibel", "be") internal class AnibelParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.ANIBEL) { override val configKeyDomain = ConfigKey.Domain("anibel.net", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt index c0c18d14..9cadcd89 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt @@ -6,6 +6,7 @@ import org.json.JSONObject import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -19,6 +20,7 @@ import javax.crypto.spec.SecretKeySpec private const val PAGE_SIZE = 60 private const val PAGE_SIZE_SEARCH = 20 +@MangaSourceParser("BATOTO", "Bato.To") internal class BatoToParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.BATOTO) { override val sortOrders: Set = EnumSet.of( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt index ae7a92b2..c4f62999 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt @@ -6,6 +6,7 @@ import org.json.JSONArray import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -20,6 +21,7 @@ import java.util.* private const val PAGE_SIZE = 20 private const val CHAPTERS_LIMIT = 99999 +@MangaSourceParser("COMICK_FUN", "ComicK") internal class ComickFunParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.COMICK_FUN) { override val configKeyDomain = ConfigKey.Domain("comick.fun", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt index 9ba61469..1cc38970 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -11,6 +12,7 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed import org.koitharu.kotatsu.parsers.util.json.mapJSONToSet import java.util.* +@MangaSourceParser("DESUME", "Desu.me", "ru") internal class DesuMeParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.DESUME) { override val configKeyDomain = ConfigKey.Domain("desu.me", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt index de9558b8..cde5ef98 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt @@ -4,6 +4,7 @@ import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException @@ -15,6 +16,7 @@ import kotlin.math.pow private const val DOMAIN_UNAUTHORIZED = "e-hentai.org" private const val DOMAIN_AUTHORIZED = "exhentai.org" +@MangaSourceParser("EXHENTAI", "ExHentai") internal class ExHentaiParser( override val context: MangaLoaderContext, ) : MangaParser(MangaSource.EXHENTAI), MangaParserAuthProvider { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt index c19a6236..24d509cb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -8,6 +9,7 @@ import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.toTitleCase +@MangaSourceParser("HENCHAN", "Хентай-тян", "ru") internal class HenChanParser(override val context: MangaLoaderContext) : ChanParser(MangaSource.HENCHAN) { override val configKeyDomain = ConfigKey.Domain("hentaichan.live", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt index 2181d142..fee4e450 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt @@ -2,9 +2,11 @@ package org.koitharu.kotatsu.parsers.site import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource +@MangaSourceParser("HENTAILIB", "HentaiLib", "ru") internal class HentaiLibParser(context: MangaLoaderContext) : MangaLibParser(context, MangaSource.HENTAILIB) { override val configKeyDomain = ConfigKey.Domain("hentailib.me", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt index ac5a2918..63f86d44 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt @@ -1,9 +1,11 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource +@MangaSourceParser("MANGACHAN", "Манга-тян", "ru") internal class MangaChanParser(override val context: MangaLoaderContext) : ChanParser(MangaSource.MANGACHAN) { override val configKeyDomain = ConfigKey.Domain("manga-chan.me", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt index 2049c07a..3c788162 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.coroutineScope import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -17,6 +18,7 @@ private const val CONTENT_RATING = "contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic" private const val LOCALE_FALLBACK = "en" +@MangaSourceParser("MANGADEX", "MangaDex") internal class MangaDexParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGADEX) { override val configKeyDomain = ConfigKey.Domain("mangadex.org", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt index 797f6dc2..88b0c7b1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt @@ -7,6 +7,7 @@ import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException @@ -20,7 +21,7 @@ import java.util.* internal open class MangaLibParser( override val context: MangaLoaderContext, - source: MangaSource = MangaSource.MANGALIB, + source: MangaSource, ) : MangaParser(source), MangaParserAuthProvider { override val configKeyDomain = ConfigKey.Domain("mangalib.me", null) @@ -280,4 +281,7 @@ internal open class MangaLibParser( ) } } + + @MangaSourceParser("MANGALIB", "MangaLib", "ru") + class Impl(context: MangaLoaderContext) : MangaLibParser(context, MangaSource.MANGALIB) } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt index 785a7997..301b6dfb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -9,6 +10,7 @@ import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* +@MangaSourceParser("MANGAOWL", "MangaOwl", "en") internal class MangaOwlParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGAOWL) { override val configKeyDomain = ConfigKey.Domain("mangaowls.com", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt index 7ed922f9..c8332729 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -10,6 +11,7 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* +@MangaSourceParser("MANGATOWN", "MangaTown", "en") internal class MangaTownParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGATOWN) { override val configKeyDomain = ConfigKey.Domain("www.mangatown.com", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt index 393bd793..b164d02e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -12,6 +13,7 @@ import java.util.* private const val PAGE_SIZE = 12 +@MangaSourceParser("MANGAREAD", "MangaRead", "en") internal class MangareadParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGAREAD) { override val configKeyDomain = ConfigKey.Domain("www.mangaread.org", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt index 7145c5d9..e40c726e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt @@ -1,9 +1,11 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource +@MangaSourceParser("MINTMANGA", "MintManga", "ru") internal class MintMangaParser(override val context: MangaLoaderContext) : GroupleParser(MangaSource.MINTMANGA) { override val configKeyDomain = ConfigKey.Domain("mintmanga.live", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt index 6f4c97f9..4e5f0b36 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt @@ -4,6 +4,7 @@ import okhttp3.Headers import okhttp3.HttpUrl.Companion.toHttpUrl import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -211,42 +212,49 @@ internal abstract class NineMangaParser( return 0L } + @MangaSourceParser("NINEMANGA_EN", "NineManga English", "en") class English(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_EN, "www.ninemanga.com", ) + @MangaSourceParser("NINEMANGA_ES", "NineManga Español", "es") class Spanish(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_ES, "es.ninemanga.com", ) + @MangaSourceParser("NINEMANGA_RU", "NineManga Русский", "ru") class Russian(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_RU, "ru.ninemanga.com", ) + @MangaSourceParser("NINEMANGA_DE", "NineManga Deutsch", "de") class Deutsch(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_DE, "de.ninemanga.com", ) + @MangaSourceParser("NINEMANGA_BR", "NineManga Brasil", "pt") class Brazil(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_BR, "br.ninemanga.com", ) + @MangaSourceParser("NINEMANGA_IT", "NineManga Italiano", "it") class Italiano(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_IT, "it.ninemanga.com", ) + @MangaSourceParser("NINEMANGA_FR", "NineManga Français", "fr") class Francais(context: MangaLoaderContext) : NineMangaParser( context, MangaSource.NINEMANGA_FR, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt index a88c3da9..04cddcc9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt @@ -4,6 +4,7 @@ import androidx.collection.SparseArrayCompat import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException @@ -15,6 +16,7 @@ import java.util.regex.Pattern private const val MAX_THUMB_INDEX = 20 +@MangaSourceParser("NUDEMOON", "Nude-Moon", "ru") internal class NudeMoonParser( override val context: MangaLoaderContext, ) : MangaParser(MangaSource.NUDEMOON), MangaParserAuthProvider { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt index 9bb47051..d579bd59 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt @@ -1,9 +1,11 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource +@MangaSourceParser("READMANGA_RU", "ReadManga", "ru") internal class ReadmangaParser(override val context: MangaLoaderContext) : GroupleParser(MangaSource.READMANGA_RU) { override val configKeyDomain = ConfigKey.Domain("readmanga.io", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt index dd970c02..fb5b16bd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt @@ -8,6 +8,7 @@ import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException @@ -27,6 +28,7 @@ private const val PAGE_SIZE = 30 private const val STATUS_ONGOING = 1 private const val STATUS_FINISHED = 0 +@MangaSourceParser("REMANGA", "Remanga", "ru") internal class RemangaParser( override val context: MangaLoaderContext, ) : MangaParser(MangaSource.REMANGA), MangaParserAuthProvider { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt index c485aa1d..e00889e5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt @@ -1,9 +1,11 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource +@MangaSourceParser("SELFMANGA", "SelfManga", "ru") internal class SelfMangaParser(override val context: MangaLoaderContext) : GroupleParser(MangaSource.SELFMANGA) { override val configKeyDomain = ConfigKey.Domain("selfmanga.live", null) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt index 3fec897e..c344cf7b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.Manga @@ -9,6 +10,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.relUrl +@MangaSourceParser("YAOICHAN", "Яой-тян", "ru") internal class YaoiChanParser(override val context: MangaLoaderContext) : ChanParser(MangaSource.YAOICHAN) { override val configKeyDomain = ConfigKey.Domain("yaoi-chan.me", null)