Make date formatters thread-safe (#12014)

This commit is contained in:
kasperskier 2022-06-01 10:42:46 +08:00 committed by GitHub
parent b62fe0d0e0
commit db0c2d7646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 24 deletions

View File

@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
import java.text.DateFormat.getDateInstance import java.text.DateFormat.getDateTimeInstance
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.TimeZone import java.util.TimeZone
@ -63,7 +63,7 @@ open class ComicGamma(
val dateStr = nextDate.textNodes() val dateStr = nextDate.textNodes()
.filter { it.text().contains("【次回更新】") }[0] .filter { it.text().contains("【次回更新】") }[0]
.text().trim().removePrefix("【次回更新】") .text().trim().removePrefix("【次回更新】")
val localDate = JST_FORMAT.parse(dateStr)?.let { LOCAL_FORMAT.format(it) } val localDate = JST_FORMAT_DESC.parseJST(dateStr)?.let { LOCAL_FORMAT_DESC.format(it) }
if (localDate != null) description = "【Next/Repeat: $localDate\n$description" if (localDate != null) description = "【Next/Repeat: $localDate\n$description"
} }
} }
@ -79,9 +79,17 @@ open class ComicGamma(
it.text().contains("集中連載") || it.text().contains("配信中!!") it.text().contains("集中連載") || it.text().contains("配信中!!")
}.joinToString("") { it.text() } }.joinToString("") { it.text() }
name = "$chapterNumber $title" name = "$chapterNumber $title"
val date = element.select(".episode_caption").textNodes().firstOrNull { it.text().contains("【公開日】") } element.select(".episode_caption").textNodes().forEach {
?.text()?.trim()?.removePrefix("【公開日】") if (it.text().contains("【公開日】")) {
date_upload = date?.let { JST_FORMAT.parse(it)?.time } ?: -1L // hide unknown ones val date = it.text().trim().removePrefix("【公開日】")
date_upload = JST_FORMAT_LIST.parseJST(date)!!.time
} else if (it.text().contains("【次回更新】")) {
val date = it.text().trim().removePrefix("【次回更新】")
val localDate = JST_FORMAT_LIST.parseJST(date)?.let { LOCAL_FORMAT_LIST.format(it) }
if (localDate != null) scanlator = "~$localDate"
}
}
if (date_upload <= 0L) date_upload = -1L // hide unknown ones
} }
override fun pageListParse(document: Document) = override fun pageListParse(document: Document) =
@ -91,10 +99,20 @@ open class ComicGamma(
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.") override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
// for thread-safety (of subclasses)
private val JST_FORMAT_DESC = getJSTFormat()
private val JST_FORMAT_LIST = getJSTFormat()
private val LOCAL_FORMAT_DESC = getDateTimeInstance()
private val LOCAL_FORMAT_LIST = getDateTimeInstance()
companion object { companion object {
private val JST_FORMAT by lazy { private fun SimpleDateFormat.parseJST(date: String) = parse(date)?.apply {
SimpleDateFormat("yyyy年M月dd日(E)", Locale.JAPANESE).apply { timeZone = TimeZone.getTimeZone("JST") } time += 12 * 3600 * 1000 // updates at 12 noon
} }
private val LOCAL_FORMAT by lazy { getDateInstance() }
private fun getJSTFormat() =
SimpleDateFormat("yyyy年M月dd日(E)", Locale.JAPANESE).apply {
timeZone = TimeZone.getTimeZone("GMT+09:00")
}
} }
} }

View File

@ -6,7 +6,7 @@ import generator.ThemeSourceGenerator
class ComicGammaGenerator : ThemeSourceGenerator { class ComicGammaGenerator : ThemeSourceGenerator {
override val themeClass = "ComicGamma" override val themeClass = "ComicGamma"
override val themePkg = "comicgamma" override val themePkg = "comicgamma"
override val baseVersionCode = 1 override val baseVersionCode = 2
override val sources = listOf( override val sources = listOf(
SingleLang( SingleLang(
name = "Web Comic Gamma", name = "Web Comic Gamma",

View File

@ -6,7 +6,7 @@ ext {
extName = 'Manga Cross' extName = 'Manga Cross'
pkgNameSuffix = 'ja.mangacross' pkgNameSuffix = 'ja.mangacross'
extClass = '.MangaCross' extClass = '.MangaCross'
extVersionCode = 3 extVersionCode = 4
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -88,16 +88,6 @@ data class MCEpisodeList(
val total_pages: Int, val total_pages: Int,
) )
private val jstDate by lazy {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).apply {
timeZone = TimeZone.getTimeZone("GMT+09:00")
}
}
private val localDate by lazy { getDateTimeInstance() }
private fun parseJSTDate(date: String) = date.removeSuffix("+09:00").let { jstDate.parse(it) }!!
@Serializable @Serializable
data class MCEpisode( data class MCEpisode(
// val id: Long, // val id: Long,
@ -121,21 +111,35 @@ data class MCEpisode(
val prefix = if (status == "public") "" else "🔒 " val prefix = if (status == "public") "" else "🔒 "
name = "$prefix$volume $title" name = "$prefix$volume $title"
// milliseconds are always 000 // milliseconds are always 000
date_upload = parseJSTDate(publish_start).time date_upload = JST_FORMAT_LIST.parseJST(publish_start)!!.time
// show end date in scanlator field // show end date in scanlator field
scanlator = publish_end?.let { "~" + localDate.format(parseJSTDate(it)) } scanlator = publish_end?.let { "~" + LOCAL_FORMAT_LIST.format(JST_FORMAT_LIST.parseJST(it)!!) }
} }
fun getNextDatePrefix(): String? = when { fun getNextDatePrefix(): String? = when {
!episode_next_date.isNullOrEmpty() -> { !episode_next_date.isNullOrEmpty() -> {
val date = parseJSTDate(episode_next_date).apply { val date = JST_FORMAT_DESC.parseJST(episode_next_date)!!.apply {
time += 10 * 3600 * 1000 // 10 am JST time += 10 * 3600 * 1000 // 10 am JST
} }
"【Next: ${localDate.format(date)}" "【Next: ${LOCAL_FORMAT_DESC.format(date)}"
} }
!next_date_customize_text.isNullOrEmpty() -> "$next_date_customize_text】" !next_date_customize_text.isNullOrEmpty() -> "$next_date_customize_text】"
else -> null else -> null
} }
companion object {
// for thread-safety
private val JST_FORMAT_DESC = getJSTFormat()
private val JST_FORMAT_LIST = getJSTFormat()
private val LOCAL_FORMAT_DESC = getDateTimeInstance()
private val LOCAL_FORMAT_LIST = getDateTimeInstance()
private fun SimpleDateFormat.parseJST(date: String) = parse(date.removeSuffix("+09:00"))
private fun getJSTFormat() =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).apply {
timeZone = TimeZone.getTimeZone("GMT+09:00")
}
}
} }
@Serializable @Serializable