Comick: fix new chapters delay and small refactor (#1354)
* remove chapter pagination page parameter seems to trigger some cache issue in their api * update baseUrl * data class -> class micro optimization * small refactor * remove useless interceptor * oops * mutable not needed
This commit is contained in:
		
							parent
							
								
									9fa6b8cb51
								
							
						
					
					
						commit
						9602aa5dd5
					
				| @ -3,7 +3,7 @@ | |||||||
| 
 | 
 | ||||||
|     <application> |     <application> | ||||||
|         <activity |         <activity | ||||||
|             android:name=".all.comickfun.ComickFunUrlActivity" |             android:name=".all.comickfun.ComickUrlActivity" | ||||||
|             android:excludeFromRecents="true" |             android:excludeFromRecents="true" | ||||||
|             android:exported="true" |             android:exported="true" | ||||||
|             android:theme="@android:style/Theme.NoDisplay"> |             android:theme="@android:style/Theme.NoDisplay"> | ||||||
| @ -14,6 +14,7 @@ | |||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE" /> | ||||||
| 
 | 
 | ||||||
|                 <data android:scheme="https" /> |                 <data android:scheme="https" /> | ||||||
|  |                 <data android:host="comick.io" /> | ||||||
|                 <data android:host="comick.cc" /> |                 <data android:host="comick.cc" /> | ||||||
|                 <data android:host="comick.ink" /> |                 <data android:host="comick.ink" /> | ||||||
|                 <data android:host="comick.app" /> |                 <data android:host="comick.app" /> | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| ext { | ext { | ||||||
|     extName = 'Comick' |     extName = 'Comick' | ||||||
|     extClass = '.ComickFunFactory' |     extClass = '.ComickFactory' | ||||||
|     extVersionCode = 41 |     extVersionCode = 42 | ||||||
|     isNsfw = true |     isNsfw = true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -26,19 +26,16 @@ import okhttp3.Response | |||||||
| import rx.Observable | import rx.Observable | ||||||
| import uy.kohesive.injekt.Injekt | import uy.kohesive.injekt.Injekt | ||||||
| import uy.kohesive.injekt.api.get | import uy.kohesive.injekt.api.get | ||||||
| import java.text.SimpleDateFormat |  | ||||||
| import java.util.Locale |  | ||||||
| import java.util.TimeZone |  | ||||||
| import kotlin.math.min | import kotlin.math.min | ||||||
| 
 | 
 | ||||||
| abstract class ComickFun( | abstract class Comick( | ||||||
|     override val lang: String, |     override val lang: String, | ||||||
|     private val comickFunLang: String, |     private val comickLang: String, | ||||||
| ) : ConfigurableSource, HttpSource() { | ) : ConfigurableSource, HttpSource() { | ||||||
| 
 | 
 | ||||||
|     override val name = "Comick" |     override val name = "Comick" | ||||||
| 
 | 
 | ||||||
|     override val baseUrl = "https://comick.cc" |     override val baseUrl = "https://comick.io" | ||||||
| 
 | 
 | ||||||
|     private val apiUrl = "https://api.comick.fun" |     private val apiUrl = "https://api.comick.fun" | ||||||
| 
 | 
 | ||||||
| @ -62,8 +59,9 @@ abstract class ComickFun( | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private val preferences: SharedPreferences by lazy { |     private val preferences by lazy { | ||||||
|         Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) |         Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) | ||||||
|  |             .newLineIgnoredGroups() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun setupPreferenceScreen(screen: PreferenceScreen) { |     override fun setupPreferenceScreen(screen: PreferenceScreen) { | ||||||
| @ -151,23 +149,18 @@ abstract class ComickFun( | |||||||
|     private val SharedPreferences.scorePosition: String |     private val SharedPreferences.scorePosition: String | ||||||
|         get() = getString(SCORE_POSITION_PREF, SCORE_POSITION_DEFAULT) ?: SCORE_POSITION_DEFAULT |         get() = getString(SCORE_POSITION_PREF, SCORE_POSITION_DEFAULT) ?: SCORE_POSITION_DEFAULT | ||||||
| 
 | 
 | ||||||
|     init { |  | ||||||
|         preferences.newLineIgnoredGroups() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun headersBuilder() = Headers.Builder().apply { |     override fun headersBuilder() = Headers.Builder().apply { | ||||||
|         add("Referer", "$baseUrl/") |         add("Referer", "$baseUrl/") | ||||||
|         add("User-Agent", "Tachiyomi ${System.getProperty("http.agent")}") |         add("User-Agent", "Tachiyomi ${System.getProperty("http.agent")}") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override val client = network.client.newBuilder() |     override val client = network.client.newBuilder() | ||||||
|         .addInterceptor(::thumbnailIntercept) |  | ||||||
|         .rateLimit(3, 1) |         .rateLimit(3, 1) | ||||||
|         .build() |         .build() | ||||||
| 
 | 
 | ||||||
|     /** Popular Manga **/ |     /** Popular Manga **/ | ||||||
|     override fun popularMangaRequest(page: Int): Request { |     override fun popularMangaRequest(page: Int): Request { | ||||||
|         val url = "$apiUrl/v1.0/search?sort=follow&limit=$limit&page=$page&tachiyomi=true" |         val url = "$apiUrl/v1.0/search?sort=follow&limit=$LIMIT&page=$page&tachiyomi=true" | ||||||
|         return GET(url, headers) |         return GET(url, headers) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -175,13 +168,13 @@ abstract class ComickFun( | |||||||
|         val result = response.parseAs<List<SearchManga>>() |         val result = response.parseAs<List<SearchManga>>() | ||||||
|         return MangasPage( |         return MangasPage( | ||||||
|             result.map(SearchManga::toSManga), |             result.map(SearchManga::toSManga), | ||||||
|             hasNextPage = result.size >= limit, |             hasNextPage = result.size >= LIMIT, | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Latest Manga **/ |     /** Latest Manga **/ | ||||||
|     override fun latestUpdatesRequest(page: Int): Request { |     override fun latestUpdatesRequest(page: Int): Request { | ||||||
|         val url = "$apiUrl/v1.0/search?sort=uploaded&limit=$limit&page=$page&tachiyomi=true" |         val url = "$apiUrl/v1.0/search?sort=uploaded&limit=$LIMIT&page=$page&tachiyomi=true" | ||||||
|         return GET(url, headers) |         return GET(url, headers) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -233,8 +226,8 @@ abstract class ComickFun( | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun paginatedSearchPage(page: Int): MangasPage { |     private fun paginatedSearchPage(page: Int): MangasPage { | ||||||
|         val end = min(page * limit, searchResponse.size) |         val end = min(page * LIMIT, searchResponse.size) | ||||||
|         val entries = searchResponse.subList((page - 1) * limit, end) |         val entries = searchResponse.subList((page - 1) * LIMIT, end) | ||||||
|             .map(SearchManga::toSManga) |             .map(SearchManga::toSManga) | ||||||
|         return MangasPage(entries, end < searchResponse.size) |         return MangasPage(entries, end < searchResponse.size) | ||||||
|     } |     } | ||||||
| @ -317,7 +310,7 @@ abstract class ComickFun( | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             addQueryParameter("tachiyomi", "true") |             addQueryParameter("tachiyomi", "true") | ||||||
|             addQueryParameter("limit", "$limit") |             addQueryParameter("limit", "$LIMIT") | ||||||
|             addQueryParameter("page", "$page") |             addQueryParameter("page", "$page") | ||||||
|         }.build() |         }.build() | ||||||
| 
 | 
 | ||||||
| @ -367,7 +360,7 @@ abstract class ComickFun( | |||||||
|             val coversUrl = |             val coversUrl = | ||||||
|                 "$apiUrl/comic/${mangaData.comic.slug ?: mangaData.comic.hid}/covers?tachiyomi=true" |                 "$apiUrl/comic/${mangaData.comic.slug ?: mangaData.comic.hid}/covers?tachiyomi=true" | ||||||
|             val covers = client.newCall(GET(coversUrl)).execute() |             val covers = client.newCall(GET(coversUrl)).execute() | ||||||
|                 .parseAs<Covers>().md_covers.reversed() |                 .parseAs<Covers>().mdCovers.reversed() | ||||||
|             return mangaData.toSManga( |             return mangaData.toSManga( | ||||||
|                 includeMuTags = preferences.includeMuTags, |                 includeMuTags = preferences.includeMuTags, | ||||||
|                 covers = if (covers.any { it.vol == "1" }) covers.filter { it.vol == "1" } else covers, |                 covers = if (covers.any { it.vol == "1" }) covers.filter { it.vol == "1" } else covers, | ||||||
| @ -387,19 +380,15 @@ abstract class ComickFun( | |||||||
|             throw Exception("Migrate from Comick to Comick") |             throw Exception("Migrate from Comick to Comick") | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return paginatedChapterListRequest(manga.url.removeSuffix("#"), 1) |         val mangaUrl = manga.url.removeSuffix("#") | ||||||
|     } |         val url = "$apiUrl$mangaUrl".toHttpUrl().newBuilder().apply { | ||||||
|  |             addPathSegment("chapters") | ||||||
|  |             if (comickLang != "all") addQueryParameter("lang", comickLang) | ||||||
|  |             addQueryParameter("tachiyomi", "true") | ||||||
|  |             addQueryParameter("limit", "$CHAPTERS_LIMIT") | ||||||
|  |         }.build() | ||||||
| 
 | 
 | ||||||
|     private fun paginatedChapterListRequest(mangaUrl: String, page: Int): Request { |         return GET(url, headers) | ||||||
|         return GET( |  | ||||||
|             "$apiUrl$mangaUrl".toHttpUrl().newBuilder().apply { |  | ||||||
|                 addPathSegment("chapters") |  | ||||||
|                 if (comickFunLang != "all") addQueryParameter("lang", comickFunLang) |  | ||||||
|                 addQueryParameter("tachiyomi", "true") |  | ||||||
|                 addQueryParameter("page", "$page") |  | ||||||
|             }.build(), |  | ||||||
|             headers, |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun chapterListParse(response: Response): List<SChapter> { |     override fun chapterListParse(response: Response): List<SChapter> { | ||||||
| @ -409,20 +398,6 @@ abstract class ComickFun( | |||||||
|             .substringBefore("/chapters") |             .substringBefore("/chapters") | ||||||
|             .substringAfter(apiUrl) |             .substringAfter(apiUrl) | ||||||
| 
 | 
 | ||||||
|         var resultSize = chapterListResponse.chapters.size |  | ||||||
|         var page = 2 |  | ||||||
| 
 |  | ||||||
|         while (chapterListResponse.total > resultSize) { |  | ||||||
|             val newRequest = paginatedChapterListRequest(mangaUrl, page) |  | ||||||
|             val newResponse = client.newCall(newRequest).execute() |  | ||||||
|             val newChapterListResponse = newResponse.parseAs<ChapterList>() |  | ||||||
| 
 |  | ||||||
|             chapterListResponse.chapters += newChapterListResponse.chapters |  | ||||||
| 
 |  | ||||||
|             resultSize += newChapterListResponse.chapters.size |  | ||||||
|             page += 1 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return chapterListResponse.chapters |         return chapterListResponse.chapters | ||||||
|             .filter { |             .filter { | ||||||
|                 it.groups.map { g -> g.lowercase() }.intersect(preferences.ignoredGroups).isEmpty() |                 it.groups.map { g -> g.lowercase() }.intersect(preferences.ignoredGroups).isEmpty() | ||||||
| @ -457,8 +432,8 @@ abstract class ComickFun( | |||||||
| 
 | 
 | ||||||
|     override fun getFilterList() = getFilters() |     override fun getFilterList() = getFilters() | ||||||
| 
 | 
 | ||||||
|     private fun SharedPreferences.newLineIgnoredGroups() { |     private fun SharedPreferences.newLineIgnoredGroups(): SharedPreferences { | ||||||
|         if (getBoolean(MIGRATED_IGNORED_GROUPS, false)) return |         if (getBoolean(MIGRATED_IGNORED_GROUPS, false)) return this | ||||||
|         val ignoredGroups = getString(IGNORED_GROUPS_PREF, "").orEmpty() |         val ignoredGroups = getString(IGNORED_GROUPS_PREF, "").orEmpty() | ||||||
| 
 | 
 | ||||||
|         edit() |         edit() | ||||||
| @ -472,6 +447,8 @@ abstract class ComickFun( | |||||||
|             ) |             ) | ||||||
|             .putBoolean(MIGRATED_IGNORED_GROUPS, true) |             .putBoolean(MIGRATED_IGNORED_GROUPS, true) | ||||||
|             .apply() |             .apply() | ||||||
|  | 
 | ||||||
|  |         return this | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     companion object { |     companion object { | ||||||
| @ -484,14 +461,7 @@ abstract class ComickFun( | |||||||
|         private const val FIRST_COVER_DEFAULT = true |         private const val FIRST_COVER_DEFAULT = true | ||||||
|         private const val SCORE_POSITION_PREF = "ScorePosition" |         private const val SCORE_POSITION_PREF = "ScorePosition" | ||||||
|         private const val SCORE_POSITION_DEFAULT = "top" |         private const val SCORE_POSITION_DEFAULT = "top" | ||||||
|         private const val limit = 20 |         private const val LIMIT = 20 | ||||||
|         val dateFormat by lazy { |         private const val CHAPTERS_LIMIT = 99999 | ||||||
|             SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH).apply { |  | ||||||
|                 timeZone = TimeZone.getTimeZone("UTC") |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         val markdownLinksRegex = "\\[([^]]+)]\\(([^)]+)\\)".toRegex() |  | ||||||
|         val markdownItalicBoldRegex = "\\*+\\s*([^*]*)\\s*\\*+".toRegex() |  | ||||||
|         val markdownItalicRegex = "_+\\s*([^_]*)\\s*_+".toRegex() |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -10,7 +10,7 @@ val legacyLanguageMappings = mapOf( | |||||||
|     "zh" to "zh-Hans", // Simplified Chinese |     "zh" to "zh-Hans", // Simplified Chinese | ||||||
| ).withDefault { it } // country code matches language code | ).withDefault { it } // country code matches language code | ||||||
| 
 | 
 | ||||||
| class ComickFunFactory : SourceFactory { | class ComickFactory : SourceFactory { | ||||||
|     private val idMap = listOf( |     private val idMap = listOf( | ||||||
|         "all" to 982606170401027267, |         "all" to 982606170401027267, | ||||||
|         "en" to 2971557565147974499, |         "en" to 2971557565147974499, | ||||||
| @ -55,7 +55,7 @@ class ComickFunFactory : SourceFactory { | |||||||
|         "da" to 7137437402245830147, |         "da" to 7137437402245830147, | ||||||
|     ).toMap() |     ).toMap() | ||||||
|     override fun createSources(): List<Source> = idMap.keys.map { |     override fun createSources(): List<Source> = idMap.keys.map { | ||||||
|         object : ComickFun(legacyLanguageMappings.getValue(it), it) { |         object : Comick(legacyLanguageMappings.getValue(it), it) { | ||||||
|             override val id: Long = idMap[it]!! |             override val id: Long = idMap[it]!! | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -7,7 +7,7 @@ import android.os.Bundle | |||||||
| import android.util.Log | import android.util.Log | ||||||
| import kotlin.system.exitProcess | import kotlin.system.exitProcess | ||||||
| 
 | 
 | ||||||
| class ComickFunUrlActivity : Activity() { | class ComickUrlActivity : Activity() { | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|         val pathSegments = intent?.data?.pathSegments |         val pathSegments = intent?.data?.pathSegments | ||||||
| @ -15,7 +15,7 @@ class ComickFunUrlActivity : Activity() { | |||||||
|             val slug = pathSegments[1] |             val slug = pathSegments[1] | ||||||
|             val mainIntent = Intent().apply { |             val mainIntent = Intent().apply { | ||||||
|                 action = "eu.kanade.tachiyomi.SEARCH" |                 action = "eu.kanade.tachiyomi.SEARCH" | ||||||
|                 putExtra("query", "${ComickFun.SLUG_SEARCH_PREFIX}$slug") |                 putExtra("query", "${Comick.SLUG_SEARCH_PREFIX}$slug") | ||||||
|                 putExtra("filter", packageName) |                 putExtra("filter", packageName) | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -8,9 +8,9 @@ import java.math.BigDecimal | |||||||
| import java.math.RoundingMode | import java.math.RoundingMode | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class SearchManga( | class SearchManga( | ||||||
|     val hid: String, |     private val hid: String, | ||||||
|     val title: String, |     private val title: String, | ||||||
|     @SerialName("md_covers") val mdCovers: List<MDcovers> = emptyList(), |     @SerialName("md_covers") val mdCovers: List<MDcovers> = emptyList(), | ||||||
|     @SerialName("cover_url") val cover: String? = null, |     @SerialName("cover_url") val cover: String? = null, | ||||||
| ) { | ) { | ||||||
| @ -23,12 +23,12 @@ data class SearchManga( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Manga( | class Manga( | ||||||
|     val comic: Comic, |     val comic: Comic, | ||||||
|     val artists: List<Name> = emptyList(), |     private val artists: List<Name> = emptyList(), | ||||||
|     val authors: List<Name> = emptyList(), |     private val authors: List<Name> = emptyList(), | ||||||
|     val genres: List<Name> = emptyList(), |     private val genres: List<Name> = emptyList(), | ||||||
|     val demographic: String? = null, |     private val demographic: String? = null, | ||||||
| ) { | ) { | ||||||
|     fun toSManga( |     fun toSManga( | ||||||
|         includeMuTags: Boolean = false, |         includeMuTags: Boolean = false, | ||||||
| @ -90,10 +90,10 @@ data class Manga( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Comic( | class Comic( | ||||||
|     val hid: String, |     val hid: String, | ||||||
|     val title: String, |     val title: String, | ||||||
|     val country: String? = null, |     private val country: String? = null, | ||||||
|     val slug: String? = null, |     val slug: String? = null, | ||||||
|     @SerialName("md_titles") val altTitles: List<Title> = emptyList(), |     @SerialName("md_titles") val altTitles: List<Title> = emptyList(), | ||||||
|     val desc: String? = null, |     val desc: String? = null, | ||||||
| @ -125,55 +125,54 @@ data class Comic( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class MdGenres( | class MdGenres( | ||||||
|     @SerialName("md_genres") val name: Name? = null, |     @SerialName("md_genres") val name: Name? = null, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class MuComicCategories( | class MuComicCategories( | ||||||
|     @SerialName("mu_comic_categories") val categories: List<MuCategories?> = emptyList(), |     @SerialName("mu_comic_categories") val categories: List<MuCategories?> = emptyList(), | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class MuCategories( | class MuCategories( | ||||||
|     @SerialName("mu_categories") val category: Title? = null, |     @SerialName("mu_categories") val category: Title? = null, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Covers( | class Covers( | ||||||
|     val md_covers: List<MDcovers> = emptyList(), |     @SerialName("md_covers") val mdCovers: List<MDcovers> = emptyList(), | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class MDcovers( | class MDcovers( | ||||||
|     val b2key: String?, |     val b2key: String?, | ||||||
|     val vol: String? = null, |     val vol: String? = null, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Title( | class Title( | ||||||
|     val title: String?, |     val title: String?, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Name( | class Name( | ||||||
|     val name: String, |     val name: String, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class ChapterList( | class ChapterList( | ||||||
|     val chapters: MutableList<Chapter>, |     val chapters: List<Chapter>, | ||||||
|     val total: Int, |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Chapter( | class Chapter( | ||||||
|     val hid: String, |     private val hid: String, | ||||||
|     val lang: String = "", |     private val lang: String = "", | ||||||
|     val title: String = "", |     private val title: String = "", | ||||||
|     @SerialName("created_at") val createdAt: String = "", |     @SerialName("created_at") val createdAt: String = "", | ||||||
|     val chap: String = "", |     private val chap: String = "", | ||||||
|     val vol: String = "", |     private val vol: String = "", | ||||||
|     @SerialName("group_name") val groups: List<String> = emptyList(), |     @SerialName("group_name") val groups: List<String> = emptyList(), | ||||||
| ) { | ) { | ||||||
|     fun toSChapter(mangaUrl: String) = SChapter.create().apply { |     fun toSChapter(mangaUrl: String) = SChapter.create().apply { | ||||||
| @ -185,16 +184,16 @@ data class Chapter( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class PageList( | class PageList( | ||||||
|     val chapter: ChapterPageData, |     val chapter: ChapterPageData, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class ChapterPageData( | class ChapterPageData( | ||||||
|     val images: List<Page>, |     val images: List<Page>, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @Serializable | @Serializable | ||||||
| data class Page( | class Page( | ||||||
|     val url: String? = null, |     val url: String? = null, | ||||||
| ) | ) | ||||||
| @ -1,13 +1,19 @@ | |||||||
| package eu.kanade.tachiyomi.extension.all.comickfun | package eu.kanade.tachiyomi.extension.all.comickfun | ||||||
| 
 | 
 | ||||||
| import eu.kanade.tachiyomi.extension.all.comickfun.ComickFun.Companion.dateFormat |  | ||||||
| import eu.kanade.tachiyomi.extension.all.comickfun.ComickFun.Companion.markdownItalicBoldRegex |  | ||||||
| import eu.kanade.tachiyomi.extension.all.comickfun.ComickFun.Companion.markdownItalicRegex |  | ||||||
| import eu.kanade.tachiyomi.extension.all.comickfun.ComickFun.Companion.markdownLinksRegex |  | ||||||
| import eu.kanade.tachiyomi.source.model.SManga | import eu.kanade.tachiyomi.source.model.SManga | ||||||
| import okhttp3.Interceptor |  | ||||||
| import okhttp3.Response |  | ||||||
| import org.jsoup.parser.Parser | import org.jsoup.parser.Parser | ||||||
|  | import java.text.SimpleDateFormat | ||||||
|  | import java.util.Locale | ||||||
|  | import java.util.TimeZone | ||||||
|  | 
 | ||||||
|  | private val dateFormat by lazy { | ||||||
|  |     SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH).apply { | ||||||
|  |         timeZone = TimeZone.getTimeZone("UTC") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | private val markdownLinksRegex = "\\[([^]]+)]\\(([^)]+)\\)".toRegex() | ||||||
|  | private val markdownItalicBoldRegex = "\\*+\\s*([^*]*)\\s*\\*+".toRegex() | ||||||
|  | private val markdownItalicRegex = "_+\\s*([^_]*)\\s*_+".toRegex() | ||||||
| 
 | 
 | ||||||
| internal fun String.beautifyDescription(): String { | internal fun String.beautifyDescription(): String { | ||||||
|     return Parser.unescapeEntities(this, false) |     return Parser.unescapeEntities(this, false) | ||||||
| @ -42,25 +48,6 @@ internal fun parseCover(thumbnailUrl: String?, mdCovers: List<MDcovers>): String | |||||||
|     return thumbnailUrl?.replaceAfterLast("/", "$b2key#$vol") |     return thumbnailUrl?.replaceAfterLast("/", "$b2key#$vol") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| internal fun thumbnailIntercept(chain: Interceptor.Chain): Response { |  | ||||||
|     val request = chain.request() |  | ||||||
|     val frag = request.url.fragment |  | ||||||
|     if (frag.isNullOrEmpty()) return chain.proceed(request) |  | ||||||
|     val response = chain.proceed(request) |  | ||||||
|     if (!response.isSuccessful && response.code == 404) { |  | ||||||
|         response.close() |  | ||||||
|         val url = request.url.toString() |  | ||||||
|             .replaceAfterLast("/", frag) |  | ||||||
| 
 |  | ||||||
|         return chain.proceed( |  | ||||||
|             request.newBuilder() |  | ||||||
|                 .url(url) |  | ||||||
|                 .build(), |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
|     return response |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| internal fun beautifyChapterName(vol: String, chap: String, title: String): String { | internal fun beautifyChapterName(vol: String, chap: String, title: String): String { | ||||||
|     return buildString { |     return buildString { | ||||||
|         if (vol.isNotEmpty()) { |         if (vol.isNotEmpty()) { | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 AwkwardPeak7
						AwkwardPeak7