Specify visibility modifiers explicitly

master
Koitharu 2 years ago
parent 1c15e569bf
commit 3918bfafdf
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -80,11 +80,11 @@ class ParserProcessor(
"""
package org.koitharu.kotatsu.parsers.model
enum class MangaParserSource(
val title: String,
val locale: String,
val contentType: ContentType,
val isBroken: Boolean,
public enum class MangaParserSource(
public val title: String,
public val locale: String,
public val contentType: ContentType,
public val isBroken: Boolean,
): MangaSource {
""".trimIndent(),

@ -5,4 +5,4 @@ package org.koitharu.kotatsu.parsers
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class Broken
internal annotation class Broken

@ -1,18 +1,18 @@
package org.koitharu.kotatsu.parsers
object ErrorMessages {
public object ErrorMessages {
const val FILTER_MULTIPLE_STATES_NOT_SUPPORTED = "Multiple states are not supported by this source"
const val FILTER_MULTIPLE_GENRES_NOT_SUPPORTED = "Multiple genres are not supported by this source"
const val FILTER_MULTIPLE_CONTENT_RATING_NOT_SUPPORTED =
public const val FILTER_MULTIPLE_STATES_NOT_SUPPORTED: String = "Multiple states are not supported by this source"
public const val FILTER_MULTIPLE_GENRES_NOT_SUPPORTED: String = "Multiple genres are not supported by this source"
public const val FILTER_MULTIPLE_CONTENT_RATING_NOT_SUPPORTED: String =
"Multiple Content ratings are not supported by this source"
const val FILTER_MULTIPLE_CONTENT_TYPES_NOT_SUPPORTED =
public const val FILTER_MULTIPLE_CONTENT_TYPES_NOT_SUPPORTED: String =
"Multiple Content types are not supported by this source"
const val FILTER_MULTIPLE_DEMOGRAPHICS_NOT_SUPPORTED =
public const val FILTER_MULTIPLE_DEMOGRAPHICS_NOT_SUPPORTED: String =
"Multiple Demographics are not supported by this source"
const val FILTER_BOTH_LOCALE_GENRES_NOT_SUPPORTED =
public const val FILTER_BOTH_LOCALE_GENRES_NOT_SUPPORTED: String =
"Filtering by both genres and locale is not supported by this source"
const val FILTER_BOTH_STATES_GENRES_NOT_SUPPORTED =
public const val FILTER_BOTH_STATES_GENRES_NOT_SUPPORTED: String =
"Filtering by both genres and states is not supported by this source"
const val SEARCH_NOT_SUPPORTED = "Search is not supported by this source"
public const val SEARCH_NOT_SUPPORTED: String = "Search is not supported by this source"
}

@ -11,4 +11,4 @@ package org.koitharu.kotatsu.parsers
@SinceKotlin("1.3")
@RequiresOptIn
@MustBeDocumented
annotation class InternalParsersApi
public annotation class InternalParsersApi

@ -9,30 +9,30 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.model.MangaSource
import java.util.*
abstract class MangaLoaderContext {
public abstract class MangaLoaderContext {
abstract val httpClient: OkHttpClient
public abstract val httpClient: OkHttpClient
abstract val cookieJar: CookieJar
public abstract val cookieJar: CookieJar
fun newParserInstance(source: MangaParserSource): MangaParser = source.newParser(this)
public fun newParserInstance(source: MangaParserSource): MangaParser = source.newParser(this)
open fun encodeBase64(data: ByteArray): String = Base64.getEncoder().encodeToString(data)
public open fun encodeBase64(data: ByteArray): String = Base64.getEncoder().encodeToString(data)
open fun decodeBase64(data: String): ByteArray = Base64.getDecoder().decode(data)
public open fun decodeBase64(data: String): ByteArray = Base64.getDecoder().decode(data)
open fun getPreferredLocales(): List<Locale> = listOf(Locale.getDefault())
public open fun getPreferredLocales(): List<Locale> = listOf(Locale.getDefault())
/**
* Execute JavaScript code and return result
* @param script JavaScript source code
* @return execution result as string, may be null
*/
abstract suspend fun evaluateJs(script: String): String?
public abstract suspend fun evaluateJs(script: String): String?
abstract fun getConfig(source: MangaSource): MangaSourceConfig
public abstract fun getConfig(source: MangaSource): MangaSourceConfig
abstract fun getDefaultUserAgent(): String
public abstract fun getDefaultUserAgent(): String
/**
* Helper function to be used in an interceptor
@ -40,7 +40,7 @@ abstract class MangaLoaderContext {
* @param response Image response
* @param redraw lambda function to implement descrambling logic
*/
abstract fun redrawImageResponse(
public abstract fun redrawImageResponse(
response: Response,
redraw: (image: Bitmap) -> Bitmap,
): Response
@ -48,7 +48,7 @@ abstract class MangaLoaderContext {
/**
* create a new empty Bitmap with given dimensions
*/
abstract fun createBitmap(
public abstract fun createBitmap(
width: Int,
height: Int,
): Bitmap

@ -6,19 +6,19 @@ import org.koitharu.kotatsu.parsers.exception.ParseException
/**
* Implement this in your parser for authorization support
*/
interface MangaParserAuthProvider {
public interface MangaParserAuthProvider {
/**
* Return link to the login page, which will be opened in browser.
* Must be an absolute url
*/
val authUrl: String
public val authUrl: String
/**
* Quick check if user is logged in.
* In most case you should check for cookies in [MangaLoaderContext.cookieJar].
*/
val isAuthorized: Boolean
public val isAuthorized: Boolean
/**
* Fetch and return current user`s name or login.
@ -26,5 +26,5 @@ interface MangaParserAuthProvider {
* @throws [AuthRequiredException] if user is not logged in or authorization is expired
* @throws [ParseException] on parsing error
*/
suspend fun getUsername(): String
}
public suspend fun getUsername(): String
}

@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.model.ContentType
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class MangaSourceParser(
internal annotation class MangaSourceParser(
/**
* Name of manga source. Used as an Enum value, must be UPPER_CASE and unique.
*/

@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.model.SortOrder
@InternalParsersApi
abstract class SinglePageMangaParser(
public abstract class SinglePageMangaParser(
context: MangaLoaderContext,
source: MangaParserSource,
) : MangaParser(context, source) {
@ -18,5 +18,5 @@ abstract class SinglePageMangaParser(
return getList(order, filter)
}
abstract suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga>
public abstract suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga>
}

@ -1,9 +1,9 @@
package org.koitharu.kotatsu.parsers.bitmap
interface Bitmap {
public interface Bitmap {
val width: Int
val height: Int
public val width: Int
public val height: Int
fun drawBitmap(sourceBitmap: Bitmap, src: Rect, dst: Rect)
public fun drawBitmap(sourceBitmap: Bitmap, src: Rect, dst: Rect)
}

@ -1,6 +1,6 @@
package org.koitharu.kotatsu.parsers.bitmap
data class Rect(
public data class Rect(
val left: Int = 0,
val top: Int = 0,
val right: Int = 0,

@ -1,13 +1,13 @@
package org.koitharu.kotatsu.parsers.config
sealed class ConfigKey<T>(
@JvmField val key: String,
public sealed class ConfigKey<T>(
@JvmField public val key: String,
) {
abstract val defaultValue: T
public abstract val defaultValue: T
class Domain(
@JvmField @JvmSuppressWildcards vararg val presetValues: String,
public class Domain(
@JvmField @JvmSuppressWildcards public vararg val presetValues: String,
) : ConfigKey<String>("domain") {
init {
@ -18,20 +18,20 @@ sealed class ConfigKey<T>(
get() = presetValues.first()
}
class ShowSuspiciousContent(
public class ShowSuspiciousContent(
override val defaultValue: Boolean,
) : ConfigKey<Boolean>("show_suspicious")
class UserAgent(
public class UserAgent(
override val defaultValue: String,
) : ConfigKey<String>("user_agent")
class SplitByTranslations(
public class SplitByTranslations(
override val defaultValue: Boolean,
) : ConfigKey<Boolean>("split_translations")
class PreferredImageServer(
val presetValues: Map<String?, String?>,
public class PreferredImageServer(
public val presetValues: Map<String?, String?>,
override val defaultValue: String?,
) : ConfigKey<String?>("img_server")
}

@ -1,6 +1,6 @@
package org.koitharu.kotatsu.parsers.config
interface MangaSourceConfig {
public interface MangaSourceConfig {
operator fun <T> get(key: ConfigKey<T>): T
}
public operator fun <T> get(key: ConfigKey<T>): T
}

@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
/**
* Authorization is required for access to the requested content
*/
class AuthRequiredException @InternalParsersApi @JvmOverloads constructor(
val source: MangaSource,
public class AuthRequiredException @InternalParsersApi @JvmOverloads constructor(
public val source: MangaSource,
cause: Throwable? = null,
) : RuntimeException("Authorization required", cause)

@ -2,86 +2,86 @@ package org.koitharu.kotatsu.parsers.model
import org.koitharu.kotatsu.parsers.InternalParsersApi
class Manga(
public class Manga(
/**
* Unique identifier for manga
*/
@JvmField val id: Long,
@JvmField public val id: Long,
/**
* Manga title, human-readable
*/
@JvmField val title: String,
@JvmField public val title: String,
/**
* Alternative title (for example on other language), may be null
*/
@JvmField val altTitle: String?,
@JvmField public val altTitle: String?,
/**
* Relative url to manga (**without** a domain) or any other uri.
* Used principally in parsers
*/
@JvmField val url: String,
@JvmField public val url: String,
/**
* Absolute url to manga, must be ready to open in browser
*/
@JvmField val publicUrl: String,
@JvmField public val publicUrl: String,
/**
* Normalized manga rating, must be in range of 0..1 or [RATING_UNKNOWN] if rating s unknown
* @see hasRating
*/
@JvmField val rating: Float,
@JvmField public val rating: Float,
/**
* Indicates that manga may contain sensitive information (18+, NSFW)
*/
@JvmField val isNsfw: Boolean,
@JvmField public val isNsfw: Boolean,
/**
* Absolute link to the cover
* @see largeCoverUrl
*/
@JvmField val coverUrl: String,
@JvmField public val coverUrl: String,
/**
* Tags (genres) of the manga
*/
@JvmField val tags: Set<MangaTag>,
@JvmField public val tags: Set<MangaTag>,
/**
* Manga status (ongoing, finished) or null if unknown
*/
@JvmField val state: MangaState?,
@JvmField public val state: MangaState?,
/**
* Author of the manga, may be null
*/
@JvmField val author: String?,
@JvmField public val author: String?,
/**
* Large cover url (absolute), null if is no large cover
* @see coverUrl
*/
@JvmField val largeCoverUrl: String? = null,
@JvmField public val largeCoverUrl: String? = null,
/**
* Manga description, may be html or null
*/
@JvmField val description: String? = null,
@JvmField public val description: String? = null,
/**
* List of chapters
*/
@JvmField val chapters: List<MangaChapter>? = null,
@JvmField public val chapters: List<MangaChapter>? = null,
/**
* Manga source
*/
@JvmField val source: MangaSource,
@JvmField public val source: MangaSource,
) {
/**
* Return if manga has a specified rating
* @see rating
*/
val hasRating: Boolean
public val hasRating: Boolean
get() = rating > 0f && rating <= 1f
fun getChapters(branch: String?): List<MangaChapter>? {
public fun getChapters(branch: String?): List<MangaChapter>? {
return chapters?.filter { x -> x.branch == branch }
}
@InternalParsersApi
fun copy(
public fun copy(
title: String = this.title,
altTitle: String? = this.altTitle,
publicUrl: String = this.publicUrl,
@ -95,7 +95,7 @@ class Manga(
description: String? = this.description,
chapters: List<MangaChapter>? = this.chapters,
source: MangaSource = this.source,
) = Manga(
): Manga = Manga(
id = id,
title = title,
altTitle = altTitle,

@ -1,45 +1,45 @@
package org.koitharu.kotatsu.parsers.model
class MangaChapter(
public class MangaChapter(
/**
* An unique id of chapter
*/
@JvmField val id: Long,
@JvmField public val id: Long,
/**
* User-readable name of chapter
*/
@JvmField val name: String,
@JvmField public val name: String,
/**
* Chapter number starting from 1, 0 if unknown
*/
@JvmField val number: Float,
@JvmField public val number: Float,
/**
* Volume number starting from 1, 0 if unknown
*/
@JvmField val volume: Int,
@JvmField public val volume: Int,
/**
* Relative url to chapter (**without** a domain) or any other uri.
* Used principally in parsers
*/
@JvmField val url: String,
@JvmField public val url: String,
/**
* User-readable name of scanlator (releaser) or null if unknown
*/
@JvmField val scanlator: String?,
@JvmField public val scanlator: String?,
/**
* Chapter upload date in milliseconds
*/
@JvmField val uploadDate: Long,
@JvmField public val uploadDate: Long,
/**
* User-readable name of branch.
* A branch is a group of chapters that overlap (e.g. different languages)
*/
@JvmField val branch: String?,
@JvmField val source: MangaSource,
@JvmField public val branch: String?,
@JvmField public val source: MangaSource,
) {
@Deprecated(message = "Consider using constructor with volume value")
constructor(
internal constructor(
id: Long,
name: String,
number: Int,

@ -2,7 +2,7 @@ package org.koitharu.kotatsu.parsers.model
import org.koitharu.kotatsu.parsers.InternalParsersApi
data class MangaListFilterCapabilities @InternalParsersApi constructor(
public data class MangaListFilterCapabilities @InternalParsersApi constructor(
/**
* Whether parser supports filtering by more than one tag

@ -3,43 +3,43 @@ package org.koitharu.kotatsu.parsers.model
import org.koitharu.kotatsu.parsers.InternalParsersApi
import java.util.*
data class MangaListFilterOptions @InternalParsersApi constructor(
public data class MangaListFilterOptions @InternalParsersApi constructor(
/**
* Available tags (genres)
*/
val availableTags: Set<MangaTag>,
public val availableTags: Set<MangaTag>,
/**
* Supported [MangaState] variants for filtering. May be empty.
*
* For better performance use [EnumSet] for more than one item.
*/
val availableStates: Set<MangaState> = emptySet(),
public val availableStates: Set<MangaState> = emptySet(),
/**
* Supported [ContentRating] variants for filtering. May be empty.
*
* For better performance use [EnumSet] for more than one item.
*/
val availableContentRating: Set<ContentRating> = emptySet(),
public val availableContentRating: Set<ContentRating> = emptySet(),
/**
* Supported [ContentType] variants for filtering. May be empty.
*
* For better performance use [EnumSet] for more than one item.
*/
val availableContentTypes: Set<ContentType> = emptySet(),
public val availableContentTypes: Set<ContentType> = emptySet(),
/**
* Supported [Demographic] variants for filtering. May be empty.
*
* For better performance use [EnumSet] for more than one item.
*/
val availableDemographics: Set<Demographic> = emptySet(),
public val availableDemographics: Set<Demographic> = emptySet(),
/**
* Supported content locales for multilingual sources
*/
val availableLocales: Set<Locale> = emptySet(),
public val availableLocales: Set<Locale> = emptySet(),
)

@ -2,7 +2,7 @@ package org.koitharu.kotatsu.parsers.model
import java.util.*
data class MangaListFilterV2(
public data class MangaListFilterV2(
@JvmField val query: String? = null,
@JvmField val tags: Set<MangaTag> = emptySet(),
@JvmField val tagsExclude: Set<MangaTag> = emptySet(),
@ -17,7 +17,7 @@ data class MangaListFilterV2(
@JvmField val yearTo: Int = 0,
) {
fun isEmpty(): Boolean = tags.isEmpty() &&
public fun isEmpty(): Boolean = tags.isEmpty() &&
tagsExclude.isEmpty() &&
locale == null &&
originalLocale == null &&
@ -30,9 +30,9 @@ data class MangaListFilterV2(
types.isEmpty() &&
demographics.isEmpty()
companion object {
public companion object {
@JvmStatic
val EMPTY = MangaListFilterV2()
public val EMPTY: MangaListFilterV2 = MangaListFilterV2()
}
}

@ -1,6 +1,6 @@
package org.koitharu.kotatsu.parsers.model
interface MangaSource {
public interface MangaSource {
val name: String
public val name: String
}

@ -1,5 +1,5 @@
package org.koitharu.kotatsu.parsers.model
enum class MangaState {
public enum class MangaState {
ONGOING, FINISHED, ABANDONED, PAUSED, UPCOMING
}

@ -2,17 +2,17 @@ package org.koitharu.kotatsu.parsers.model
import org.koitharu.kotatsu.parsers.MangaParser
class MangaTag(
public class MangaTag(
/**
* User-readable tag title, should be in Title case
*/
@JvmField val title: String,
@JvmField public val title: String,
/**
* Identifier of a tag, must be unique among the source.
* @see MangaParser.getList
*/
@JvmField val key: String,
@JvmField val source: MangaSource,
@JvmField public val key: String,
@JvmField public val source: MangaSource,
) {
override fun equals(other: Any?): Boolean {

@ -3,9 +3,9 @@ package org.koitharu.kotatsu.parsers.model
import org.koitharu.kotatsu.parsers.InternalParsersApi
@InternalParsersApi
class WordSet(private vararg val words: String) {
public class WordSet(private vararg val words: String) {
fun anyWordIn(dateString: String): Boolean = words.any {
public fun anyWordIn(dateString: String): Boolean = words.any {
dateString.contains(it, ignoreCase = true)
}
}
}

@ -27,7 +27,7 @@ import kotlin.math.min
@OptIn(ExperimentalUnsignedTypes::class)
@MangaSourceParser("HITOMILA", "Hitomi.La", type = ContentType.HENTAI)
class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HITOMILA) {
internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HITOMILA) {
override val configKeyDomain = ConfigKey.Domain("hitomi.la")
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {

@ -21,7 +21,8 @@ import javax.crypto.spec.SecretKeySpec
import kotlin.math.min
@MangaSourceParser("MANGAREADERTO", "MangaReader.To")
class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.MANGAREADERTO, 16),
internal class MangaReaderToParser(context: MangaLoaderContext) :
PagedMangaParser(context, MangaParserSource.MANGAREADERTO, 16),
Interceptor, MangaParserAuthProvider {
override val configKeyDomain = ConfigKey.Domain("mangareader.to")

@ -14,7 +14,7 @@ import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("TUMANGAONLINE", "TuMangaOnline", "es")
class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
internal class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
context,
source = MangaParserSource.TUMANGAONLINE,
pageSize = 24,

@ -11,7 +11,7 @@ import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("DOUJINDESU", "DoujinDesu.tv", "id")
class DoujinDesuParser(context: MangaLoaderContext) :
internal class DoujinDesuParser(context: MangaLoaderContext) :
PagedMangaParser(context, MangaParserSource.DOUJINDESU, pageSize = 18) {
override val configKeyDomain: ConfigKey.Domain

@ -9,7 +9,7 @@ import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.*
abstract class MangaWorldParser(
internal abstract class MangaWorldParser(
context: MangaLoaderContext,
source: MangaParserSource,
domain: String,

@ -9,7 +9,7 @@ import java.util.*
@Broken
@MangaSourceParser("LERMANGA", "LerManga", "pt")
class LerManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.LERMANGA, 24) {
internal class LerManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.LERMANGA, 24) {
override val availableSortOrders: Set<SortOrder> =
EnumSet.of(

@ -11,7 +11,7 @@ import java.util.*
@Broken
@MangaSourceParser("ONEPIECEEX", "OnePieceEx", "pt")
class OnePieceEx(context: MangaLoaderContext) : SinglePageMangaParser(context, MangaParserSource.ONEPIECEEX) {
internal class OnePieceEx(context: MangaLoaderContext) : SinglePageMangaParser(context, MangaParserSource.ONEPIECEEX) {
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)

@ -13,7 +13,8 @@ import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("YUGENMANGAS", "YugenApp", "pt")
class YugenMangas(context: MangaLoaderContext) : SinglePageMangaParser(context, MangaParserSource.YUGENMANGAS) {
internal class YugenMangas(context: MangaLoaderContext) :
SinglePageMangaParser(context, MangaParserSource.YUGENMANGAS) {
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.ALPHABETICAL)
override val configKeyDomain = ConfigKey.Domain("yugenmangasbr.voblog.xyz")

@ -16,7 +16,7 @@ import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("MANGA_WTF", "MangaWtf", "ru")
class MangaWtfParser(
internal class MangaWtfParser(
context: MangaLoaderContext,
) : PagedMangaParser(context, MangaParserSource.MANGA_WTF, pageSize = 20) {

@ -10,7 +10,7 @@ import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("YAOIFLIX", "YaoiFlix", "tr", ContentType.HENTAI)
class YaoiFlix(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.YAOIFLIX, 8) {
internal class YaoiFlix(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.YAOIFLIX, 8) {
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)

@ -12,7 +12,7 @@ import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("YURINEKO", "YuriNeko", "vi", ContentType.HENTAI)
class YurinekoParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.YURINEKO, 20) {
internal class YurinekoParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.YURINEKO, 20) {
override val configKeyDomain: ConfigKey.Domain
get() = ConfigKey.Domain("yurineko.net")

@ -1,8 +1,8 @@
package org.koitharu.kotatsu.parsers.util
fun <T : Any> T?.assertNotNull(name: String): T? {
internal fun <T : Any> T?.assertNotNull(name: String): T? {
assert(this != null) {
"Value $name is null"
}
return this
}
}

@ -4,7 +4,7 @@ import org.koitharu.kotatsu.parsers.InternalParsersApi
import org.koitharu.kotatsu.parsers.model.MangaChapter
@InternalParsersApi
inline fun <T> List<T>.mapChapters(
public inline fun <T> List<T>.mapChapters(
reversed: Boolean = false,
transform: (index: Int, T) -> MangaChapter?,
): List<MangaChapter> {
@ -20,7 +20,7 @@ inline fun <T> List<T>.mapChapters(
}
@InternalParsersApi
inline fun <T> List<T>.flatMapChapters(
public inline fun <T> List<T>.flatMapChapters(
reversed: Boolean = false,
transform: (T) -> Iterable<MangaChapter?>,
): List<MangaChapter> {

@ -7,11 +7,11 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlin.coroutines.cancellation.CancellationException
fun Iterable<Job>.cancelAll(cause: CancellationException? = null) {
public fun Iterable<Job>.cancelAll(cause: CancellationException? = null) {
forEach { it.cancel(cause) }
}
suspend fun <T> Iterable<Deferred<T>>.awaitFirst(): T {
public suspend fun <T> Iterable<Deferred<T>>.awaitFirst(): T {
return channelFlow {
for (deferred in this@awaitFirst) {
launch {
@ -21,7 +21,7 @@ suspend fun <T> Iterable<Deferred<T>>.awaitFirst(): T {
}.first().also { this@awaitFirst.cancelAll() }
}
suspend fun <T> Collection<Deferred<T>>.awaitFirst(condition: (T) -> Boolean): T {
public suspend fun <T> Collection<Deferred<T>>.awaitFirst(condition: (T) -> Boolean): T {
return channelFlow {
for (deferred in this@awaitFirst) {
launch {

@ -4,10 +4,10 @@ package org.koitharu.kotatsu.parsers.util
import kotlin.enums.EnumEntries
fun <E : Enum<E>> EnumEntries<E>.names() = Array(size) { i ->
public fun <E : Enum<E>> EnumEntries<E>.names() = Array(size) { i ->
get(i).name
}
fun <E : Enum<E>> EnumEntries<E>.find(name: String): E? {
public fun <E : Enum<E>> EnumEntries<E>.find(name: String): E? {
return find { x -> x.name == name }
}

@ -6,12 +6,12 @@ import org.koitharu.kotatsu.parsers.model.Favicons
import org.koitharu.kotatsu.parsers.network.WebClient
import org.koitharu.kotatsu.parsers.util.json.mapJSON
class FaviconParser(
public class FaviconParser(
private val webClient: WebClient,
private val domain: String,
) {
suspend fun parseFavicons(): Favicons {
public suspend fun parseFavicons(): Favicons {
val url = "https://$domain"
val doc = webClient.httpGet(url).parseHtml()
val result = HashSet<Favicon>()

Loading…
Cancel
Save