Madara - add sources, refactor date parsing (#3553)
This commit is contained in:
parent
7220a19a58
commit
51f073fb0c
@ -5,7 +5,7 @@ ext {
|
|||||||
appName = 'Tachiyomi: Madara (multiple sources)'
|
appName = 'Tachiyomi: Madara (multiple sources)'
|
||||||
pkgNameSuffix = "all.madara"
|
pkgNameSuffix = "all.madara"
|
||||||
extClass = '.MadaraFactory'
|
extClass = '.MadaraFactory'
|
||||||
extVersionCode = 108
|
extVersionCode = 109
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import eu.kanade.tachiyomi.util.asJsoup
|
|||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import okhttp3.CacheControl
|
import okhttp3.CacheControl
|
||||||
@ -398,22 +397,25 @@ abstract class Madara(
|
|||||||
chapter.name = urlElement.text()
|
chapter.name = urlElement.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For when source's chapter date is a graphic representing "new" instead of text
|
// Dates can be part of a "new" graphic or plain text
|
||||||
val imgDate = select("img").attr("alt")
|
chapter.date_upload = select("img").firstOrNull()?.attr("alt")?.let { parseRelativeDate(it) }
|
||||||
if (imgDate.isNotBlank()) {
|
?: parseChapterDate(select("span.chapter-release-date i").firstOrNull()?.text())
|
||||||
chapter.date_upload = parseRelativeDate(imgDate)
|
|
||||||
} else {
|
|
||||||
// For a chapter date that's text
|
|
||||||
select("span.chapter-release-date i").first()?.let {
|
|
||||||
chapter.date_upload = parseChapterDate(it.text()) ?: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chapter
|
return chapter
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun parseChapterDate(date: String): Long? {
|
open fun parseChapterDate(date: String?): Long {
|
||||||
|
date ?: return 0
|
||||||
|
|
||||||
|
fun SimpleDateFormat.tryParse(string: String): Long {
|
||||||
|
return try {
|
||||||
|
parse(string).time
|
||||||
|
} catch (_: ParseException) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
date.endsWith(" ago", ignoreCase = true) -> {
|
date.endsWith(" ago", ignoreCase = true) -> {
|
||||||
parseRelativeDate(date)
|
parseRelativeDate(date)
|
||||||
@ -449,42 +451,24 @@ abstract class Madara(
|
|||||||
it
|
it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.let { dateFormat.parseOrNull(it.joinToString(" "))?.time }
|
.let { dateFormat.tryParse(it.joinToString(" ")) }
|
||||||
}
|
}
|
||||||
else -> dateFormat.parseOrNull(date)?.time
|
else -> dateFormat.tryParse(date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses dates in this form:
|
// Parses dates in this form:
|
||||||
// 21 horas ago
|
// 21 horas ago
|
||||||
private fun parseRelativeDate(date: String): Long {
|
private fun parseRelativeDate(date: String): Long {
|
||||||
val trimmedDate = date.split(" ")
|
val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0
|
||||||
val number = trimmedDate[0].toIntOrNull()
|
val cal = Calendar.getInstance()
|
||||||
val isRelative = trimmedDate[2] == "ago" || trimmedDate[2] == "atrás"
|
|
||||||
/**
|
|
||||||
* Size check is for Arabic language, would sometimes break if we don't check
|
|
||||||
* Take that in to consideration if adding support for parsing Arabic dates
|
|
||||||
*/
|
|
||||||
return if (trimmedDate.size == 3 && isRelative && number is Int) {
|
|
||||||
val cal = Calendar.getInstance()
|
|
||||||
// Map English and other language units to Java units
|
|
||||||
when (trimmedDate[1].removeSuffix("s")) {
|
|
||||||
"jour", "día", "dia", "day" -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
|
|
||||||
"heure", "hora", "hour" -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
|
|
||||||
"min", "minute", "minuto" -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
|
|
||||||
"segundo", "second" -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun SimpleDateFormat.parseOrNull(string: String): Date? {
|
return when {
|
||||||
return try {
|
WordSet("jour", "día", "dia", "day").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
|
||||||
parse(string)
|
WordSet("heure", "hora", "hour").anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
|
||||||
} catch (e: ParseException) {
|
WordSet("min", "minute", "minuto").anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
|
||||||
null
|
WordSet("segundo", "second").anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
|
||||||
|
else -> 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,3 +491,5 @@ abstract class Madara(
|
|||||||
|
|
||||||
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
|
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WordSet(private vararg val words: String) { fun anyWordIn(dateString: String): Boolean = words.any { dateString.contains(it, ignoreCase = true) } }
|
||||||
|
@ -137,7 +137,12 @@ class MadaraFactory : SourceFactory {
|
|||||||
QueensManga(),
|
QueensManga(),
|
||||||
DropeScan(),
|
DropeScan(),
|
||||||
TheTopComic(),
|
TheTopComic(),
|
||||||
WebNovel()
|
WebNovel(),
|
||||||
|
TruyenTranhAudioCom(),
|
||||||
|
TruyenTranhAudioOnline(),
|
||||||
|
MangaTurf(),
|
||||||
|
SheaManga(),
|
||||||
|
FurioScans()
|
||||||
// Removed by request of site owner
|
// Removed by request of site owner
|
||||||
// EarlyManga(),
|
// EarlyManga(),
|
||||||
// MangaGecesi(),
|
// MangaGecesi(),
|
||||||
@ -977,3 +982,36 @@ class DropeScan : Madara("Drope Scan", "https://dropescan.com", "pt-BR") {
|
|||||||
class TheTopComic : Madara("TheTopComic", "https://thetopcomic.com", "en")
|
class TheTopComic : Madara("TheTopComic", "https://thetopcomic.com", "en")
|
||||||
|
|
||||||
class WebNovel : Madara("WebNovel", "https://webnovel.live", "en")
|
class WebNovel : Madara("WebNovel", "https://webnovel.live", "en")
|
||||||
|
|
||||||
|
class TruyenTranhAudioCom : Madara("TruyenTranhAudio.com", "https://truyentranhaudio.com", "vi", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
|
||||||
|
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers)
|
||||||
|
override fun popularMangaSelector() = searchMangaSelector()
|
||||||
|
override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
|
||||||
|
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers)
|
||||||
|
override fun latestUpdatesSelector() = searchMangaSelector()
|
||||||
|
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
|
||||||
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
|
return document.select("div.reading-content img").map { it.attr("abs:src") }
|
||||||
|
.filterNot { it.isNullOrEmpty() }
|
||||||
|
.distinct()
|
||||||
|
.mapIndexed { i, url -> Page(i, "", url) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TruyenTranhAudioOnline : Madara("TruyenTranhAudio.online", "https://truyentranhaudio.online", "vi", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
|
||||||
|
override val formHeaders: Headers = headersBuilder()
|
||||||
|
.add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
.build()
|
||||||
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
|
return document.select("div.reading-content img").map { it.attr("abs:src") }
|
||||||
|
.filterNot { it.isNullOrEmpty() }
|
||||||
|
.distinct()
|
||||||
|
.mapIndexed { i, url -> Page(i, "", url) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MangaTurf : Madara("Manga Turf", "https://mangaturf.com", "en")
|
||||||
|
|
||||||
|
class SheaManga : Madara("Shea Manga", "https://sheamanga.my.id", "id")
|
||||||
|
|
||||||
|
class FurioScans : Madara("Furio Scans", "https://furioscans.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user