Madara - add sources, refactor date parsing (#3553)

This commit is contained in:
Mike 2020-06-17 02:15:29 -04:00 committed by GitHub
parent 7220a19a58
commit 51f073fb0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 42 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: Madara (multiple sources)'
pkgNameSuffix = "all.madara"
extClass = '.MadaraFactory'
extVersionCode = 108
extVersionCode = 109
libVersion = '1.2'
}

View File

@ -14,7 +14,6 @@ import eu.kanade.tachiyomi.util.asJsoup
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit
import okhttp3.CacheControl
@ -398,22 +397,25 @@ abstract class Madara(
chapter.name = urlElement.text()
}
// For when source's chapter date is a graphic representing "new" instead of text
val imgDate = select("img").attr("alt")
if (imgDate.isNotBlank()) {
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
}
}
// Dates can be part of a "new" graphic or plain text
chapter.date_upload = select("img").firstOrNull()?.attr("alt")?.let { parseRelativeDate(it) }
?: parseChapterDate(select("span.chapter-release-date i").firstOrNull()?.text())
}
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 {
date.endsWith(" ago", ignoreCase = true) -> {
parseRelativeDate(date)
@ -449,42 +451,24 @@ abstract class Madara(
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:
// 21 horas ago
private fun parseRelativeDate(date: String): Long {
val trimmedDate = date.split(" ")
val number = trimmedDate[0].toIntOrNull()
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
}
}
val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0
val cal = Calendar.getInstance()
private fun SimpleDateFormat.parseOrNull(string: String): Date? {
return try {
parse(string)
} catch (e: ParseException) {
null
return when {
WordSet("jour", "día", "dia", "day").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
WordSet("heure", "hora", "hour").anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("min", "minute", "minuto").anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
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")
}
class WordSet(private vararg val words: String) { fun anyWordIn(dateString: String): Boolean = words.any { dateString.contains(it, ignoreCase = true) } }

View File

@ -137,7 +137,12 @@ class MadaraFactory : SourceFactory {
QueensManga(),
DropeScan(),
TheTopComic(),
WebNovel()
WebNovel(),
TruyenTranhAudioCom(),
TruyenTranhAudioOnline(),
MangaTurf(),
SheaManga(),
FurioScans()
// Removed by request of site owner
// EarlyManga(),
// MangaGecesi(),
@ -977,3 +982,36 @@ class DropeScan : Madara("Drope Scan", "https://dropescan.com", "pt-BR") {
class TheTopComic : Madara("TheTopComic", "https://thetopcomic.com", "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()))