Implement Mangafox and Mangahere with the new source

This commit is contained in:
len 2016-05-23 14:26:50 +02:00
parent dd5692bb2d
commit 015257fe75
5 changed files with 250 additions and 13 deletions

View file

@ -8,6 +8,8 @@ import eu.kanade.tachiyomi.data.source.base.Source
import eu.kanade.tachiyomi.data.source.base.YamlOnlineSource
import eu.kanade.tachiyomi.data.source.online.english.Batoto
import eu.kanade.tachiyomi.data.source.online.english.Kissmanga
import eu.kanade.tachiyomi.data.source.online.english.Mangafox
import eu.kanade.tachiyomi.data.source.online.english.Mangahere
import org.yaml.snakeyaml.Yaml
import timber.log.Timber
import java.io.File
@ -36,6 +38,8 @@ open class SourceManager(private val context: Context) {
private fun createSource(id: Int): Source? = when (id) {
BATOTO -> Batoto(context, id)
KISSMANGA -> Kissmanga(context, id)
MANGAHERE -> Mangahere(context, id)
MANGAFOX -> Mangafox(context, id)
else -> null
}

View file

@ -202,6 +202,7 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
for ((i, element) in selectElement.select("option").withIndex()) {
pages.add(Page(i, element.attr("value")))
}
pages.getOrNull(0)?.imageUrl = imageUrlParse(document)
} else {
// For webtoons in one page
for ((i, element) in document.select("div > img").withIndex()) {

View file

@ -40,6 +40,8 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
}
}
override fun popularMangaNextPageSelector() = "li > a:contains( Next)"
override fun searchMangaRequest(page: MangasPage, query: String): Request {
if (page.page == 1) {
page.url = searchMangaInitialUrl(query)
@ -55,7 +57,7 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
return post(page.url, headers, form)
}
override fun popularMangaNextPageSelector() = "li > a:contains( Next)"
override fun searchMangaInitialUrl(query: String) = "$baseUrl/AdvanceSearch"
override fun searchMangaSelector() = popularMangaSelector()
@ -65,26 +67,20 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
override fun searchMangaNextPageSelector() = null
override fun searchMangaInitialUrl(query: String) = "$baseUrl/AdvanceSearch"
override fun mangaDetailsParse(document: Document, manga: Manga) {
val infoElement = document.select("div.barContent").first()
manga.author = infoElement.select("p:has(span:contains(Author:)) > a").first()?.text()
manga.genre = infoElement.select("p:has(span:contains(Genres:)) > *:gt(0)").text()
manga.description = infoElement.select("p:has(span:contains(Summary:)) ~ p").text()
manga.status = parseStatus(infoElement.select("p:has(span:contains(Status:))").first()?.text())
manga.status = infoElement.select("p:has(span:contains(Status:))").first()?.text().orEmpty().let { parseStatus(it)}
manga.thumbnail_url = document.select(".rightBox:eq(0) img").first()?.attr("src")
}
fun parseStatus(status: String?): Int {
if (status != null) {
when {
status.contains("Ongoing") -> return Manga.ONGOING
status.contains("Completed") -> return Manga.COMPLETED
}
}
return Manga.UNKNOWN
fun parseStatus(status: String) = when {
status.contains("Ongoing") -> Manga.ONGOING
status.contains("Completed") -> Manga.COMPLETED
else -> Manga.UNKNOWN
}
override fun chapterListSelector() = "table.listing tr:gt(1)"
@ -102,7 +98,8 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
override fun pageListRequest(chapter: Chapter) = post(baseUrl + chapter.url, headers)
override fun pageListParse(response: Response, pages: MutableList<Page>) {
val p = Pattern.compile("lstImages.push\\(\"(.+?)\"")
//language=RegExp
val p = Pattern.compile("""lstImages.push\("(.+?)"""")
val m = p.matcher(response.body().string())
var i = 0

View file

@ -0,0 +1,122 @@
package eu.kanade.tachiyomi.data.source.online.english
import android.content.Context
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.source.EN
import eu.kanade.tachiyomi.data.source.Language
import eu.kanade.tachiyomi.data.source.base.ParsedOnlineSource
import eu.kanade.tachiyomi.data.source.model.Page
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
class Mangafox(context: Context, override val id: Int) : ParsedOnlineSource(context) {
override val name = "Mangafox"
override val baseUrl = "http://mangafox.me"
override val lang: Language get() = EN
override fun popularMangaInitialUrl() = "$baseUrl/directory/"
override fun popularMangaSelector() = "div#mangalist > ul.list > li"
override fun popularMangaFromElement(element: Element, manga: Manga) {
element.select("a.title").first().let {
manga.setUrl(it.attr("href"))
manga.title = it.text()
}
}
override fun popularMangaNextPageSelector() = "a:has(span.next)"
override fun searchMangaInitialUrl(query: String) =
"$baseUrl/search.php?name_method=cw&advopts=1&order=za&sort=views&name=$query&page=1"
override fun searchMangaSelector() = "table#listing > tbody > tr:gt(0)"
override fun searchMangaFromElement(element: Element, manga: Manga) {
element.select("a.series_preview").first().let {
manga.setUrl(it.attr("href"))
manga.title = it.text()
}
}
override fun searchMangaNextPageSelector() = "a:has(span.next)"
override fun mangaDetailsParse(document: Document, manga: Manga) {
val infoElement = document.select("div#title").first()
val rowElement = infoElement.select("table > tbody > tr:eq(1)").first()
val sideInfoElement = document.select("#series_info").first()
manga.author = rowElement.select("td:eq(1)").first()?.text()
manga.artist = rowElement.select("td:eq(2)").first()?.text()
manga.genre = rowElement.select("td:eq(3)").first()?.text()
manga.description = infoElement.select("p.summary").first()?.text()
manga.status = sideInfoElement.select(".data").first()?.text().orEmpty().let { parseStatus(it) }
manga.thumbnail_url = sideInfoElement.select("div.cover > img").first()?.attr("src")
}
private fun parseStatus(status: String) = when {
status.contains("Ongoing") -> Manga.ONGOING
status.contains("Completed") -> Manga.COMPLETED
else -> Manga.UNKNOWN
}
override fun chapterListSelector() = "div#chapters li div"
override fun chapterFromElement(element: Element, chapter: Chapter) {
val urlElement = element.select("a.tips").first()
chapter.setUrl(urlElement.attr("href"))
chapter.name = urlElement.text()
chapter.date_upload = element.select("span.date").first()?.text()?.let { parseChapterDate(it) } ?: 0
}
private fun parseChapterDate(date: String): Long {
return if ("Today" in date || " ago" in date) {
Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
} else if ("Yesterday" in date) {
Calendar.getInstance().apply {
add(Calendar.DATE, -1)
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
} else {
try {
SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH).parse(date).time
} catch (e: ParseException) {
0L
}
}
}
override fun pageListParse(response: Response, pages: MutableList<Page>) {
val document = Jsoup.parse(response.body().string())
val url = response.request().url().toString().substringBeforeLast('/')
document.select("select.m").first().select("option:not([value=0])").forEach {
pages.add(Page(pages.size, "$url/${it.attr("value")}.html"))
}
pages.getOrNull(0)?.imageUrl = imageUrlParse(document)
}
// Not used, overrides parent.
override fun pageListParse(document: Document, pages: MutableList<Page>) {}
override fun imageUrlParse(document: Document) = document.getElementById("image").attr("src")
}

View file

@ -0,0 +1,113 @@
package eu.kanade.tachiyomi.data.source.online.english
import android.content.Context
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.source.EN
import eu.kanade.tachiyomi.data.source.Language
import eu.kanade.tachiyomi.data.source.base.ParsedOnlineSource
import eu.kanade.tachiyomi.data.source.model.Page
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
class Mangahere(context: Context, override val id: Int) : ParsedOnlineSource(context) {
override val name = "Mangahere"
override val baseUrl = "http://www.mangahere.co"
override val lang: Language get() = EN
override fun popularMangaInitialUrl() = "$baseUrl/directory/"
override fun popularMangaSelector() = "div.directory_list > ul > li"
override fun popularMangaFromElement(element: Element, manga: Manga) {
element.select("div.title > a").first().let {
manga.setUrl(it.attr("href"))
manga.title = it.text()
}
}
override fun popularMangaNextPageSelector() = "div.next-page > a.next"
override fun searchMangaInitialUrl(query: String) =
"$baseUrl/search.php?name=$query&page=1&sort=views&order=za"
override fun searchMangaSelector() = "div.result_search > dl"
override fun searchMangaFromElement(element: Element, manga: Manga) {
element.select("a.manga_info").first().let {
manga.setUrl(it.attr("href"))
manga.title = it.text()
}
}
override fun searchMangaNextPageSelector() = "div.next-page > a.next"
override fun mangaDetailsParse(document: Document, manga: Manga) {
val detailElement = document.select(".manga_detail_top").first()
val infoElement = detailElement.select(".detail_topText").first()
manga.author = infoElement.select("a[href^=http://www.mangahere.co/author/]").first()?.text()
manga.artist = infoElement.select("a[href^=http://www.mangahere.co/artist/]").first()?.text()
manga.genre = infoElement.select("li:eq(3)").first()?.text()?.substringAfter("Genre(s):")
manga.description = infoElement.select("#show").first()?.text()?.substringBeforeLast("Show less")
manga.status = infoElement.select("li:eq(6)").first()?.text().orEmpty().let { parseStatus(it) }
manga.thumbnail_url = detailElement.select("img.img").first()?.attr("src")
}
private fun parseStatus(status: String) = when {
status.contains("Ongoing") -> Manga.ONGOING
status.contains("Completed") -> Manga.COMPLETED
else -> Manga.UNKNOWN
}
override fun chapterListSelector() = ".detail_list > ul:not([class]) > li"
override fun chapterFromElement(element: Element, chapter: Chapter) {
val urlElement = element.select("a").first()
chapter.setUrl(urlElement.attr("href"))
chapter.name = urlElement.text()
chapter.date_upload = element.select("span.right").first()?.text()?.let { parseChapterDate(it) } ?: 0
}
private fun parseChapterDate(date: String): Long {
return if ("Today" in date) {
Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
} else if ("Yesterday" in date) {
Calendar.getInstance().apply {
add(Calendar.DATE, -1)
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
} else {
try {
SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH).parse(date).time
} catch (e: ParseException) {
0L
}
}
}
override fun pageListParse(document: Document, pages: MutableList<Page>) {
document.select("select.wid60").first().getElementsByTag("option").forEach {
pages.add(Page(pages.size, it.attr("value")))
}
pages.getOrNull(0)?.imageUrl = imageUrlParse(document)
}
override fun imageUrlParse(document: Document) = document.getElementById("image").attr("src")
}