Lint fixes

This commit is contained in:
arkon 2020-04-24 23:15:45 -04:00 committed by arkon
parent 60ef2bea02
commit 5d5c6016ea
77 changed files with 644 additions and 588 deletions

View File

@ -1,26 +1,29 @@
package eu.kanade.tachiyomi.extension.all.boommanga package eu.kanade.tachiyomi.extension.all.boommanga
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.*
open class BoomManga ( open class BoomManga(
override val name: String, override val name: String,
override val baseUrl: String, override val baseUrl: String,
override val lang: String override val lang: String
) : ParsedHttpSource() { ) : ParsedHttpSource() {
//override val name = "BoomManga" // override val name = "BoomManga"
//override val baseUrl = "https://m.boommanga.com/" // override val baseUrl = "https://m.boommanga.com/"
//override val lang = "en" // override val lang = "en"
override val supportsLatest = true override val supportsLatest = true
override fun popularMangaRequest(page: Int) = GET("$baseUrl/category?sort=heat&page=$page", headers) override fun popularMangaRequest(page: Int) = GET("$baseUrl/category?sort=heat&page=$page", headers)
@ -39,10 +42,9 @@ open class BoomManga (
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun mangaDetailsRequest(manga: SManga) = GET(manga.url, headers)
override fun mangaDetailsRequest(manga: SManga) = GET( manga.url, headers)
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga) override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
override fun pageListRequest(chapter: SChapter) = GET( chapter.url, headers) override fun pageListRequest(chapter: SChapter) = GET(chapter.url, headers)
override fun popularMangaFromElement(element: Element) = mangaFromElement(element) override fun popularMangaFromElement(element: Element) = mangaFromElement(element)
override fun latestUpdatesFromElement(element: Element) = mangaFromElement(element) override fun latestUpdatesFromElement(element: Element) = mangaFromElement(element)
@ -69,7 +71,7 @@ open class BoomManga (
val chapter = SChapter.create() val chapter = SChapter.create()
chapter.url = element.select("a").attr("href") chapter.url = element.select("a").attr("href")
chapter.chapter_number = element.select("[data-num]").attr("data-num").toFloat() chapter.chapter_number = element.select("[data-num]").attr("data-num").toFloat()
val date= element.select(".date").text() val date = element.select(".date").text()
if (date.isNotBlank()) { chapter.date_upload = parseDate(date) } if (date.isNotBlank()) { chapter.date_upload = parseDate(date) }
chapter.name = nameselector(element).trim() chapter.name = nameselector(element).trim()
return chapter return chapter
@ -82,7 +84,7 @@ open class BoomManga (
} }
private fun parseDate(date: String): Long { private fun parseDate(date: String): Long {
return SimpleDateFormat("yyyy-MM-dd kk:mm:ss", Locale.US ).parse(date).time return SimpleDateFormat("yyyy-MM-dd kk:mm:ss", Locale.US).parse(date).time
} }
override fun mangaDetailsParse(document: Document): SManga { override fun mangaDetailsParse(document: Document): SManga {
@ -124,10 +126,7 @@ open class BoomManga (
return url return url
} }
override fun pageListParse(document: Document) = throw Exception("Not used") override fun pageListParse(document: Document) = throw Exception("Not used")
override fun imageUrlRequest(page: Page) = throw Exception("Not used") override fun imageUrlRequest(page: Page) = throw Exception("Not used")
override fun imageUrlParse(document: Document) = throw Exception("Not used") override fun imageUrlParse(document: Document) = throw Exception("Not used")
} }

View File

@ -6,7 +6,6 @@ import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
class BoomMangaFactory : SourceFactory { class BoomMangaFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(
BoomMangacom(), BoomMangacom(),
@ -20,7 +19,7 @@ class BoomMangaFactory : SourceFactory {
class BoomMangacom : BoomManga("BoomManga", "https://m.boommanga.com", "en") class BoomMangacom : BoomManga("BoomManga", "https://m.boommanga.com", "en")
class ManManga: BoomManga("ManManga", "https://m.manmanga.com", "en"){ class ManManga : BoomManga("ManManga", "https://m.manmanga.com", "en") {
override fun nameselector(element: Element) = element.select("a").attr("alt") override fun nameselector(element: Element) = element.select("a").attr("alt")
override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim() override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim()
override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'") override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'")
@ -33,7 +32,7 @@ class ManManga: BoomManga("ManManga", "https://m.manmanga.com", "en"){
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
} }
} }
class TwinsComics: BoomManga("TwinsComics", "https://m.twinscomics.com", "en"){ class TwinsComics : BoomManga("TwinsComics", "https://m.twinscomics.com", "en") {
override fun nameselector(element: Element) = element.select("a").attr("alt") override fun nameselector(element: Element) = element.select("a").attr("alt")
override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim() override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim()
override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'") override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'")
@ -49,7 +48,7 @@ class TwinsComics: BoomManga("TwinsComics", "https://m.twinscomics.com", "en"){
class BoomMangazh : BoomManga("BoomManga", "https://m.boommanga.com/cn", "zh") class BoomMangazh : BoomManga("BoomManga", "https://m.boommanga.com/cn", "zh")
class ManMangazh: BoomManga("ManManga", "https://m.manmanga.com/cn", "zh"){ class ManMangazh : BoomManga("ManManga", "https://m.manmanga.com/cn", "zh") {
override fun nameselector(element: Element) = element.select("a").attr("alt") override fun nameselector(element: Element) = element.select("a").attr("alt")
override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim() override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim()
override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'") override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'")
@ -58,12 +57,12 @@ class ManMangazh: BoomManga("ManManga", "https://m.manmanga.com/cn", "zh"){
}.joinToString(", ") }.joinToString(", ")
override fun statusget(document: Document) = when (document.select(".type").text().substringAfter("").trim()) { override fun statusget(document: Document) = when (document.select(".type").text().substringAfter("").trim()) {
"连载中" -> SManga.ONGOING "连载中" -> SManga.ONGOING
//"Completed" -> SManga.COMPLETED // "Completed" -> SManga.COMPLETED
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
} }
} }
class TwinsComicszh: BoomManga("TwinsComics", "https://m.twinscomics.com/cn", "zh"){ class TwinsComicszh : BoomManga("TwinsComics", "https://m.twinscomics.com/cn", "zh") {
override fun nameselector(element: Element) = element.select("a").attr("alt") override fun nameselector(element: Element) = element.select("a").attr("alt")
override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim() override fun authorget(document: Document) = document.select(".author").text().substringAfter("").trim()
override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'") override fun thumbnailget(document: Document) = document.select(".bg-box .bg").attr("style").substringAfter("'").substringBefore("'")
@ -72,7 +71,7 @@ class TwinsComicszh: BoomManga("TwinsComics", "https://m.twinscomics.com/cn", "z
}.joinToString(", ") }.joinToString(", ")
override fun statusget(document: Document) = when (document.select(".type").text().substringAfter("").trim()) { override fun statusget(document: Document) = when (document.select(".type").text().substringAfter("").trim()) {
"连载中" -> SManga.ONGOING "连载中" -> SManga.ONGOING
//"Completed" -> SManga.COMPLETED // "Completed" -> SManga.COMPLETED
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
} }
} }

View File

@ -20,17 +20,17 @@ import org.jsoup.nodes.Element
abstract class Ciayo(override val lang: String) : HttpSource() { abstract class Ciayo(override val lang: String) : HttpSource() {
//Info // Info
override val name: String = "Ciayo Comics" override val name: String = "Ciayo Comics"
override val baseUrl: String = "https://www.ciayo.com" override val baseUrl: String = "https://www.ciayo.com"
private val apiUrl = "https://vueserion.ciayo.com/3.3/comics" private val apiUrl = "https://vueserion.ciayo.com/3.3/comics"
override val supportsLatest: Boolean = true override val supportsLatest: Boolean = true
//Page Helpers // Page Helpers
private var next: String? = "" private var next: String? = ""
private var previous: String? = "" private var previous: String? = ""
//Popular // Popular
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val body = response.body()!!.string() val body = response.body()!!.string()
val json = JsonParser().parse(body)["c"] val json = JsonParser().parse(body)["c"]
@ -67,7 +67,7 @@ abstract class Ciayo(override val lang: String) : HttpSource() {
thumbnail_url = json["image"]["cover"].string thumbnail_url = json["image"]["cover"].string
} }
//Latest // Latest
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val body = response.body()!!.string() val body = response.body()!!.string()
@ -101,7 +101,7 @@ abstract class Ciayo(override val lang: String) : HttpSource() {
private fun latestUpdatesFromJson(json: JsonElement): SManga = popularMangaFromJson(json) private fun latestUpdatesFromJson(json: JsonElement): SManga = popularMangaFromJson(json)
//Search // Search
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup() val document = response.asJsoup()
@ -115,7 +115,6 @@ abstract class Ciayo(override val lang: String) : HttpSource() {
} != null } != null
return MangasPage(mangas, hasNextPage) return MangasPage(mangas, hasNextPage)
} }
private fun searchMangaSelector() = "div.ais-Hits li.ais-Hits-item" private fun searchMangaSelector() = "div.ais-Hits li.ais-Hits-item"
@ -126,14 +125,13 @@ abstract class Ciayo(override val lang: String) : HttpSource() {
title = this.text().trim() title = this.text().trim()
url = this.attr("href") url = this.attr("href")
} }
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/$lang/search?query=$query&page=$page") return GET("$baseUrl/$lang/search?query=$query&page=$page")
} }
//Details // Details
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup() val document = response.asJsoup()
@ -150,7 +148,7 @@ abstract class Ciayo(override val lang: String) : HttpSource() {
} }
} }
//Chapters // Chapters
override fun chapterListRequest(manga: SManga): Request { override fun chapterListRequest(manga: SManga): Request {
val slug = manga.url.substringAfterLast("/") val slug = manga.url.substringAfterLast("/")
@ -169,19 +167,16 @@ abstract class Ciayo(override val lang: String) : HttpSource() {
date_upload = it["release_date"].long * 1000 date_upload = it["release_date"].long * 1000
} }
} }
} }
//Pages // Pages
override fun pageListParse(response: Response): List<Page> = mutableListOf<Page>().apply { override fun pageListParse(response: Response): List<Page> = mutableListOf<Page>().apply {
val document = response.asJsoup() val document = response.asJsoup()
document.select("div.chapterViewer img").forEach { document.select("div.chapterViewer img").forEach {
add(Page(size, "", it.attr("abs:src"))) add(Page(size, "", it.attr("abs:src")))
} }
} }
override fun imageUrlParse(response: Response): String = throw Exception("ImgParse Not Used") override fun imageUrlParse(response: Response): String = throw Exception("ImgParse Not Used")
} }

View File

@ -13,5 +13,3 @@ class CiayoFactory : SourceFactory {
class CiayoID : Ciayo("id") class CiayoID : Ciayo("id")
class CiayoEN : Ciayo("en") class CiayoEN : Ciayo("en")

View File

@ -9,12 +9,12 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import java.text.SimpleDateFormat
import okhttp3.Headers import okhttp3.Headers
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.text.SimpleDateFormat
abstract class ComiCake( abstract class ComiCake(
override val name: String, override val name: String,

View File

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.net.URLEncoder
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.CookieJar import okhttp3.CookieJar
import okhttp3.Headers import okhttp3.Headers
@ -18,7 +19,6 @@ import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
import java.net.URLEncoder
open class EHentai(override val lang: String, private val ehLang: String) : HttpSource() { open class EHentai(override val lang: String, private val ehLang: String) : HttpSource() {
@ -32,12 +32,12 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
val doc = response.asJsoup() val doc = response.asJsoup()
val parsedMangas = doc.select("table.itg td.glname").map { val parsedMangas = doc.select("table.itg td.glname").map {
SManga.create().apply { SManga.create().apply {
//Get title // Get title
it.select("a")?.first()?.apply { it.select("a")?.first()?.apply {
title = this.select(".glink").text() title = this.select(".glink").text()
url = ExGalleryMetadata.normalizeUrl(attr("href")) url = ExGalleryMetadata.normalizeUrl(attr("href"))
} }
//Get image // Get image
it.parent().select(".glthumb img")?.first().apply { it.parent().select(".glthumb img")?.first().apply {
thumbnail_url = this?.attr("data-src")?.nullIfBlank() thumbnail_url = this?.attr("data-src")?.nullIfBlank()
?: this?.attr("src") ?: this?.attr("src")
@ -45,7 +45,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
} }
} }
//Add to page if required // Add to page if required
val hasNextPage = doc.select("a[onclick=return false]").last()?.text() == ">" val hasNextPage = doc.select("a[onclick=return false]").last()?.text() == ">"
return MangasPage(parsedMangas, hasNextPage) return MangasPage(parsedMangas, hasNextPage)
@ -66,8 +66,11 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
/** /**
* Recursively fetch chapter pages * Recursively fetch chapter pages
*/ */
private fun fetchChapterPage(chapter: SChapter, np: String, private fun fetchChapterPage(
pastUrls: List<String> = emptyList()): Observable<List<String>> { chapter: SChapter,
np: String,
pastUrls: List<String> = emptyList()
): Observable<List<String>> {
val urls = ArrayList(pastUrls) val urls = ArrayList(pastUrls)
return chapterPageCall(np).flatMap { return chapterPageCall(np).flatMap {
val jsoup = it.asJsoup() val jsoup = it.asJsoup()
@ -92,9 +95,9 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
} }
override fun popularMangaRequest(page: Int) = latestUpdatesRequest(page) override fun popularMangaRequest(page: Int) = latestUpdatesRequest(page)
//This source supports finding popular manga but will not respect language filters on the popular manga page! // This source supports finding popular manga but will not respect language filters on the popular manga page!
//We currently display the latest updates instead until this is fixed // We currently display the latest updates instead until this is fixed
//override fun popularMangaRequest(page: Int) = exGet("$baseUrl/toplist.php?tl=15", page) // override fun popularMangaRequest(page: Int) = exGet("$baseUrl/toplist.php?tl=15", page)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val uri = Uri.parse("$baseUrl$QUERY_PREFIX").buildUpon() val uri = Uri.parse("$baseUrl$QUERY_PREFIX").buildUpon()
@ -138,7 +141,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
altTitle = select("#gj").text().nullIfBlank()?.trim() altTitle = select("#gj").text().nullIfBlank()?.trim()
//Thumbnail is set as background of element in style attribute // Thumbnail is set as background of element in style attribute
thumbnailUrl = select("#gd1 div").attr("style").nullIfBlank()?.let { thumbnailUrl = select("#gd1 div").attr("style").nullIfBlank()?.let {
it.substring(it.indexOf('(') + 1 until it.lastIndexOf(')')) it.substring(it.indexOf('(') + 1 until it.lastIndexOf(')'))
} }
@ -146,7 +149,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
uploader = select("#gdn").text().nullIfBlank()?.trim() uploader = select("#gdn").text().nullIfBlank()?.trim()
//Parse the table // Parse the table
select("#gdd tr").forEach { select("#gdd tr").forEach {
it.select(".gdt1") it.select(".gdt1")
.text() .text()
@ -176,7 +179,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
} }
} }
//Parse ratings // Parse ratings
ignore { ignore {
averageRating = select("#rating_label") averageRating = select("#rating_label")
.text() .text()
@ -191,7 +194,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
?.toInt() ?.toInt()
} }
//Parse tags // Parse tags
tags.clear() tags.clear()
select("#taglist tr").forEach { select("#taglist tr").forEach {
val namespace = it.select(".tc").text().removeSuffix(":") val namespace = it.select(".tc").text().removeSuffix(":")
@ -202,7 +205,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
tags[namespace] = currentTags tags[namespace] = currentTags
} }
//Copy metadata to manga // Copy metadata to manga
SManga.create().apply { SManga.create().apply {
copyTo(this) copyTo(this)
} }
@ -238,8 +241,8 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
private fun realImageUrlParse(response: Response, page: Page) = with(response.asJsoup()) { private fun realImageUrlParse(response: Response, page: Page) = with(response.asJsoup()) {
val currentImage = getElementById("img").attr("src") val currentImage = getElementById("img").attr("src")
//TODO We cannot currently do this as page.url is immutable // TODO We cannot currently do this as page.url is immutable
//Each press of the retry button will choose another server // Each press of the retry button will choose another server
/*select("#loadfail").attr("onclick").nullIfBlank()?.let { /*select("#loadfail").attr("onclick").nullIfBlank()?.let {
page.url = addParam(page.url, "nl", it.substring(it.indexOf('\'') + 1 until it.lastIndexOf('\''))) page.url = addParam(page.url, "nl", it.substring(it.indexOf('\'') + 1 until it.lastIndexOf('\'')))
}*/ }*/
@ -251,13 +254,13 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
private val cookiesHeader by lazy { private val cookiesHeader by lazy {
val cookies = mutableMapOf<String, String>() val cookies = mutableMapOf<String, String>()
//Setup settings // Setup settings
val settings = mutableListOf<String>() val settings = mutableListOf<String>()
//Do not show popular right now pane as we can't parse it // Do not show popular right now pane as we can't parse it
settings += "prn_n" settings += "prn_n"
//Exclude every other language except the one we have selected // Exclude every other language except the one we have selected
settings += "xl_" + languageMappings.filter { it.first != ehLang } settings += "xl_" + languageMappings.filter { it.first != ehLang }
.flatMap { it.second } .flatMap { it.second }
.joinToString("x") .joinToString("x")
@ -270,7 +273,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
buildCookies(cookies) buildCookies(cookies)
} }
//Headers // Headers
override fun headersBuilder() = super.headersBuilder().add("Cookie", cookiesHeader)!! override fun headersBuilder() = super.headersBuilder().add("Cookie", cookiesHeader)!!
private fun buildSettings(settings: List<String?>) = settings.filterNotNull().joinToString(separator = "-") private fun buildSettings(settings: List<String?>) = settings.filterNotNull().joinToString(separator = "-")
@ -297,7 +300,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
chain.proceed(newReq) chain.proceed(newReq)
}.build()!! }.build()!!
//Filters // Filters
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(
Watched(), Watched(),
GenreGroup(), GenreGroup(),
@ -306,7 +309,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
class Watched : Filter.CheckBox("Watched List"), UriFilter { class Watched : Filter.CheckBox("Watched List"), UriFilter {
override fun addToUri(builder: Uri.Builder) { override fun addToUri(builder: Uri.Builder) {
if(state) if (state)
builder.appendPath("watched") builder.appendPath("watched")
} }
} }
@ -349,7 +352,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
} }
} }
//Explicit type arg for listOf() to workaround this: KT-16570 // Explicit type arg for listOf() to workaround this: KT-16570
class AdvancedGroup : UriGroup<Filter<*>>("Advanced Options", listOf( class AdvancedGroup : UriGroup<Filter<*>>("Advanced Options", listOf(
AdvancedOption("Search Gallery Name", "f_sname", true), AdvancedOption("Search Gallery Name", "f_sname", true),
AdvancedOption("Search Gallery Tags", "f_stags", true), AdvancedOption("Search Gallery Tags", "f_stags", true),
@ -362,7 +365,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Http
RatingOption() RatingOption()
)) ))
//map languages to their internal ids // map languages to their internal ids
private val languageMappings = listOf( private val languageMappings = listOf(
Pair("japanese", listOf("0", "1024", "2048")), Pair("japanese", listOf("0", "1024", "2048")),
Pair("english", listOf("1", "1025", "2049")), Pair("english", listOf("1", "1025", "2049")),

View File

@ -18,7 +18,7 @@ class ExGalleryMetadata {
var datePosted: Long? = null var datePosted: Long? = null
var parent: String? = null var parent: String? = null
var visible: String? = null //Not a boolean var visible: String? = null // Not a boolean
var language: String? = null var language: String? = null
var translated: Boolean? = null var translated: Boolean? = null
var size: Long? = null var size: Long? = null
@ -33,7 +33,7 @@ class ExGalleryMetadata {
companion object { companion object {
private fun splitGalleryUrl(url: String) = url.let { private fun splitGalleryUrl(url: String) = url.let {
//Only parse URL if is full URL // Only parse URL if is full URL
val pathSegments = if (it.startsWith("http")) val pathSegments = if (it.startsWith("http"))
Uri.parse(it).pathSegments Uri.parse(it).pathSegments
else else

View File

@ -22,19 +22,19 @@ fun ExGalleryMetadata.copyTo(manga: SManga) {
(title ?: altTitle)?.let { manga.title = it } (title ?: altTitle)?.let { manga.title = it }
//Set artist (if we can find one) // Set artist (if we can find one)
tags[EH_ARTIST_NAMESPACE]?.let { tags[EH_ARTIST_NAMESPACE]?.let {
if (it.isNotEmpty()) manga.artist = it.joinToString(transform = Tag::name) if (it.isNotEmpty()) manga.artist = it.joinToString(transform = Tag::name)
} }
//Set author (if we can find one) // Set author (if we can find one)
tags[EH_AUTHOR_NAMESPACE]?.let { tags[EH_AUTHOR_NAMESPACE]?.let {
if (it.isNotEmpty()) manga.author = it.joinToString(transform = Tag::name) if (it.isNotEmpty()) manga.author = it.joinToString(transform = Tag::name)
} }
//Set genre // Set genre
genre?.let { manga.genre = it } genre?.let { manga.genre = it }
//Try to automatically identify if it is ongoing, we try not to be too lenient here to avoid making mistakes // Try to automatically identify if it is ongoing, we try not to be too lenient here to avoid making mistakes
//We default to completed // We default to completed
manga.status = SManga.COMPLETED manga.status = SManga.COMPLETED
title?.let { t -> title?.let { t ->
if (ONGOING_SUFFIX.any { if (ONGOING_SUFFIX.any {
@ -42,7 +42,7 @@ fun ExGalleryMetadata.copyTo(manga: SManga) {
}) manga.status = SManga.ONGOING }) manga.status = SManga.ONGOING
} }
//Build a nice looking description out of what we know // Build a nice looking description out of what we know
val titleDesc = StringBuilder() val titleDesc = StringBuilder()
title?.let { titleDesc += "Title: $it\n" } title?.let { titleDesc += "Title: $it\n" }
altTitle?.let { titleDesc += "Alternate Title: $it\n" } altTitle?.let { titleDesc += "Alternate Title: $it\n" }
@ -73,7 +73,7 @@ fun ExGalleryMetadata.copyTo(manga: SManga) {
} }
private fun buildTagsDescription(metadata: ExGalleryMetadata) = StringBuilder("Tags:\n").apply { private fun buildTagsDescription(metadata: ExGalleryMetadata) = StringBuilder("Tags:\n").apply {
//BiConsumer only available in Java 8, we have to use destructuring here // BiConsumer only available in Java 8, we have to use destructuring here
metadata.tags.forEach { (namespace, tags) -> metadata.tags.forEach { (namespace, tags) ->
if (tags.isNotEmpty()) { if (tags.isNotEmpty()) {
val joinedTags = tags.joinToString(separator = " ", transform = { "<${it.name}>" }) val joinedTags = tags.joinToString(separator = " ", transform = { "<${it.name}>" })

View File

@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.util.Calendar
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -16,7 +17,6 @@ import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.Calendar
/** /**
* For sites based on the Flat-Manga CMS * For sites based on the Flat-Manga CMS

View File

@ -11,16 +11,16 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.net.URLEncoder
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.Headers
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.net.URLEncoder
class FMReaderFactory : SourceFactory { class FMReaderFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(
@ -72,8 +72,8 @@ class ReadComicOnlineOrg : FMReader("ReadComicOnline.org", "https://readcomiconl
.add("dqh_firewall", URLEncoder.encode(request.url().toString().substringAfter(baseUrl), "utf-8")) .add("dqh_firewall", URLEncoder.encode(request.url().toString().substringAfter(baseUrl), "utf-8"))
.build() .build()
val cookie = response.headers("set-cookie")[0].split(" ") val cookie = response.headers("set-cookie")[0].split(" ")
.filter {it.contains("__cfduid") || it.contains("PHPSESSID") } .filter { it.contains("__cfduid") || it.contains("PHPSESSID") }
.joinToString("; ") {it.substringBefore(";")} .joinToString("; ") { it.substringBefore(";") }
headers.newBuilder().add("Cookie", cookie).build() headers.newBuilder().add("Cookie", cookie).build()
client.newCall(POST(request.url().toString(), headers, body)).execute() client.newCall(POST(request.url().toString(), headers, body)).execute()
} else { } else {

View File

@ -10,17 +10,17 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.FormBody
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
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.Date
import java.util.HashSet import java.util.HashSet
import java.util.Locale import java.util.Locale
import okhttp3.FormBody
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
abstract class FoolSlide( abstract class FoolSlide(
override val name: String, override val name: String,
@ -115,8 +115,8 @@ abstract class FoolSlide(
// if there's no image on the details page, get the first page of the first chapter // if there's no image on the details page, get the first page of the first chapter
fun getDetailsThumbnail(document: Document, urlSelector: String = chapterUrlSelector): String? { fun getDetailsThumbnail(document: Document, urlSelector: String = chapterUrlSelector): String? {
return document.select("div.thumbnail img, table.thumb img").firstOrNull()?.attr("abs:src") ?: return document.select("div.thumbnail img, table.thumb img").firstOrNull()?.attr("abs:src")
document.select(chapterListSelector()).last().select(urlSelector).attr("abs:href") ?: document.select(chapterListSelector()).last().select(urlSelector).attr("abs:href")
.let { url -> client.newCall(allowAdult(GET(url, headers))).execute() } .let { url -> client.newCall(allowAdult(GET(url, headers))).execute() }
.let { response -> pageListParse(response).first().imageUrl } .let { response -> pageListParse(response).first().imageUrl }
} }
@ -167,11 +167,11 @@ abstract class FoolSlide(
if (lcDate.endsWith(" ago")) if (lcDate.endsWith(" ago"))
parseRelativeDate(lcDate)?.let { return it } parseRelativeDate(lcDate)?.let { return it }
//Handle 'yesterday' and 'today', using midnight // Handle 'yesterday' and 'today', using midnight
var relativeDate: Calendar? = null var relativeDate: Calendar? = null
if (lcDate.startsWith("yesterday")) { if (lcDate.startsWith("yesterday")) {
relativeDate = Calendar.getInstance() relativeDate = Calendar.getInstance()
relativeDate.add(Calendar.DAY_OF_MONTH, -1) //yesterday relativeDate.add(Calendar.DAY_OF_MONTH, -1) // yesterday
relativeDate.set(Calendar.HOUR_OF_DAY, 0) relativeDate.set(Calendar.HOUR_OF_DAY, 0)
relativeDate.set(Calendar.MINUTE, 0) relativeDate.set(Calendar.MINUTE, 0)
relativeDate.set(Calendar.SECOND, 0) relativeDate.set(Calendar.SECOND, 0)
@ -184,7 +184,7 @@ abstract class FoolSlide(
relativeDate.set(Calendar.MILLISECOND, 0) relativeDate.set(Calendar.MILLISECOND, 0)
} else if (lcDate.startsWith("tomorrow")) { } else if (lcDate.startsWith("tomorrow")) {
relativeDate = Calendar.getInstance() relativeDate = Calendar.getInstance()
relativeDate.add(Calendar.DAY_OF_MONTH, +1) //tomorrow relativeDate.add(Calendar.DAY_OF_MONTH, +1) // tomorrow
relativeDate.set(Calendar.HOUR_OF_DAY, 0) relativeDate.set(Calendar.HOUR_OF_DAY, 0)
relativeDate.set(Calendar.MINUTE, 0) relativeDate.set(Calendar.MINUTE, 0)
relativeDate.set(Calendar.SECOND, 0) relativeDate.set(Calendar.SECOND, 0)

View File

@ -8,12 +8,12 @@ import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.net.URLEncoder
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
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.net.URLEncoder
class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga") { class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga") {
// We have custom latest updates logic so do not dedupe latest updates // We have custom latest updates logic so do not dedupe latest updates
@ -121,8 +121,8 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga
if (!response.isSuccessful) { if (!response.isSuccessful) {
response.close() response.close()
// Better error message for invalid artist // Better error message for invalid artist
if (response.code() == 404 if (response.code() == 404 &&
&& !filters.findInstance<ArtistFilter>()?.state.isNullOrBlank()) !filters.findInstance<ArtistFilter>()?.state.isNullOrBlank())
error("Invalid artist!") error("Invalid artist!")
else throw Exception("HTTP error ${response.code()}") else throw Exception("HTTP error ${response.code()}")
} }

View File

@ -8,15 +8,15 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.jsoup.select.Elements import org.jsoup.select.Elements
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
abstract class Genkan( abstract class Genkan(
override val name: String, override val name: String,
@ -169,7 +169,7 @@ abstract class Genkan(
return pages return pages
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun imageRequest(page: Page): Request { override fun imageRequest(page: Page): Request {
return if (page.imageUrl!!.startsWith("http")) GET(page.imageUrl!!, headers) else GET(baseUrl + page.imageUrl!!, headers) return if (page.imageUrl!!.startsWith("http")) GET(page.imageUrl!!, headers) else GET(baseUrl + page.imageUrl!!, headers)
@ -239,5 +239,4 @@ abstract class GenkanOriginal(
override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
} }

View File

@ -35,6 +35,6 @@ class TheNonamesScans : Genkan("The Nonames Scans", "https://the-nonames.com", "
class HatigarmScans : GenkanOriginal("Hatigarm Scans", "https://hatigarmscanz.net", "en") { class HatigarmScans : GenkanOriginal("Hatigarm Scans", "https://hatigarmscanz.net", "en") {
override val versionId = 2 override val versionId = 2
} }
class EdelgardeScans : Genkan("Edelgarde Scans", "https://edelgardescans.com", "en") class EdelgardeScans : Genkan("Edelgarde Scans", "https://edelgardescans.com", "en")
class SecretScans : GenkanOriginal("SecretScans", "https://secretscans.co", "en") class SecretScans : GenkanOriginal("SecretScans", "https://secretscans.co", "en")
class MethodScans : Genkan("Method Scans", "https://methodscans.com", "en") class MethodScans : Genkan("Method Scans", "https://methodscans.com", "en")

View File

@ -22,6 +22,9 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
@ -33,8 +36,6 @@ import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
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.*
open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
override fun popularMangaRequest(page: Int): Request = override fun popularMangaRequest(page: Int): Request =
@ -151,8 +152,8 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
private fun SeriesDto.toSManga(): SManga = private fun SeriesDto.toSManga(): SManga =
SManga.create().apply { SManga.create().apply {
title = metadata.title title = metadata.title
url = "/api/v1/series/${id}" url = "/api/v1/series/$id"
thumbnail_url = "$baseUrl/api/v1/series/${id}/thumbnail" thumbnail_url = "$baseUrl/api/v1/series/$id/thumbnail"
status = when (metadata.status) { status = when (metadata.status) {
"ONGOING" -> SManga.ONGOING "ONGOING" -> SManga.ONGOING
"ENDED" -> SManga.COMPLETED "ENDED" -> SManga.COMPLETED
@ -239,8 +240,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
try { try {
val res = preferences.edit().putString(title, newValue as String).commit() val res = preferences.edit().putString(title, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting." Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
, Toast.LENGTH_LONG).show()
res res
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
@ -267,8 +267,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
try { try {
val res = preferences.edit().putString(title, newValue as String).commit() val res = preferences.edit().putString(title, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting." Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
, Toast.LENGTH_LONG).show()
res res
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
@ -295,7 +294,6 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
emptyList() emptyList()
} }
}, {}) }, {})
} }
companion object { companion object {

View File

@ -11,5 +11,4 @@ class KomgaFactory : SourceFactory {
Komga("2"), Komga("2"),
Komga("3") Komga("3")
) )
} }

View File

@ -11,7 +11,11 @@ import eu.kanade.tachiyomi.extension.all.lanraragi.model.ArchivePage
import eu.kanade.tachiyomi.extension.all.lanraragi.model.ArchiveSearchResult import eu.kanade.tachiyomi.extension.all.lanraragi.model.ArchiveSearchResult
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response

View File

@ -11,22 +11,22 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.CacheControl
import okhttp3.FormBody
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.RequestBody
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
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.Date
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.CacheControl
import okhttp3.FormBody
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
abstract class Madara( abstract class Madara(
override val name: String, override val name: String,
@ -178,8 +178,8 @@ abstract class Madara(
genreInclude.add(it.id) genreInclude.add(it.id)
} }
} }
if(genreInclude.isNotEmpty()){ if (genreInclude.isNotEmpty()) {
genreInclude.forEach{ genre -> genreInclude.forEach { genre ->
url.addQueryParameter("genre[]", genre) url.addQueryParameter("genre[]", genre)
} }
} }
@ -207,64 +207,64 @@ abstract class Madara(
open fun getGenreList() = listOf( open fun getGenreList() = listOf(
Genre("Adventure", "Adventure"), Genre("Adventure", "Adventure"),
Genre( "Action", "action"), Genre("Action", "action"),
Genre( "Adventure", "adventure"), Genre("Adventure", "adventure"),
Genre( "Cars", "cars"), Genre("Cars", "cars"),
Genre( "4-Koma", "4-koma"), Genre("4-Koma", "4-koma"),
Genre( "Comedy", "comedy"), Genre("Comedy", "comedy"),
Genre( "Completed", "completed"), Genre("Completed", "completed"),
Genre( "Cooking", "cooking"), Genre("Cooking", "cooking"),
Genre( "Dementia", "dementia"), Genre("Dementia", "dementia"),
Genre( "Demons", "demons"), Genre("Demons", "demons"),
Genre( "Doujinshi", "doujinshi"), Genre("Doujinshi", "doujinshi"),
Genre( "Drama", "drama"), Genre("Drama", "drama"),
Genre( "Ecchi", "ecchi"), Genre("Ecchi", "ecchi"),
Genre( "Fantasy", "fantasy"), Genre("Fantasy", "fantasy"),
Genre( "Game", "game"), Genre("Game", "game"),
Genre( "Gender Bender", "gender-bender"), Genre("Gender Bender", "gender-bender"),
Genre( "Harem", "harem"), Genre("Harem", "harem"),
Genre( "Historical", "historical"), Genre("Historical", "historical"),
Genre( "Horror", "horror"), Genre("Horror", "horror"),
Genre( "Isekai", "isekai"), Genre("Isekai", "isekai"),
Genre( "Josei", "josei"), Genre("Josei", "josei"),
Genre( "Kids", "kids"), Genre("Kids", "kids"),
Genre( "Magic", "magic"), Genre("Magic", "magic"),
Genre( "Manga", "manga"), Genre("Manga", "manga"),
Genre( "Manhua", "manhua"), Genre("Manhua", "manhua"),
Genre( "Manhwa", "manhwa"), Genre("Manhwa", "manhwa"),
Genre( "Martial Arts", "martial-arts"), Genre("Martial Arts", "martial-arts"),
Genre( "Mature", "mature"), Genre("Mature", "mature"),
Genre( "Mecha", "mecha"), Genre("Mecha", "mecha"),
Genre( "Military", "military"), Genre("Military", "military"),
Genre( "Music", "music"), Genre("Music", "music"),
Genre( "Mystery", "mystery"), Genre("Mystery", "mystery"),
Genre( "Old Comic", "old-comic"), Genre("Old Comic", "old-comic"),
Genre( "One Shot", "one-shot"), Genre("One Shot", "one-shot"),
Genre( "Oneshot", "oneshot"), Genre("Oneshot", "oneshot"),
Genre( "Parodi", "parodi"), Genre("Parodi", "parodi"),
Genre( "Parody", "parody"), Genre("Parody", "parody"),
Genre( "Police", "police"), Genre("Police", "police"),
Genre( "Psychological", "psychological"), Genre("Psychological", "psychological"),
Genre( "Romance", "romance"), Genre("Romance", "romance"),
Genre( "Samurai", "samurai"), Genre("Samurai", "samurai"),
Genre( "School", "school"), Genre("School", "school"),
Genre( "School Life", "school-life"), Genre("School Life", "school-life"),
Genre( "Sci-Fi", "sci-fi"), Genre("Sci-Fi", "sci-fi"),
Genre( "Seinen", "seinen"), Genre("Seinen", "seinen"),
Genre( "Shoujo", "shoujo"), Genre("Shoujo", "shoujo"),
Genre( "Shoujo Ai", "shoujo-ai"), Genre("Shoujo Ai", "shoujo-ai"),
Genre( "Shounen", "shounen"), Genre("Shounen", "shounen"),
Genre( "Shounen ai", "shounen-ai"), Genre("Shounen ai", "shounen-ai"),
Genre( "Slice of Life", "slice-of-life"), Genre("Slice of Life", "slice-of-life"),
Genre( "Sports", "sports"), Genre("Sports", "sports"),
Genre( "Super Power", "super-power"), Genre("Super Power", "super-power"),
Genre( "Supernatural", "supernatural"), Genre("Supernatural", "supernatural"),
Genre( "Thriller", "thriller"), Genre("Thriller", "thriller"),
Genre( "Tragedy", "tragedy"), Genre("Tragedy", "tragedy"),
Genre( "Vampire", "vampire"), Genre("Vampire", "vampire"),
Genre( "Webtoons", "webtoons"), Genre("Webtoons", "webtoons"),
Genre( "Yaoi", "yaoi"), Genre("Yaoi", "yaoi"),
Genre( "Yuri", "yuri") Genre("Yuri", "yuri")
) )
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(
@ -422,10 +422,10 @@ abstract class Madara(
date.endsWith(" ago", ignoreCase = true) -> { date.endsWith(" ago", ignoreCase = true) -> {
parseRelativeDate(date) parseRelativeDate(date)
} }
//Handle 'yesterday' and 'today', using midnight // Handle 'yesterday' and 'today', using midnight
date.startsWith("year", ignoreCase = true) -> { date.startsWith("year", ignoreCase = true) -> {
Calendar.getInstance().apply { Calendar.getInstance().apply {
add(Calendar.DAY_OF_MONTH, -1) //yesterday add(Calendar.DAY_OF_MONTH, -1) // yesterday
set(Calendar.HOUR_OF_DAY, 0) set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0) set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0) set(Calendar.SECOND, 0)

View File

@ -10,6 +10,8 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -17,8 +19,6 @@ import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class MadaraFactory : SourceFactory { class MadaraFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(
@ -31,8 +31,8 @@ class MadaraFactory : SourceFactory {
ChibiManga(), ChibiManga(),
DisasterScans(), DisasterScans(),
DoujinHentai(), DoujinHentai(),
//Removed by request of site owner // Removed by request of site owner
//EarlyManga(), // EarlyManga(),
FirstKissManga(), FirstKissManga(),
GetManhwa(), GetManhwa(),
GoldenManga(), GoldenManga(),
@ -351,7 +351,6 @@ class DoujinHentai : Madara("DoujinHentai", "https://doujinhentai.net", "es", Si
} else { } else {
super.searchMangaFromElement(element) // query search results super.searchMangaFromElement(element) // query search results
} }
} }
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
@ -441,17 +440,16 @@ class TeabeerComics : Madara("Teabeer Comics", "https://teabeercomics.com", "en"
class KingzManga : Madara("KingzManga", "https://kingzmanga.com", "ar") class KingzManga : Madara("KingzManga", "https://kingzmanga.com", "ar")
class YaoiToshokan : Madara("Yaoi Toshokan", "https://www.yaoitoshokan.com.br", "pt-BR") { class YaoiToshokan : Madara("Yaoi Toshokan", "https://www.yaoitoshokan.com.br", "pt-BR") {
override val popularMangaUrlSelector = "div.post-title a:not([target])" //Page has custom link to scan website override val popularMangaUrlSelector = "div.post-title a:not([target])" // Page has custom link to scan website
override fun chapterListParse(response: Response): List<SChapter> { //Chapters are listed old to new override fun chapterListParse(response: Response): List<SChapter> { // Chapters are listed old to new
return super.chapterListParse(response).reversed() return super.chapterListParse(response).reversed()
} }
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
return document.select(pageListParseSelector).mapIndexed { index, element -> return document.select(pageListParseSelector).mapIndexed { index, element ->
Page(index, "", element.select("img").attr("data-src").trim()) //had to add trim because of white space in source Page(index, "", element.select("img").attr("data-src").trim()) // had to add trim because of white space in source
} }
} }
} }
class GoldenManga : Madara("موقع لترجمة المانجا", "https://golden-manga.ml", "ar", SimpleDateFormat("yyyy-MM-dd", Locale.US)) class GoldenManga : Madara("موقع لترجمة المانجا", "https://golden-manga.ml", "ar", SimpleDateFormat("yyyy-MM-dd", Locale.US))
@ -484,16 +482,16 @@ class NijiTranslations : Madara("Niji Translations", "https://niji-translations.
class IchirinNoHanaYuri : Madara("Ichirin No Hana Yuri", "https://ichirinnohanayuri.com.br", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale("pt"))) class IchirinNoHanaYuri : Madara("Ichirin No Hana Yuri", "https://ichirinnohanayuri.com.br", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale("pt")))
class LilyManga: Madara("Lily Manga","https://lilymanga.com","en",SimpleDateFormat("yyyy-MM-dd", Locale.US)) class LilyManga : Madara("Lily Manga", "https://lilymanga.com", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))
class MangaBob: Madara("MangaBob","https://mangabob.com","en") class MangaBob : Madara("MangaBob", "https://mangabob.com", "en")
class ThreeSixtyFiveManga: Madara("365Manga","https://365manga.com","en") { class ThreeSixtyFiveManga : Madara("365Manga", "https://365manga.com", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers) override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers) override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
} }
class DisasterScans: Madara("Disaster Scans","https://disasterscans.com","en") { class DisasterScans : Madara("Disaster Scans", "https://disasterscans.com", "en") {
override val popularMangaUrlSelector = "div.post-title a:last-child" override val popularMangaUrlSelector = "div.post-title a:last-child"
override fun mangaDetailsParse(document: Document): SManga { override fun mangaDetailsParse(document: Document): SManga {
@ -509,15 +507,15 @@ class DisasterScans: Madara("Disaster Scans","https://disasterscans.com","en") {
} }
} }
class MangaKiss: Madara("MangaKiss", "https://mangakiss.org", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US)) { class MangaKiss : Madara("MangaKiss", "https://mangakiss.org", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US)) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl) override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
} }
class MangaDods: Madara("MangaDods", "https://www.mangadods.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US)) class MangaDods : Madara("MangaDods", "https://www.mangadods.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US))
class MangaWOW: Madara("MangaWOW", "https://mangawow.com", "tr") class MangaWOW : Madara("MangaWOW", "https://mangawow.com", "tr")
class MangaStream: Madara("MangaStream", "https://www.mangastream.cc", "en") class MangaStream : Madara("MangaStream", "https://www.mangastream.cc", "en")
class NeoxScanlator : Madara("Neox Scanlator", "https://neoxscan.com/newsite", "pt-BR", SimpleDateFormat("dd 'de' MMM 'de' yyyy", Locale("pt", "BR"))) { class NeoxScanlator : Madara("Neox Scanlator", "https://neoxscan.com/newsite", "pt-BR", SimpleDateFormat("dd 'de' MMM 'de' yyyy", Locale("pt", "BR"))) {
override fun headersBuilder(): Headers.Builder = Headers.Builder() override fun headersBuilder(): Headers.Builder = Headers.Builder()
@ -526,7 +524,7 @@ class NeoxScanlator : Madara("Neox Scanlator", "https://neoxscan.com/newsite", "
.add("Origin", baseUrl) .add("Origin", baseUrl)
// Only status and order by filter work. // Only status and order by filter work.
override fun getFilterList(): FilterList = FilterList(super.getFilterList().slice(3 .. 4)) override fun getFilterList(): FilterList = FilterList(super.getFilterList().slice(3..4))
companion object { companion object {
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36" private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"

View File

@ -7,20 +7,20 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
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.Locale import java.util.Locale
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
// Based off of Mangakakalot 1.2.8 // Based off of Mangakakalot 1.2.8
abstract class MangaBox ( abstract class MangaBox(
override val name: String, override val name: String,
override val baseUrl: String, override val baseUrl: String,
override val lang: String, override val lang: String,

View File

@ -3,14 +3,14 @@ package eu.kanade.tachiyomi.extension.all.mangabox
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request
import okhttp3.Response
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import okhttp3.Request
import okhttp3.Response
class MangaBoxFactory : SourceFactory { class MangaBoxFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(
@ -125,7 +125,7 @@ class MangaOnl : MangaBoxPathedGenres("MangaOnl", "https://mangaonl.com", "en")
override val popularUrlPath = "story-list-ty-topview-st-all-ca-all-" override val popularUrlPath = "story-list-ty-topview-st-all-ca-all-"
override val latestUrlPath = "story-list-ty-latest-st-all-ca-all-" override val latestUrlPath = "story-list-ty-latest-st-all-ca-all-"
override fun popularMangaSelector() = "div.story_item" override fun popularMangaSelector() = "div.story_item"
override val mangaDetailsMainSelector = "div.panel_story_info, ${super.mangaDetailsMainSelector}" //Some manga link to Nelo override val mangaDetailsMainSelector = "div.panel_story_info, ${super.mangaDetailsMainSelector}" // Some manga link to Nelo
override val thumbnailSelector = "img.story_avatar, ${super.thumbnailSelector}" override val thumbnailSelector = "img.story_avatar, ${super.thumbnailSelector}"
override val descriptionSelector = "div.panel_story_info_description, ${super.descriptionSelector}" override val descriptionSelector = "div.panel_story_info_description, ${super.descriptionSelector}"
override fun chapterListSelector() = "div.chapter_list_title + ul li, ${super.chapterListSelector()}" override fun chapterListSelector() = "div.chapter_list_title + ul li, ${super.chapterListSelector()}"

View File

@ -4,7 +4,14 @@ import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.ListPreference import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen import android.support.v7.preference.PreferenceScreen
import com.github.salomonbrys.kotson.* import com.github.salomonbrys.kotson.forEach
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.keys
import com.github.salomonbrys.kotson.long
import com.github.salomonbrys.kotson.nullString
import com.github.salomonbrys.kotson.obj
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.JsonParser
@ -13,20 +20,30 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservable import eu.kanade.tachiyomi.network.asObservable
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.* import java.net.URLEncoder
import java.util.Date
import java.util.concurrent.TimeUnit
import kotlin.collections.set
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.jsoup.parser.Parser import org.jsoup.parser.Parser
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.net.URLEncoder
import java.util.Date
import java.util.concurrent.TimeUnit
import kotlin.collections.set
abstract class Mangadex( abstract class Mangadex(
override val lang: String, override val lang: String,
@ -34,7 +51,6 @@ abstract class Mangadex(
) : ConfigurableSource, ParsedHttpSource() { ) : ConfigurableSource, ParsedHttpSource() {
init { init {
} }
override val name = "MangaDex" override val name = "MangaDex"
@ -49,7 +65,7 @@ abstract class Mangadex(
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
private val mangadexDescription : MangadexDescription by lazy { private val mangadexDescription: MangadexDescription by lazy {
MangadexDescription(internalLang) MangadexDescription(internalLang)
} }
@ -130,7 +146,6 @@ abstract class Mangadex(
element.let { element.let {
manga.setUrlWithoutDomain(modifyMangaUrl(it.attr("href"))) manga.setUrlWithoutDomain(modifyMangaUrl(it.attr("href")))
manga.title = it.text().trim() manga.title = it.text().trim()
} }
manga.thumbnail_url = formThumbUrl(manga.url) manga.thumbnail_url = formThumbUrl(manga.url)
@ -331,7 +346,7 @@ abstract class Mangadex(
searchMangaFromElement(element) searchMangaFromElement(element)
} }
val hasNextPage = searchMangaNextPageSelector()?.let { selector -> val hasNextPage = searchMangaNextPageSelector().let { selector ->
document.select(selector).first() document.select(selector).first()
} != null } != null
@ -376,7 +391,7 @@ abstract class Mangadex(
return if (lastSection.toIntOrNull() != null) { return if (lastSection.toIntOrNull() != null) {
lastSection lastSection
} else { } else {
//this occurs if person has manga from before that had the id/name/ // this occurs if person has manga from before that had the id/name/
url.trimEnd('/').substringBeforeLast("/").substringAfterLast("/") url.trimEnd('/').substringBeforeLast("/").substringAfterLast("/")
} }
} }
@ -389,7 +404,7 @@ abstract class Mangadex(
val chapterJson = json.getAsJsonObject("chapter") val chapterJson = json.getAsJsonObject("chapter")
manga.title = cleanString(mangaJson.get("title").string) manga.title = cleanString(mangaJson.get("title").string)
manga.thumbnail_url = cdnUrl + mangaJson.get("cover_url").string manga.thumbnail_url = cdnUrl + mangaJson.get("cover_url").string
manga.description = cleanString(mangadexDescription.clean(internalLang, mangaJson.get("description").string)) manga.description = cleanString(mangadexDescription.clean(mangaJson.get("description").string))
manga.author = cleanString(mangaJson.get("author").string) manga.author = cleanString(mangaJson.get("author").string)
manga.artist = cleanString(mangaJson.get("artist").string) manga.artist = cleanString(mangaJson.get("artist").string)
val status = mangaJson.get("status").int val status = mangaJson.get("status").int
@ -509,7 +524,7 @@ abstract class Mangadex(
} }
chapterName.add(chapterJson.get("title").string) chapterName.add(chapterJson.get("title").string)
} }
//if volume, chapter and title is empty its a oneshot // if volume, chapter and title is empty its a oneshot
if (chapterName.isEmpty()) { if (chapterName.isEmpty()) {
chapterName.add("Oneshot") chapterName.add("Oneshot")
} }

View File

@ -14,12 +14,12 @@ class MangadexDescription(private val internalLang: String) {
else -> emptyList() else -> emptyList()
} }
fun clean(internalLang: String, description: String): String { fun clean(description: String): String {
val langList = ALL_LANGS.toMutableList() val langList = ALL_LANGS.toMutableList()
//remove any languages before the ones provided in the langTextToCheck, if no matches or empty // remove any languages before the ones provided in the langTextToCheck, if no matches or empty
// just uses the original description, also removes the potential lang from all lang list // just uses the original description, also removes the potential lang from all lang list
var newDescription = description; var newDescription = description
listOfLangs.forEach { it -> listOfLangs.forEach { it ->
newDescription = newDescription.substringAfter(it) newDescription = newDescription.substringAfter(it)
langList.remove(it) langList.remove(it)

View File

@ -41,5 +41,4 @@ class MangadexUrlActivity : Activity() {
finish() finish()
exitProcess(0) exitProcess(0)
} }
} }

View File

@ -12,14 +12,14 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.Headers import okhttp3.Headers
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import rx.Observable import rx.Observable
import java.text.SimpleDateFormat
import java.util.Locale
/** /**
* MangAdventure base source. * MangAdventure base source.
@ -73,7 +73,9 @@ abstract class MangAdventure(
override fun mangaDetailsRequest(manga: SManga) = GET(manga.url, headers) override fun mangaDetailsRequest(manga: SManga) = GET(manga.url, headers)
override fun searchMangaRequest( override fun searchMangaRequest(
page: Int, query: String, filters: FilterList page: Int,
query: String,
filters: FilterList
): Request { ): Request {
val uri = Uri.parse("$apiUrl/series/").buildUpon() val uri = Uri.parse("$apiUrl/series/").buildUpon()
if (query.startsWith(SLUG_QUERY)) { if (query.startsWith(SLUG_QUERY)) {

View File

@ -33,5 +33,4 @@ class MangAdventureActivity : Activity() {
private fun logInvalidIntent(intent: Intent) = Log.e( private fun logInvalidIntent(intent: Intent) = Log.e(
"MangAdventureActivity", "Failed to parse URI from intent: $intent" "MangAdventureActivity", "Failed to parse URI from intent: $intent"
) )
} }

View File

@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.extension.all.mangadventure
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import java.text.DecimalFormat
import okhttp3.Response import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.text.DecimalFormat
/** Returns the body of a response as a `String`. */ /** Returns the body of a response as a `String`. */
fun Response.asString(): String = body()!!.string() fun Response.asString(): String = body()!!.string()

View File

@ -14,8 +14,13 @@ import com.squareup.duktape.Duktape
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import java.util.UUID
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
@ -28,8 +33,6 @@ import okhttp3.ResponseBody
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.lang.Exception
import java.util.UUID
abstract class MangaPlus( abstract class MangaPlus(
override val lang: String, override val lang: String,
@ -390,7 +393,7 @@ abstract class MangaPlus(
} }
private val ErrorResult.langPopup: Popup private val ErrorResult.langPopup: Popup
get() = when(lang) { get() = when (lang) {
"es" -> spanishPopup "es" -> spanishPopup
else -> englishPopup else -> englishPopup
} }

View File

@ -1,11 +1,11 @@
package eu.kanade.tachiyomi.extension.all.mangaplus package eu.kanade.tachiyomi.extension.all.mangaplus
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kotlinx.serialization.protobuf.ProtoId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer import kotlinx.serialization.Serializer
import kotlinx.serialization.protobuf.ProtoId
@Serializer(forClass=MangaPlusResponse::class) @Serializer(forClass = MangaPlusResponse::class)
object MangaPlusSerializer object MangaPlusSerializer
@Serializable @Serializable

View File

@ -7,14 +7,14 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import java.util.Calendar
import java.util.concurrent.TimeUnit
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.Calendar
import java.util.concurrent.TimeUnit
open class Mangatensei(override val lang: String, private val Mtlang: String) : ParsedHttpSource() { open class Mangatensei(override val lang: String, private val Mtlang: String) : ParsedHttpSource() {
@ -270,7 +270,7 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) :
return pages return pages
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
private class AuthorFilter : Filter.Text("Author / Artist") private class AuthorFilter : Filter.Text("Author / Artist")
private class StyleFilter(genres: List<Tag>) : Filter.Group<Tag>("Styles", genres) private class StyleFilter(genres: List<Tag>) : Filter.Group<Tag>("Styles", genres)
@ -392,10 +392,9 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) :
} }
private class Tag(name: String) : Filter.CheckBox(name) private class Tag(name: String) : Filter.CheckBox(name)
} }
abstract class OtherSite(private val sourceName: String, private val sourceBaseUrl: String, private val tachiLang: String, private val sourceLang: String): Mangatensei(tachiLang, sourceLang) { abstract class OtherSite(private val sourceName: String, private val sourceBaseUrl: String, private val tachiLang: String, private val sourceLang: String) : Mangatensei(tachiLang, sourceLang) {
override val name = sourceName override val name = sourceName
override val baseUrl = sourceBaseUrl override val baseUrl = sourceBaseUrl

View File

@ -155,5 +155,3 @@ class BatotoSpanish : OtherSite("Bato.to", "https://bato.to", "es", "spanish")
class BatotoThai : OtherSite("Bato.to", "https://bato.to", "th", "thai") class BatotoThai : OtherSite("Bato.to", "https://bato.to", "th", "thai")
class BatotoTurkish : OtherSite("Bato.to", "https://bato.to", "tr", "turkish") class BatotoTurkish : OtherSite("Bato.to", "https://bato.to", "tr", "turkish")
class BatotoVietnamese : OtherSite("Bato.to", "https://bato.to", "vi", "vietnamese") class BatotoVietnamese : OtherSite("Bato.to", "https://bato.to", "vi", "vietnamese")

View File

@ -1,18 +1,21 @@
package eu.kanade.tachiyomi.extension.all.mangatoon package eu.kanade.tachiyomi.extension.all.mangatoon
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.*
open class MangaToon ( open class MangaToon(
override val lang: String, override val lang: String,
private val urllang: String private val urllang: String
) : ParsedHttpSource() { ) : ParsedHttpSource() {
@ -30,13 +33,12 @@ open class MangaToon (
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun popularMangaRequest(page: Int): Request {
override fun popularMangaRequest(page: Int): Request{ val page0 = page - 1
val page0 = page-1
return GET("$baseUrl/$urllang/genre/hot?page=$page0", headers) return GET("$baseUrl/$urllang/genre/hot?page=$page0", headers)
} }
override fun latestUpdatesRequest(page: Int): Request{ override fun latestUpdatesRequest(page: Int): Request {
val page0 = page-1 val page0 = page - 1
return GET("$baseUrl/$urllang/genre/new?page=$page0", headers) return GET("$baseUrl/$urllang/genre/new?page=$page0", headers)
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
@ -44,11 +46,10 @@ open class MangaToon (
return GET(url.toString(), headers) return GET(url.toString(), headers)
} }
//override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url, headers) // override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url, headers)
//override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers) // override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
override fun chapterListRequest(manga: SManga) = GET(baseUrl + manga.url + "/episodes", headers) override fun chapterListRequest(manga: SManga) = GET(baseUrl + manga.url + "/episodes", headers)
override fun popularMangaFromElement(element: Element) = mangaFromElement(element) override fun popularMangaFromElement(element: Element) = mangaFromElement(element)
override fun latestUpdatesFromElement(element: Element) = mangaFromElement(element) override fun latestUpdatesFromElement(element: Element) = mangaFromElement(element)
override fun searchMangaFromElement(element: Element): SManga { override fun searchMangaFromElement(element: Element): SManga {
@ -74,14 +75,14 @@ open class MangaToon (
val chapter = SChapter.create() val chapter = SChapter.create()
chapter.url = element.select("a").first().attr("href") chapter.url = element.select("a").first().attr("href")
chapter.chapter_number = element.select("div.item-left").text().trim().toFloat() chapter.chapter_number = element.select("div.item-left").text().trim().toFloat()
val date= element.select("div.episode-date").text() val date = element.select("div.episode-date").text()
chapter.date_upload = parseDate(date) chapter.date_upload = parseDate(date)
chapter.name = if (chapter.chapter_number>20) {"\uD83D\uDD12 "} else {""} + element.select("div.episode-title").text().trim() chapter.name = if (chapter.chapter_number> 20) { "\uD83D\uDD12 " } else { "" } + element.select("div.episode-title").text().trim()
return chapter return chapter
} }
private fun parseDate(date: String): Long { private fun parseDate(date: String): Long {
return SimpleDateFormat("yyyy-MM-dd", Locale.US ).parse(date).time return SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(date).time
} }
override fun mangaDetailsParse(document: Document): SManga { override fun mangaDetailsParse(document: Document): SManga {
@ -94,7 +95,7 @@ open class MangaToon (
manga.genre = glist.joinToString(", ") manga.genre = glist.joinToString(", ")
manga.status = when (document.select("span.update-date")?.first()?.text()) { manga.status = when (document.select("span.update-date")?.first()?.text()) {
"Update" -> SManga.ONGOING "Update" -> SManga.ONGOING
"End","完结" -> SManga.COMPLETED "End", "完结" -> SManga.COMPLETED
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
} }
return manga return manga
@ -107,13 +108,11 @@ open class MangaToon (
for (i in 0 until elements.size) { for (i in 0 until elements.size) {
pages.add(Page(i, "", elements[i].attr("abs:src"))) pages.add(Page(i, "", elements[i].attr("abs:src")))
} }
if (pages.size ==1) throw Exception("Locked episode, download MangaToon APP and read for free!") if (pages.size == 1) throw Exception("Locked episode, download MangaToon APP and read for free!")
return pages return pages
} }
override fun pageListParse(document: Document) = throw Exception("Not used") override fun pageListParse(document: Document) = throw Exception("Not used")
override fun imageUrlRequest(page: Page) = throw Exception("Not used") override fun imageUrlRequest(page: Page) = throw Exception("Not used")
override fun imageUrlParse(document: Document) = throw Exception("Not used") override fun imageUrlParse(document: Document) = throw Exception("Not used")
} }

View File

@ -4,10 +4,6 @@ import android.annotation.SuppressLint
import android.annotation.TargetApi import android.annotation.TargetApi
import android.os.Build import android.os.Build
import com.google.gson.Gson import com.google.gson.Gson
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.io.PrintWriter import java.io.PrintWriter
import java.security.cert.CertificateException import java.security.cert.CertificateException
import java.time.ZonedDateTime import java.time.ZonedDateTime
@ -16,6 +12,10 @@ import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager import javax.net.ssl.X509TrustManager
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
/** /**
* This class generates the sources for MMRCMS. * This class generates the sources for MMRCMS.
@ -55,10 +55,10 @@ class Generator {
var prefix = itemUrl.substringAfterLast("/").substringBeforeLast("/") var prefix = itemUrl.substringAfterLast("/").substringBeforeLast("/")
//Sometimes itemUrl is the root of the website, and thus the prefix found is the website address. // Sometimes itemUrl is the root of the website, and thus the prefix found is the website address.
// In this case, we set the default prefix as "manga". // In this case, we set the default prefix as "manga".
if (prefix.startsWith("www")){ if (prefix.startsWith("www")) {
prefix="manga" prefix = "manga"
} }
val mangaListDocument = getDocument("${it.third}/$prefix-list")!! val mangaListDocument = getDocument("${it.third}/$prefix-list")!!
@ -78,10 +78,8 @@ class Generator {
val toJson = Gson().toJson(map) val toJson = Gson().toJson(map)
buffer.append("private const val MMRSOURCE_$number = \"\"\"$toJson\"\"\"\n") buffer.append("private const val MMRSOURCE_$number = \"\"\"$toJson\"\"\"\n")
number++ number++
} catch (e: Exception) { } catch (e: Exception) {
println("error generating source ${it.second} ${e.printStackTrace()}") println("error generating source ${it.second} ${e.printStackTrace()}")
} }
@ -104,7 +102,6 @@ class Generator {
val writer = PrintWriter(relativePath) val writer = PrintWriter(relativePath)
writer.write(buffer.toString()) writer.write(buffer.toString())
writer.close() writer.close()
} else { } else {
val writer = PrintWriter(relativePathTest) val writer = PrintWriter(relativePathTest)
writer.write(buffer.toString()) writer.write(buffer.toString())
@ -158,14 +155,13 @@ class Generator {
array.add(map) array.add(map)
} }
return array return array
} }
private fun getItemUrl(document: Document): String { private fun getItemUrl(document: Document): String {
return document.toString().substringAfter("showURL = \"").substringAfter("showURL=\"").substringBefore("/SELECTION\";") return document.toString().substringAfter("showURL = \"").substringAfter("showURL=\"").substringBefore("/SELECTION\";")
//Some websites like mangasyuri use javascript minifiers, and thus "showURL = " becomes "showURL="https://mangasyuri.net/manga/SELECTION"" // Some websites like mangasyuri use javascript minifiers, and thus "showURL = " becomes "showURL="https://mangasyuri.net/manga/SELECTION""
//(without spaces). Hence the double substringAfter. // (without spaces). Hence the double substringAfter.
} }
private fun supportsLatest(third: String): Boolean { private fun supportsLatest(third: String): Boolean {
@ -190,7 +186,6 @@ class Generator {
return array return array
} }
@Throws(Exception::class) @Throws(Exception::class)
private fun getOkHttpClient(): OkHttpClient { private fun getOkHttpClient(): OkHttpClient {
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
@ -227,7 +222,6 @@ class Generator {
.build() .build()
} }
companion object { companion object {
const val DRY_RUN = false const val DRY_RUN = false
val sources = listOf( val sources = listOf(
@ -239,7 +233,7 @@ class Generator {
Triple("en", "White Cloud Pavilion", "https://www.whitecloudpavilion.com/manga/free"), Triple("en", "White Cloud Pavilion", "https://www.whitecloudpavilion.com/manga/free"),
Triple("fr", "Scan FR", "https://www.scan-fr.co"), Triple("fr", "Scan FR", "https://www.scan-fr.co"),
Triple("fr", "Scan VF", "https://www.scan-vf.net"), Triple("fr", "Scan VF", "https://www.scan-vf.net"),
Triple("fr", "Scan OP","https://scan-op.com"), Triple("fr", "Scan OP", "https://scan-op.com"),
Triple("id", "Komikid", "https://www.komikid.com"), Triple("id", "Komikid", "https://www.komikid.com"),
Triple("pl", "ToraScans", "http://torascans.pl"), Triple("pl", "ToraScans", "http://torascans.pl"),
Triple("pt", "Comic Space", "https://www.comicspace.com.br"), Triple("pt", "Comic Space", "https://www.comicspace.com.br"),
@ -256,70 +250,69 @@ class Generator {
Triple("bg", "Utsukushii", "https://manga.utsukushii-bg.com"), Triple("bg", "Utsukushii", "https://manga.utsukushii-bg.com"),
Triple("es", "Universo Yuri", "https://universoyuri.com"), Triple("es", "Universo Yuri", "https://universoyuri.com"),
Triple("pl", "Phoenix-Scans", "https://phoenix-scans.pl"), Triple("pl", "Phoenix-Scans", "https://phoenix-scans.pl"),
Triple("ru", "Japit Comics","https://j-comics.ru"), Triple("ru", "Japit Comics", "https://j-comics.ru"),
Triple("tr", "Puzzmos", "https://puzzmos.com"), Triple("tr", "Puzzmos", "https://puzzmos.com"),
Triple("fr", "Scan-1", "https://www.scan-1.com"), Triple("fr", "Scan-1", "https://www.scan-1.com"),
Triple("fr", "Lelscan-VF", "https://www.lelscan-vf.com"), Triple("fr", "Lelscan-VF", "https://www.lelscan-vf.com"),
//NOTE: THIS SOURCE CONTAINS A CUSTOM LANGUAGE SYSTEM (which will be ignored)! // NOTE: THIS SOURCE CONTAINS A CUSTOM LANGUAGE SYSTEM (which will be ignored)!
Triple("other", "HentaiShark", "https://www.hentaishark.com")) Triple("other", "HentaiShark", "https://www.hentaishark.com"))
//Changed CMS // Changed CMS
//Triple("en", "MangaTreat Scans", "http://www.mangatreat.com"), // Triple("en", "MangaTreat Scans", "http://www.mangatreat.com"),
//Triple("en", "Chibi Manga Reader", "https://www.cmreader.info"), // Triple("en", "Chibi Manga Reader", "https://www.cmreader.info"),
//Triple("tr", "Epikmanga", "https://www.epikmanga.com"), // Triple("tr", "Epikmanga", "https://www.epikmanga.com"),
//Triple("en", "Hatigarm Scans", "https://hatigarmscans.net"), // Triple("en", "Hatigarm Scans", "https://hatigarmscans.net"),
//Went offline // Went offline
//Triple("ru", "Anigai clan", "http://anigai.ru"), // Triple("ru", "Anigai clan", "http://anigai.ru"),
//Triple("en", "ZXComic", "http://zxcomic.com"), // Triple("en", "ZXComic", "http://zxcomic.com"),
//Triple("es", "SOS Scanlation", "https://sosscanlation.com"), // Triple("es", "SOS Scanlation", "https://sosscanlation.com"),
//Triple("es", "MangaCasa", "https://mangacasa.com")) // Triple("es", "MangaCasa", "https://mangacasa.com"))
//Triple("ja", "RAW MANGA READER", "https://rawmanga.site"), // Triple("ja", "RAW MANGA READER", "https://rawmanga.site"),
//Triple("ar", "Manga FYI", "http://mangafyi.com/manga/arabic"), // Triple("ar", "Manga FYI", "http://mangafyi.com/manga/arabic"),
//Triple("en", "MangaRoot", "http://mangaroot.com"), // Triple("en", "MangaRoot", "http://mangaroot.com"),
//Triple("en", "MangaForLife", "http://manga4ever.com"), // Triple("en", "MangaForLife", "http://manga4ever.com"),
//Triple("en", "Manga Spoil", "http://mangaspoil.com"), // Triple("en", "Manga Spoil", "http://mangaspoil.com"),
//Triple("en", "MangaBlue", "http://mangablue.com"), // Triple("en", "MangaBlue", "http://mangablue.com"),
//Triple("en", "Manga Forest", "https://mangaforest.com"), // Triple("en", "Manga Forest", "https://mangaforest.com"),
//Triple("en", "DManga", "http://dmanga.website"), // Triple("en", "DManga", "http://dmanga.website"),
//Triple("en", "DB Manga", "http://dbmanga.com"), // Triple("en", "DB Manga", "http://dbmanga.com"),
//Triple("en", "Mangacox", "http://mangacox.com"), // Triple("en", "Mangacox", "http://mangacox.com"),
//Triple("en", "GO Manhwa", "http://gomanhwa.xyz"), // Triple("en", "GO Manhwa", "http://gomanhwa.xyz"),
//Triple("en", "KoManga", "https://komanga.net"), // Triple("en", "KoManga", "https://komanga.net"),
//Triple("en", "Manganimecan", "http://manganimecan.com"), // Triple("en", "Manganimecan", "http://manganimecan.com"),
//Triple("en", "Hentai2Manga", "http://hentai2manga.com"), // Triple("en", "Hentai2Manga", "http://hentai2manga.com"),
//Triple("en", "4 Manga", "http://4-manga.com"), // Triple("en", "4 Manga", "http://4-manga.com"),
//Triple("en", "XYXX.INFO", "http://xyxx.info"), // Triple("en", "XYXX.INFO", "http://xyxx.info"),
//Triple("en", "Isekai Manga Reader", "https://isekaimanga.club"), // Triple("en", "Isekai Manga Reader", "https://isekaimanga.club"),
//Triple("fa", "TrinityReader", "http://trinityreader.pw"), // Triple("fa", "TrinityReader", "http://trinityreader.pw"),
//Triple("fr", "Manga-LEL", "https://www.manga-lel.com"), // Triple("fr", "Manga-LEL", "https://www.manga-lel.com"),
//Triple("fr", "Manga Etonnia", "https://www.etonnia.com"), // Triple("fr", "Manga Etonnia", "https://www.etonnia.com"),
//Triple("fr", "ScanFR.com"), "http://scanfr.com"), // Triple("fr", "ScanFR.com"), "http://scanfr.com"),
//Triple("fr", "Manga FYI", "http://mangafyi.com/manga/french"), // Triple("fr", "Manga FYI", "http://mangafyi.com/manga/french"),
//Triple("fr", "scans-manga", "http://scans-manga.com"), // Triple("fr", "scans-manga", "http://scans-manga.com"),
//Triple("fr", "Henka no Kaze", "http://henkanokazelel.esy.es/upload"), // Triple("fr", "Henka no Kaze", "http://henkanokazelel.esy.es/upload"),
//Triple("fr", "Tous Vos Scans", "http://www.tous-vos-scans.com"), // Triple("fr", "Tous Vos Scans", "http://www.tous-vos-scans.com"),
//Triple("id", "Manga Desu", "http://mangadesu.net"), // Triple("id", "Manga Desu", "http://mangadesu.net"),
//Triple("id", "Komik Mangafire.ID", "http://go.mangafire.id"), // Triple("id", "Komik Mangafire.ID", "http://go.mangafire.id"),
//Triple("id", "MangaOnline", "https://mangaonline.web.id"), // Triple("id", "MangaOnline", "https://mangaonline.web.id"),
//Triple("id", "MangaNesia", "https://manganesia.com"), // Triple("id", "MangaNesia", "https://manganesia.com"),
//Triple("id", "MangaID", "https://mangaid.me" // Triple("id", "MangaID", "https://mangaid.me"
//Triple("id", "Manga Seru", "http://www.mangaseru.top" // Triple("id", "Manga Seru", "http://www.mangaseru.top"
//Triple("id", "Manga FYI", "http://mangafyi.com/manga/indonesian" // Triple("id", "Manga FYI", "http://mangafyi.com/manga/indonesian"
//Triple("id", "Bacamangaku", "http://www.bacamangaku.com"), // Triple("id", "Bacamangaku", "http://www.bacamangaku.com"),
//Triple("id", "Indo Manga Reader", "http://indomangareader.com"), // Triple("id", "Indo Manga Reader", "http://indomangareader.com"),
//Triple("it", "Kingdom Italia Reader", "http://kireader.altervista.org"), // Triple("it", "Kingdom Italia Reader", "http://kireader.altervista.org"),
//Triple("ja", "IchigoBook", "http://ichigobook.com"), // Triple("ja", "IchigoBook", "http://ichigobook.com"),
//Triple("ja", "Mangaraw Online", "http://mangaraw.online" // Triple("ja", "Mangaraw Online", "http://mangaraw.online"
//Triple("ja", "Mangazuki RAWS", "https://raws.mangazuki.co"), // Triple("ja", "Mangazuki RAWS", "https://raws.mangazuki.co"),
//Triple("ja", "MangaRAW", "https://www.mgraw.com"), // Triple("ja", "MangaRAW", "https://www.mgraw.com"),
//Triple("ja", "マンガ/漫画 マガジン/雑誌 raw", "http://netabare-manga-raw.com"), // Triple("ja", "マンガ/漫画 マガジン/雑誌 raw", "http://netabare-manga-raw.com"),
//Triple("ru", "NAKAMA", "http://nakama.ru"), // Triple("ru", "NAKAMA", "http://nakama.ru"),
//Triple("tr", "MangAoi", "http://mangaoi.com"), // Triple("tr", "MangAoi", "http://mangaoi.com"),
//Triple("tr", "ManhuaTR", "http://www.manhua-tr.com"), // Triple("tr", "ManhuaTR", "http://www.manhua-tr.com"),
val relativePath = System.getProperty("user.dir") + "/src/all/mmrcms/src/eu/kanade/tachiyomi/extension/all/mmrcms/GeneratedSources.kt" val relativePath = System.getProperty("user.dir") + "/src/all/mmrcms/src/eu/kanade/tachiyomi/extension/all/mmrcms/GeneratedSources.kt"
val relativePathTest = System.getProperty("user.dir") + "/src/all/mmrcms/TestGeneratedSources.kt" val relativePathTest = System.getProperty("user.dir") + "/src/all/mmrcms/TestGeneratedSources.kt"
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
Generator().generate() Generator().generate()

View File

@ -16,22 +16,24 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Element
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Element
class MyMangaReaderCMSSource(override val lang: String, class MyMangaReaderCMSSource(
override val name: String, override val lang: String,
override val baseUrl: String, override val name: String,
override val supportsLatest: Boolean, override val baseUrl: String,
private val itemUrl: String, override val supportsLatest: Boolean,
private val categoryMappings: List<Pair<String, String>>, private val itemUrl: String,
private val tagMappings: List<Pair<String, String>>?) : HttpSource() { private val categoryMappings: List<Pair<String, String>>,
private val tagMappings: List<Pair<String, String>>?
) : HttpSource() {
private val jsonParser = JsonParser() private val jsonParser = JsonParser()
private val itemUrlPath = Uri.parse(itemUrl).pathSegments.firstOrNull() private val itemUrlPath = Uri.parse(itemUrl).pathSegments.firstOrNull()
private val parsedBaseUrl = Uri.parse(baseUrl) private val parsedBaseUrl = Uri.parse(baseUrl)
@ -49,7 +51,7 @@ class MyMangaReaderCMSSource(override val lang: String,
} }
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
//Query overrides everything // Query overrides everything
val url: Uri.Builder val url: Uri.Builder
if (query.isNotBlank()) { if (query.isNotBlank()) {
url = Uri.parse("$baseUrl/search")!!.buildUpon() url = Uri.parse("$baseUrl/search")!!.buildUpon()
@ -67,7 +69,7 @@ class MyMangaReaderCMSSource(override val lang: String,
override fun popularMangaParse(response: Response) = internalMangaParse(response) override fun popularMangaParse(response: Response) = internalMangaParse(response)
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
return if (response.request().url().queryParameter("query")?.isNotBlank() == true) { return if (response.request().url().queryParameter("query")?.isNotBlank() == true) {
//If a search query was specified, use search instead! // If a search query was specified, use search instead!
MangasPage(jsonParser MangasPage(jsonParser
.parse(response.body()!!.string())["suggestions"].array .parse(response.body()!!.string())["suggestions"].array
.map { .map {
@ -120,7 +122,7 @@ class MyMangaReaderCMSSource(override val lang: String,
if (urlElement.size == 0) { if (urlElement.size == 0) {
url = getUrlWithoutBaseUrl(it.select("a").attr("href")) url = getUrlWithoutBaseUrl(it.select("a").attr("href"))
title = it.select("div.caption").text() title = it.select("div.caption").text()
it.select("div.caption div").text().let { if (it.isNotEmpty()) title = title.substringBefore(it)} // To clean submanga's titles without breaking hentaishark's it.select("div.caption div").text().let { if (it.isNotEmpty()) title = title.substringBefore(it) } // To clean submanga's titles without breaking hentaishark's
} else { } else {
url = getUrlWithoutBaseUrl(urlElement.attr("href")) url = getUrlWithoutBaseUrl(urlElement.attr("href"))
title = urlElement.text().trim() title = urlElement.text().trim()
@ -175,19 +177,19 @@ class MyMangaReaderCMSSource(override val lang: String,
thumbnail_url = coverGuess(document.select(".row [class^=img-responsive]").firstOrNull()?.attr("abs:src"), document.location()) thumbnail_url = coverGuess(document.select(".row [class^=img-responsive]").firstOrNull()?.attr("abs:src"), document.location())
description = document.select(".row .well p").text().trim() description = document.select(".row .well p").text().trim()
val detailAuthor = setOf("author(s)","autor(es)","auteur(s)","著作","yazar(lar)","mangaka(lar)","pengarang/penulis","pengarang","penulis","autor","المؤلف","перевод", "autor/autorzy") val detailAuthor = setOf("author(s)", "autor(es)", "auteur(s)", "著作", "yazar(lar)", "mangaka(lar)", "pengarang/penulis", "pengarang", "penulis", "autor", "المؤلف", "перевод", "autor/autorzy")
val detailArtist = setOf("artist(s)","artiste(s)","sanatçi(lar)","artista(s)","artist(s)/ilustrator","الرسام","seniman", "rysownik/rysownicy") val detailArtist = setOf("artist(s)", "artiste(s)", "sanatçi(lar)", "artista(s)", "artist(s)/ilustrator", "الرسام", "seniman", "rysownik/rysownicy")
val detailGenre = setOf("categories","categorías","catégories","ジャンル","kategoriler","categorias","kategorie","التصنيفات","жанр","kategori", "tagi") val detailGenre = setOf("categories", "categorías", "catégories", "ジャンル", "kategoriler", "categorias", "kategorie", "التصنيفات", "жанр", "kategori", "tagi")
val detailStatus = setOf("status","statut","estado","状態","durum","الحالة","статус") val detailStatus = setOf("status", "statut", "estado", "状態", "durum", "الحالة", "статус")
val detailStatusComplete = setOf("complete","مكتملة","complet","completo", "zakończone") val detailStatusComplete = setOf("complete", "مكتملة", "complet", "completo", "zakończone")
val detailStatusOngoing = setOf("ongoing","مستمرة","en cours","em lançamento", "prace w toku") val detailStatusOngoing = setOf("ongoing", "مستمرة", "en cours", "em lançamento", "prace w toku")
val detailDescription = setOf("description","resumen") val detailDescription = setOf("description", "resumen")
for (element in document.select(".row .dl-horizontal dt")) { for (element in document.select(".row .dl-horizontal dt")) {
when (element.text().trim().toLowerCase()) { when (element.text().trim().toLowerCase()) {
in detailAuthor -> author = element.nextElementSibling().text() in detailAuthor -> author = element.nextElementSibling().text()
in detailArtist -> artist = element.nextElementSibling().text() in detailArtist -> artist = element.nextElementSibling().text()
in detailGenre-> genre = element.nextElementSibling().select("a").joinToString { in detailGenre -> genre = element.nextElementSibling().select("a").joinToString {
it.text().trim() it.text().trim()
} }
in detailStatus -> status = when (element.nextElementSibling().text().trim().toLowerCase()) { in detailStatus -> status = when (element.nextElementSibling().text().trim().toLowerCase()) {
@ -231,7 +233,7 @@ class MyMangaReaderCMSSource(override val lang: String,
* Returns the Jsoup selector that returns a list of [Element] corresponding to each chapter. * Returns the Jsoup selector that returns a list of [Element] corresponding to each chapter.
*/ */
private fun chapterListSelector() = "ul[class^=chapters] > li:not(.btn), table.table tr" private fun chapterListSelector() = "ul[class^=chapters] > li:not(.btn), table.table tr"
//Some websites add characters after "chapters" thus the need of checking classes that starts with "chapters" // Some websites add characters after "chapters" thus the need of checking classes that starts with "chapters"
/** /**
* Returns a chapter from the given element. * Returns a chapter from the given element.
@ -243,7 +245,7 @@ class MyMangaReaderCMSSource(override val lang: String,
try { try {
val titleWrapper = element.select("[class^=chapter-title-rtl]").first() val titleWrapper = element.select("[class^=chapter-title-rtl]").first()
//Some websites add characters after "..-rtl" thus the need of checking classes that starts with that // Some websites add characters after "..-rtl" thus the need of checking classes that starts with that
val url = titleWrapper.getElementsByTag("a").attr("href") val url = titleWrapper.getElementsByTag("a").attr("href")
// Ensure chapter actually links to a manga // Ensure chapter actually links to a manga
@ -278,7 +280,7 @@ class MyMangaReaderCMSSource(override val lang: String,
return null return null
} }
private fun parseDate (dateText: String): Long { private fun parseDate(dateText: String): Long {
return try { return try {
DATE_FORMAT.parse(dateText).time DATE_FORMAT.parse(dateText).time
} catch (e: ParseException) { } catch (e: ParseException) {
@ -299,7 +301,7 @@ class MyMangaReaderCMSSource(override val lang: String,
// Mangas.pw encodes some of their urls, decode them // Mangas.pw encodes some of their urls, decode them
if (url.contains("mangas.pw") && url.contains("img.php")) { if (url.contains("mangas.pw") && url.contains("img.php")) {
url = url.substringAfter("i=") url = url.substringAfter("i=")
repeat (5) { repeat(5) {
url = Base64.decode(url, Base64.DEFAULT).toString(Charsets.UTF_8).substringBefore("=") url = Base64.decode(url, Base64.DEFAULT).toString(Charsets.UTF_8).substringBefore("=")
} }
} }
@ -348,10 +350,14 @@ class MyMangaReaderCMSSource(override val lang: String,
* If an entry is selected it is appended as a query parameter onto the end of the URI. * If an entry is selected it is appended as a query parameter onto the end of the URI.
* If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI. * If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI.
*/ */
//vals: <name, display> // vals: <name, display>
open class UriSelectFilter(displayName: String, private val uriParam: String, private val vals: Array<Pair<String, String>>, open class UriSelectFilter(
private val firstIsUnspecified: Boolean = true, displayName: String,
defaultValue: Int = 0) : private val uriParam: String,
private val vals: Array<Pair<String, String>>,
private val firstIsUnspecified: Boolean = true,
defaultValue: Int = 0
) :
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter { Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter {
override fun addToUri(uri: Uri.Builder) { override fun addToUri(uri: Uri.Builder) {
if (state != 0 || !firstIsUnspecified) if (state != 0 || !firstIsUnspecified)

View File

@ -86,5 +86,3 @@ class MyMangaReaderCMSSources : SourceFactory {
it["id"].string to it["name"].string it["id"].string to it["name"].string
} }
} }

View File

@ -3,9 +3,17 @@ package eu.kanade.tachiyomi.extension.all.myreadingmanga
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.concurrent.TimeUnit
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -13,13 +21,10 @@ import okhttp3.Response
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.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
open class MyReadingManga(override val lang: String) : ParsedHttpSource() { open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
//Basic Info // Basic Info
override val name = "MyReadingManga" override val name = "MyReadingManga"
override val baseUrl = "https://myreadingmanga.info" override val baseUrl = "https://myreadingmanga.info"
override val client: OkHttpClient = network.cloudflareClient.newBuilder() override val client: OkHttpClient = network.cloudflareClient.newBuilder()
@ -30,7 +35,7 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
.build()!! .build()!!
override val supportsLatest = true override val supportsLatest = true
//Popular - Random // Popular - Random
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/search/?wpsolr_sort=sort_by_random&wpsolr_page=$page", headers) // Random Manga as returned by search return GET("$baseUrl/search/?wpsolr_sort=sort_by_random&wpsolr_page=$page", headers) // Random Manga as returned by search
} }
@ -40,9 +45,9 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun popularMangaParse(response: Response) = searchMangaParse(response) override fun popularMangaParse(response: Response) = searchMangaParse(response)
override fun popularMangaFromElement(element: Element) = searchMangaFromElement(element) override fun popularMangaFromElement(element: Element) = searchMangaFromElement(element)
//Latest // Latest
override fun latestUpdatesRequest(page: Int): Request { override fun latestUpdatesRequest(page: Int): Request {
return GET("$baseUrl/page/$page/", headers) //Home Page - Latest Manga return GET("$baseUrl/page/$page/", headers) // Home Page - Latest Manga
} }
override fun latestUpdatesNextPageSelector() = "li.pagination-next" override fun latestUpdatesNextPageSelector() = "li.pagination-next"
@ -56,7 +61,6 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
} }
for (element in list) { for (element in list) {
mangas.add(latestUpdatesFromElement(element)) mangas.add(latestUpdatesFromElement(element))
} }
val hasNextPage = latestUpdatesNextPageSelector().let { selector -> val hasNextPage = latestUpdatesNextPageSelector().let { selector ->
@ -68,16 +72,15 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun latestUpdatesFromElement(element: Element) = buildManga(element.select("a[rel]").first(), element.select("a.entry-image-link img").first()) override fun latestUpdatesFromElement(element: Element) = buildManga(element.select("a[rel]").first(), element.select("a.entry-image-link img").first())
//Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val uri = if (query.isNotBlank()) { val uri = if (query.isNotBlank()) {
Uri.parse("$baseUrl/search/").buildUpon() Uri.parse("$baseUrl/search/").buildUpon()
.appendQueryParameter("search", query) .appendQueryParameter("search", query)
.appendQueryParameter("wpsolr_page", page.toString()) .appendQueryParameter("wpsolr_page", page.toString())
} else { } else {
val uri = Uri.parse("$baseUrl/").buildUpon() val uri = Uri.parse("$baseUrl/").buildUpon()
//Append uri filters // Append uri filters
filters.forEach { filters.forEach {
if (it is UriFilter) if (it is UriFilter)
it.addToUri(uri) it.addToUri(uri)
@ -90,7 +93,7 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun searchMangaNextPageSelector(): String? = null override fun searchMangaNextPageSelector(): String? = null
override fun searchMangaSelector() = "div.results-by-facets div[id*=res]" override fun searchMangaSelector() = "div.results-by-facets div[id*=res]"
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
//Filter Assist - Caches Pages required for filter parsing // Filter Assist - Caches Pages required for filter parsing
if (!filtersCached) { if (!filtersCached) {
filterAssist(baseUrl) filterAssist(baseUrl)
filterAssist("$baseUrl/cats/") filterAssist("$baseUrl/cats/")
@ -101,7 +104,7 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
val document = response.asJsoup() val document = response.asJsoup()
val mangas = mutableListOf<SManga>() val mangas = mutableListOf<SManga>()
//Process Search Results // Process Search Results
if (document.baseUri().contains("search", true)) { if (document.baseUri().contains("search", true)) {
val elements = document.select(searchMangaSelector()) val elements = document.select(searchMangaSelector())
for (element in elements) { for (element in elements) {
@ -115,16 +118,15 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
return MangasPage(mangas, hasNextPage) return MangasPage(mangas, hasNextPage)
} }
//Process Filter Results / Same theme as home page // Process Filter Results / Same theme as home page
else { else {
//return popularMangaParse(response) // return popularMangaParse(response)
val list = document.select(latestUpdatesSelector()).filter { element -> val list = document.select(latestUpdatesSelector()).filter { element ->
val select = element.select("a[rel=bookmark]") val select = element.select("a[rel=bookmark]")
select.text().contains("[$lang", true) select.text().contains("[$lang", true)
} }
for (element in list) { for (element in list) {
mangas.add(latestUpdatesFromElement(element)) mangas.add(latestUpdatesFromElement(element))
} }
val hasNextPage = latestUpdatesNextPageSelector().let { selector -> val hasNextPage = latestUpdatesNextPageSelector().let { selector ->
@ -137,8 +139,7 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun searchMangaFromElement(element: Element) = buildManga(element.select("a").first(), element.select("img")?.first()) override fun searchMangaFromElement(element: Element) = buildManga(element.select("a").first(), element.select("img")?.first())
// Build Manga From Element
//Build Manga From Element
private fun buildManga(titleElement: Element, thumbnailElement: Element?): SManga { private fun buildManga(titleElement: Element, thumbnailElement: Element?): SManga {
val manga = SManga.create() val manga = SManga.create()
manga.setUrlWithoutDomain(titleElement.attr("href")) manga.setUrlWithoutDomain(titleElement.attr("href"))
@ -160,16 +161,15 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
return url return url
} }
//removes resizing // removes resizing
private fun getThumbnail(thumbnailUrl: String) = thumbnailUrl.substringBeforeLast("-") + "." + thumbnailUrl.substringAfterLast(".") private fun getThumbnail(thumbnailUrl: String) = thumbnailUrl.substringBeforeLast("-") + "." + thumbnailUrl.substringAfterLast(".")
//cleans up the name removing author and language from the title // cleans up the name removing author and language from the title
private fun cleanTitle(title: String) = title.substringBeforeLast("[").substringAfterLast("]").substringBeforeLast("(").trim() private fun cleanTitle(title: String) = title.substringBeforeLast("[").substringAfterLast("]").substringBeforeLast("(").trim()
private fun cleanAuthor(author: String) = author.substringAfter("[").substringBefore("]").trim() private fun cleanAuthor(author: String) = author.substringAfter("[").substringBefore("]").trim()
// Manga Details
//Manga Details
override fun fetchMangaDetails(manga: SManga): Observable<SManga> { override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
val needCover = manga.thumbnail_url.isNullOrEmpty() val needCover = manga.thumbnail_url.isNullOrEmpty()
@ -204,8 +204,7 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun mangaDetailsParse(document: Document) = throw Exception("Not used") override fun mangaDetailsParse(document: Document) = throw Exception("Not used")
// Start Chapter Get
//Start Chapter Get
override fun chapterListSelector() = ".entry-pagination a" override fun chapterListSelector() = ".entry-pagination a"
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
@ -217,9 +216,9 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
val chfirstname = document.select(".chapter-class a[href*=$mangaUrl]")?.first()?.text()?.ifEmpty { "Ch. 1" }?.capitalize() val chfirstname = document.select(".chapter-class a[href*=$mangaUrl]")?.first()?.text()?.ifEmpty { "Ch. 1" }?.capitalize()
?: "Ch. 1" ?: "Ch. 1"
val scangroup = document.select(".entry-terms a[href*=group]")?.first()?.text() val scangroup = document.select(".entry-terms a[href*=group]")?.first()?.text()
//create first chapter since its on main manga page // create first chapter since its on main manga page
chapters.add(createChapter("1", document.baseUri(), date, chfirstname, scangroup)) chapters.add(createChapter("1", document.baseUri(), date, chfirstname, scangroup))
//see if there are multiple chapters or not // see if there are multiple chapters or not
document.select(chapterListSelector())?.let { it -> document.select(chapterListSelector())?.let { it ->
it.forEach { it.forEach {
if (!it.text().contains("Next »", true)) { if (!it.text().contains("Next »", true)) {
@ -249,7 +248,7 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun chapterFromElement(element: Element) = throw Exception("Not used") override fun chapterFromElement(element: Element) = throw Exception("Not used")
//Pages // Pages
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val body = response.asJsoup() val body = response.asJsoup()
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
@ -264,16 +263,16 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
override fun imageUrlRequest(page: Page) = throw Exception("Not used") override fun imageUrlRequest(page: Page) = throw Exception("Not used")
override fun imageUrlParse(document: Document) = throw Exception("Not used") override fun imageUrlParse(document: Document) = throw Exception("Not used")
//Filter Parsing, grabs pages as document and filters out Genres, Popular Tags, and Categories, Parings, and Scan Groups // Filter Parsing, grabs pages as document and filters out Genres, Popular Tags, and Categories, Parings, and Scan Groups
private var filtersCached = false private var filtersCached = false
//Grabs page containing filters and puts it into cache // Grabs page containing filters and puts it into cache
private fun filterAssist(url: String): String { private fun filterAssist(url: String): String {
val response = client.newCall(GET(url, headers)).execute() val response = client.newCall(GET(url, headers)).execute()
return response.body()!!.string() return response.body()!!.string()
} }
//Returns page from cache to reduce calls to website // Returns page from cache to reduce calls to website
private fun getCache(url: String): Document? { private fun getCache(url: String): Document? {
val response = client.newCall(GET(url, headers, CacheControl.FORCE_CACHE)).execute() val response = client.newCall(GET(url, headers, CacheControl.FORCE_CACHE)).execute()
return if (response.isSuccessful) { return if (response.isSuccessful) {
@ -285,16 +284,16 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
} }
} }
//Parses page for filter // Parses page for filter
private fun returnFilter(document: Document?, css: String, attributekey: String): Array<Pair<String, String>> { private fun returnFilter(document: Document?, css: String, attributekey: String): Array<Pair<String, String>> {
return document?.select(css)?.map { Pair(it.attr(attributekey).substringBeforeLast("/").substringAfterLast("/"), it.text()) }?.toTypedArray() return document?.select(css)?.map { Pair(it.attr(attributekey).substringBeforeLast("/").substringAfterLast("/"), it.text()) }?.toTypedArray()
?: arrayOf(Pair("", "Press 'Reset' to try again")) ?: arrayOf(Pair("", "Press 'Reset' to try again"))
} }
//Generates the filter lists for app // Generates the filter lists for app
override fun getFilterList(): FilterList { override fun getFilterList(): FilterList {
val filterList = FilterList( val filterList = FilterList(
//MRM does not support genre filtering and text search at the same time // MRM does not support genre filtering and text search at the same time
Filter.Header("NOTE: Filters are ignored if using text search."), Filter.Header("NOTE: Filters are ignored if using text search."),
Filter.Header("Only one filter can be used at a time."), Filter.Header("Only one filter can be used at a time."),
GenreFilter(returnFilter(getCache(baseUrl), ".tagcloud a[href*=/genre/]", "href")), GenreFilter(returnFilter(getCache(baseUrl), ".tagcloud a[href*=/genre/]", "href")),
@ -317,10 +316,14 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
* If an entry is selected it is appended as a query parameter onto the end of the URI. * If an entry is selected it is appended as a query parameter onto the end of the URI.
* If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI. * If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI.
*/ */
//vals: <name, display> // vals: <name, display>
private open class UriSelectFilterPath(displayName: String, val uriParam: String, val vals: Array<Pair<String, String>>, private open class UriSelectFilterPath(
val firstIsUnspecified: Boolean = true, displayName: String,
defaultValue: Int = 0) : val uriParam: String,
val vals: Array<Pair<String, String>>,
val firstIsUnspecified: Boolean = true,
defaultValue: Int = 0
) :
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter { Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter {
override fun addToUri(uri: Uri.Builder) { override fun addToUri(uri: Uri.Builder) {
if (state != 0 || !firstIsUnspecified) if (state != 0 || !firstIsUnspecified)
@ -329,14 +332,17 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
} }
} }
private open class UriSelectFilterShortPath(displayName: String, val uriParam: String, val vals: Array<Pair<String, String>>, private open class UriSelectFilterShortPath(
val firstIsUnspecified: Boolean = true, displayName: String,
defaultValue: Int = 0) : val uriParam: String,
val vals: Array<Pair<String, String>>,
val firstIsUnspecified: Boolean = true,
defaultValue: Int = 0
) :
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter { Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter {
override fun addToUri(uri: Uri.Builder) { override fun addToUri(uri: Uri.Builder) {
if (state != 0 || !firstIsUnspecified) if (state != 0 || !firstIsUnspecified)
uri.appendPath(vals[state].first) uri.appendPath(vals[state].first)
} }
} }
@ -346,6 +352,4 @@ open class MyReadingManga(override val lang: String) : ParsedHttpSource() {
private interface UriFilter { private interface UriFilter {
fun addToUri(uri: Uri.Builder) fun addToUri(uri: Uri.Builder)
} }
} }

View File

@ -4,9 +4,8 @@ package eu.kanade.tachiyomi.extension.all.myreadingmanga
* MyReadingManga languages * MyReadingManga languages
*/ */
class MyReadingMangaEnglish : MyReadingManga("en") class MyReadingMangaEnglish : MyReadingManga("en")
fun getAllMyReadingMangaLanguages() = listOf( fun getAllMyReadingMangaLanguages() = listOf(
MyReadingMangaEnglish() MyReadingMangaEnglish()
) )

View File

@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.extension.all.nhentai package eu.kanade.tachiyomi.extension.all.nhentai
import java.text.SimpleDateFormat
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
object NHUtils { object NHUtils {
fun getArtists(document: Document): String { fun getArtists(document: Document): String {

View File

@ -53,7 +53,7 @@ open class NHentai(
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
private var displayFullTitle: Boolean = when(preferences.getString(TITLE_PREF, "full")){ private var displayFullTitle: Boolean = when (preferences.getString(TITLE_PREF, "full")) {
"full" -> true "full" -> true
else -> false else -> false
} }
@ -67,7 +67,7 @@ open class NHentai(
summary = "%s" summary = "%s"
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
displayFullTitle = when(newValue){ displayFullTitle = when (newValue) {
"full" -> true "full" -> true
else -> false else -> false
} }
@ -75,7 +75,7 @@ open class NHentai(
} }
} }
if(!preferences.contains(TITLE_PREF)) if (!preferences.contains(TITLE_PREF))
preferences.edit().putString(TITLE_PREF, "full").apply() preferences.edit().putString(TITLE_PREF, "full").apply()
screen.addPreference(serverPref) screen.addPreference(serverPref)
@ -90,7 +90,7 @@ open class NHentai(
summary = "%s" summary = "%s"
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
displayFullTitle = when(newValue){ displayFullTitle = when (newValue) {
"full" -> true "full" -> true
else -> false else -> false
} }
@ -98,7 +98,7 @@ open class NHentai(
} }
} }
if(!preferences.contains(TITLE_PREF)) if (!preferences.contains(TITLE_PREF))
preferences.edit().putString(TITLE_PREF, "full").apply() preferences.edit().putString(TITLE_PREF, "full").apply()
screen.addPreference(serverPref) screen.addPreference(serverPref)
@ -259,5 +259,4 @@ open class NHentai(
const val PREFIX_ID_SEARCH = "id:" const val PREFIX_ID_SEARCH = "id:"
private const val TITLE_PREF = "Display manga title as:" private const val TITLE_PREF = "Display manga title as:"
} }
} }

View File

@ -3,30 +3,29 @@ package eu.kanade.tachiyomi.extension.all.ninehentai
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
data class Manga( data class Manga(
val id : Int, val id: Int,
var title: String, var title: String,
val image_server: String, val image_server: String,
val tags: List<Tag>, val tags: List<Tag>,
val total_page: Int val total_page: Int
) )
class Tag( class Tag(
val id: Int, val id: Int,
name: String, name: String,
val description: String = "null", val description: String = "null",
val type: Int = 1 val type: Int = 1
): Filter.TriState(name) ) : Filter.TriState(name)
data class SearchRequest( data class SearchRequest(
val text: String, val text: String,
val page: Int, val page: Int,
val sort: Int, val sort: Int,
val pages: Map<String, IntArray> = mapOf("range" to intArrayOf(0, 2000)), val pages: Map<String, IntArray> = mapOf("range" to intArrayOf(0, 2000)),
val tag: Map<String, Items> val tag: Map<String, Items>
) )
data class Items( data class Items(
val included: MutableList<Tag>, val included: MutableList<Tag>,
val excluded: MutableList<Tag> val excluded: MutableList<Tag>
) )

View File

@ -1520,5 +1520,4 @@ object NHTags {
Tag(id = 21354, name = "Zinkurou"), Tag(id = 21354, name = "Zinkurou"),
Tag(id = 290, name = "Zombie") Tag(id = 290, name = "Zombie")
) )
}
}

View File

@ -9,13 +9,22 @@ import com.google.gson.JsonElement
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.* import java.util.Date
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
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.util.*
open class NineHentai : ParsedHttpSource() { open class NineHentai : ParsedHttpSource() {
@ -92,25 +101,25 @@ open class NineHentai : ParsedHttpSource() {
val chapterId = manga.url.substringAfter("/g/").toInt() val chapterId = manga.url.substringAfter("/g/").toInt()
chapter.url = "/g/$chapterId" chapter.url = "/g/$chapterId"
chapter.name = "chapter" chapter.name = "chapter"
//api doesnt return date so setting to current date for now // api doesnt return date so setting to current date for now
chapter.date_upload = Date().time chapter.date_upload = Date().time
return Observable.just(listOf(chapter)) return Observable.just(listOf(chapter))
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val includedTags = mutableListOf<Tag>() val includedTags = mutableListOf<Tag>()
val excludedTags = mutableListOf<Tag>() val excludedTags = mutableListOf<Tag>()
var sort = 0 var sort = 0
for (filter in if (filters.isEmpty()) getFilterList() else filters) { for (filter in if (filters.isEmpty()) getFilterList() else filters) {
when(filter){ when (filter) {
is GenreList -> { is GenreList -> {
filter.state.forEach { f -> filter.state.forEach { f ->
if (!f.isIgnored()) { if (!f.isIgnored()) {
if (f.isExcluded()) if (f.isExcluded())
excludedTags.add(f) excludedTags.add(f)
else else
includedTags.add(f) includedTags.add(f)
} }
} }
} }
@ -153,7 +162,7 @@ open class NineHentai : ParsedHttpSource() {
} }
private fun buildRequestBody(searchText: String = "", page: Int, sort: Int = 0, includedTags: MutableList<Tag> = arrayListOf(), excludedTags: MutableList<Tag> = arrayListOf()): RequestBody { private fun buildRequestBody(searchText: String = "", page: Int, sort: Int = 0, includedTags: MutableList<Tag> = arrayListOf(), excludedTags: MutableList<Tag> = arrayListOf()): RequestBody {
val json = gson.toJson(mapOf("search" to SearchRequest(text = searchText, page = page-1, sort = sort, tag = mapOf("items" to Items(includedTags, excludedTags))))) val json = gson.toJson(mapOf("search" to SearchRequest(text = searchText, page = page - 1, sort = sort, tag = mapOf("items" to Items(includedTags, excludedTags)))))
return RequestBody.create(MEDIA_TYPE, json) return RequestBody.create(MEDIA_TYPE, json)
} }

View File

@ -7,14 +7,14 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
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.Locale import java.util.Locale
import okhttp3.HttpUrl
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
open class NineManga(override val name: String, override val baseUrl: String, override val lang: String) : ParsedHttpSource() { open class NineManga(override val name: String, override val baseUrl: String, override val lang: String) : ParsedHttpSource() {

View File

@ -4,13 +4,13 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Headers
import okhttp3.Request
import org.jsoup.nodes.Element
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.Locale import java.util.Locale
import okhttp3.Headers
import okhttp3.Request
import org.jsoup.nodes.Element
class NineMangaFactory : SourceFactory { class NineMangaFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(
@ -27,7 +27,7 @@ class NineMangaFactory : SourceFactory {
class NineMangaEn : NineManga("NineMangaEn", "http://en.ninemanga.com", "en") { class NineMangaEn : NineManga("NineMangaEn", "http://en.ninemanga.com", "en") {
override fun latestUpdatesFromElement(element: Element) = SManga.create().apply { override fun latestUpdatesFromElement(element: Element) = SManga.create().apply {
element.select("a.bookname").let { element.select("a.bookname").let {
url = it.attr("abs:href").replace("www","en").substringAfter(baseUrl) url = it.attr("abs:href").replace("www", "en").substringAfter(baseUrl)
title = it.text() title = it.text()
} }
thumbnail_url = element.select("img").attr("abs:src") thumbnail_url = element.select("img").attr("abs:src")
@ -772,7 +772,7 @@ fun parseChapterDateByLang(date: String): Long {
"minutos" -> Calendar.MINUTE // ES "minutos" -> Calendar.MINUTE // ES
"horas" -> Calendar.HOUR "horas" -> Calendar.HOUR
//"minutos" -> Calendar.MINUTE // BR // "minutos" -> Calendar.MINUTE // BR
"hora" -> Calendar.HOUR "hora" -> Calendar.HOUR
"минут" -> Calendar.MINUTE // RU "минут" -> Calendar.MINUTE // RU

View File

@ -1,13 +1,17 @@
package eu.kanade.tachiyomi.extension.all.noisemanga package eu.kanade.tachiyomi.extension.all.noisemanga
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.* import okhttp3.Headers
import okhttp3.Request
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.lang.Exception
abstract class NoiseManga(override val lang: String) : ParsedHttpSource() { abstract class NoiseManga(override val lang: String) : ParsedHttpSource() {
@ -90,7 +94,7 @@ abstract class NoiseManga(override val lang: String) : ParsedHttpSource() {
.substringAfterLast(", ") .substringAfterLast(", ")
.substringBeforeLast(" ") .substringBeforeLast(" ")
} }
.mapIndexed { i, imgUrl -> Page(i, "", imgUrl)} .mapIndexed { i, imgUrl -> Page(i, "", imgUrl) }
} }
override fun imageUrlParse(document: Document) = "" override fun imageUrlParse(document: Document) = ""

View File

@ -11,4 +11,4 @@ class NoiseMangaFactory : SourceFactory {
} }
class NoiseMangaEnglish : NoiseManga("en") class NoiseMangaEnglish : NoiseManga("en")
class NoiseMangaPortuguese: NoiseManga("pt") class NoiseMangaPortuguese : NoiseManga("pt")

View File

@ -7,7 +7,11 @@ import com.github.salomonbrys.kotson.string
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonObject import com.google.gson.JsonObject
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -16,8 +20,7 @@ import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
abstract class SimplyHentai(
abstract class SimplyHentai (
override val lang: String, override val lang: String,
private val urlLang: String, private val urlLang: String,
private val searchLang: String private val searchLang: String
@ -158,7 +161,7 @@ abstract class SimplyHentai (
// Filters // Filters
private class SortOrder(sortPairs: List<Pair<String, String>>): Filter.Select<String>("Sort By", sortPairs.map { it.first }.toTypedArray()) private class SortOrder(sortPairs: List<Pair<String, String>>) : Filter.Select<String>("Sort By", sortPairs.map { it.first }.toTypedArray())
private class SearchPair(name: String, val id: String = name) : Filter.CheckBox(name) private class SearchPair(name: String, val id: String = name) : Filter.CheckBox(name)
private class GenreList(searchVal: List<SearchPair>) : Filter.Group<SearchPair>("Genres", searchVal) private class GenreList(searchVal: List<SearchPair>) : Filter.Group<SearchPair>("Genres", searchVal)
private class SeriesList(searchVal: List<SearchPair>) : Filter.Group<SearchPair>("Series", searchVal) private class SeriesList(searchVal: List<SearchPair>) : Filter.Group<SearchPair>("Series", searchVal)

View File

@ -17,13 +17,12 @@ class SimplyHentaiFactory : SourceFactory {
) )
} }
class SimplyHentaiEN: SimplyHentai("en", "english", "1") class SimplyHentaiEN : SimplyHentai("en", "english", "1")
class SimplyHentaiJA: SimplyHentai("ja", "japanese", "2") class SimplyHentaiJA : SimplyHentai("ja", "japanese", "2")
class SimplyHentaiZH: SimplyHentai("zh", "chinese", "11") class SimplyHentaiZH : SimplyHentai("zh", "chinese", "11")
class SimplyHentaiKO: SimplyHentai("ko", "korean", "9") class SimplyHentaiKO : SimplyHentai("ko", "korean", "9")
class SimplyHentaiES: SimplyHentai("es", "spanish", "8") class SimplyHentaiES : SimplyHentai("es", "spanish", "8")
class SimplyHentaiRU: SimplyHentai("ru", "russian", "7") class SimplyHentaiRU : SimplyHentai("ru", "russian", "7")
class SimplyHentaiFR: SimplyHentai("fr", "french", "3") class SimplyHentaiFR : SimplyHentai("fr", "french", "3")
class SimplyHentaiDE: SimplyHentai("de", "german", "4") class SimplyHentaiDE : SimplyHentai("de", "german", "4")
class SimplyHentaiPT: SimplyHentai("pt", "portuguese", "6") class SimplyHentaiPT : SimplyHentai("pt", "portuguese", "6")

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.extension.all.toomics
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.Locale
class ToomicsFactory : SourceFactory { class ToomicsFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(

View File

@ -2,24 +2,29 @@ package eu.kanade.tachiyomi.extension.all.toomics
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Headers
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import java.net.URLDecoder import java.net.URLDecoder
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
abstract class ToomicsGlobal(private val siteLang: String, abstract class ToomicsGlobal(
private val dateFormat: SimpleDateFormat, private val siteLang: String,
override val lang: String = siteLang, private val dateFormat: SimpleDateFormat,
displayName: String = "") : ParsedHttpSource() { override val lang: String = siteLang,
displayName: String = ""
) : ParsedHttpSource() {
override val name = "Toomics (Only free chapters)" + (if (displayName.isNotEmpty()) " ($displayName)" else "") override val name = "Toomics (Only free chapters)" + (if (displayName.isNotEmpty()) " ($displayName)" else "")
@ -133,7 +138,7 @@ abstract class ToomicsGlobal(private val siteLang: String,
val url = document.select("head meta[property='og:url']").attr("content") val url = document.select("head meta[property='og:url']").attr("content")
return document.select("div[id^=load_image_] img") return document.select("div[id^=load_image_] img")
.mapIndexed { i, el -> Page(i, url, el.attr("abs:data-original"))} .mapIndexed { i, el -> Page(i, url, el.attr("abs:data-original")) }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
@ -146,7 +151,7 @@ abstract class ToomicsGlobal(private val siteLang: String,
return GET(page.imageUrl!!, newHeaders) return GET(page.imageUrl!!, newHeaders)
} }
private fun parseChapterDate(date: String) : Long { private fun parseChapterDate(date: String): Long {
return try { return try {
dateFormat.parse(date).time dateFormat.parse(date).time
} catch (e: ParseException) { } catch (e: ParseException) {

View File

@ -5,15 +5,15 @@ import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.Headers import okhttp3.Headers
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class DongmanManhua: WebtoonsDefault("zh", "") { class DongmanManhua : WebtoonsDefault("zh", "") {
override val baseUrl = "https://www.dongmanmanhua.cn" override val baseUrl = "https://www.dongmanmanhua.cn"
override val name = "Dongman Manhua" override val name = "Dongman Manhua"

View File

@ -1,13 +1,20 @@
package eu.kanade.tachiyomi.extension.all.webtoons package eu.kanade.tachiyomi.extension.all.webtoons
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.* import java.util.Calendar
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.Calendar
abstract class Webtoons( abstract class Webtoons(
override val lang: String, override val lang: String,
@ -36,7 +43,6 @@ abstract class Webtoons(
.build() .build()
) )
} }
}) })
.build() .build()
@ -82,7 +88,7 @@ abstract class Webtoons(
} }
// Process each row // Process each row
for (i in 1 .. maxChild) { for (i in 1..maxChild) {
document.select("div#dailyList > div li:nth-child($i) a").map { mangas.add(popularMangaFromElement(it)) } document.select("div#dailyList > div li:nth-child($i) a").map { mangas.add(popularMangaFromElement(it)) }
} }
@ -104,9 +110,9 @@ abstract class Webtoons(
return manga return manga
} }
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element) override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun popularMangaNextPageSelector() : String? = null override fun popularMangaNextPageSelector(): String? = null
override fun latestUpdatesNextPageSelector(): String? = null override fun latestUpdatesNextPageSelector(): String? = null
@ -166,5 +172,4 @@ abstract class Webtoons(
} }
override fun imageUrlParse(document: Document): String = document.select("img").first().attr("src") override fun imageUrlParse(document: Document): String = document.select("img").first().attr("src")
} }

View File

@ -4,10 +4,10 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import java.text.SimpleDateFormat
import java.util.Locale
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.*
open class WebtoonsDefault( open class WebtoonsDefault(
override val lang: String, override val lang: String,

View File

@ -51,7 +51,7 @@ class WebtoonsFactory : SourceFactory {
class WebtoonsEnglish : WebtoonsDefault("en") class WebtoonsEnglish : WebtoonsDefault("en")
class WebtoonsIndonesian: WebtoonsDefault("in", "id") { class WebtoonsIndonesian : WebtoonsDefault("in", "id") {
override val name: String = "Webtoons.com (Indonesian)" override val name: String = "Webtoons.com (Indonesian)"
// Android seems to be unable to parse Indonesian dates; we'll use a short hard-coded table // Android seems to be unable to parse Indonesian dates; we'll use a short hard-coded table
@ -67,13 +67,13 @@ class WebtoonsIndonesian: WebtoonsDefault("in", "id") {
} }
} }
class WebtoonsThai: WebtoonsDefault("th") { class WebtoonsThai : WebtoonsDefault("th") {
override fun chapterParseDate(date: String): Long { override fun chapterParseDate(date: String): Long {
return SimpleDateFormat("d MMM yyyy", Locale("th")).parse(date).time return SimpleDateFormat("d MMM yyyy", Locale("th")).parse(date).time
} }
} }
class WebtoonsChineseTraditional: WebtoonsDefault("zh", "zh-hant", "zh_TW") { class WebtoonsChineseTraditional : WebtoonsDefault("zh", "zh-hant", "zh_TW") {
override fun chapterParseDate(date: String): Long { override fun chapterParseDate(date: String): Long {
return SimpleDateFormat("yyyy/MM/dd", Locale.TRADITIONAL_CHINESE).parse(date).time return SimpleDateFormat("yyyy/MM/dd", Locale.TRADITIONAL_CHINESE).parse(date).time
} }

View File

@ -2,7 +2,12 @@ package eu.kanade.tachiyomi.extension.all.webtoons
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import java.util.ArrayList
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.Request import okhttp3.Request
@ -10,7 +15,6 @@ import okhttp3.Response
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.*
import rx.Observable import rx.Observable
open class WebtoonsTranslate(override val lang: String, private val translateLangCode: String, languageNameExtra: String = "") : Webtoons(lang) { open class WebtoonsTranslate(override val lang: String, private val translateLangCode: String, languageNameExtra: String = "") : Webtoons(lang) {
@ -218,5 +222,4 @@ open class WebtoonsTranslate(override val lang: String, private val translateLan
} }
return ret return ret
} }
} }

View File

@ -1,15 +1,18 @@
package eu.kanade.tachiyomi.extension.all.wpcomics package eu.kanade.tachiyomi.extension.all.wpcomics
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.Calendar
abstract class WPComics( abstract class WPComics(
override val name: String, override val name: String,
@ -40,7 +43,6 @@ abstract class WPComics(
setUrlWithoutDomain(it.attr("abs:href")) setUrlWithoutDomain(it.attr("abs:href"))
} }
thumbnail_url = imageOrNull(element.select("div.image:first-of-type img").first()) thumbnail_url = imageOrNull(element.select("div.image:first-of-type img").first())
} }
} }
@ -169,7 +171,7 @@ abstract class WPComics(
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
return document.select(pageListSelector).mapNotNull { img -> imageOrNull(img) } return document.select(pageListSelector).mapNotNull { img -> imageOrNull(img) }
.distinct() .distinct()
.mapIndexed { i, image -> Page(i, "", image)} .mapIndexed { i, image -> Page(i, "", image) }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")

View File

@ -6,10 +6,10 @@ import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Request
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import okhttp3.Request
import org.jsoup.nodes.Element
class WPComicsFactory : SourceFactory { class WPComicsFactory : SourceFactory {
override fun createSources(): List<Source> = listOf( override fun createSources(): List<Source> = listOf(

View File

@ -8,8 +8,16 @@ import android.support.v7.preference.PreferenceScreen
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -18,11 +26,6 @@ import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.lang.UnsupportedOperationException
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.Calendar
import java.util.concurrent.TimeUnit
abstract class WPMangaStream( abstract class WPMangaStream(
override val name: String, override val name: String,
@ -88,7 +91,6 @@ abstract class WPMangaStream(
.addNetworkInterceptor(rateLimitInterceptor) .addNetworkInterceptor(rateLimitInterceptor)
.build() .build()
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/manga/page/$page/?order=popular", headers) return GET("$baseUrl/manga/page/$page/?order=popular", headers)
} }
@ -159,8 +161,8 @@ abstract class WPMangaStream(
val infoElement = document.select("div.spe").first() val infoElement = document.select("div.spe").first()
val sepName = infoElement.select(".spe > span:contains(Author)").last() val sepName = infoElement.select(".spe > span:contains(Author)").last()
val manga = SManga.create() val manga = SManga.create()
manga.author = sepName?.ownText() ?:"N/A" manga.author = sepName?.ownText() ?: "N/A"
manga.artist = sepName?.ownText() ?:"N/A" manga.artist = sepName?.ownText() ?: "N/A"
manga.genre = infoElement.select(".spe > span:nth-child(1) > a").joinToString { it.text() } manga.genre = infoElement.select(".spe > span:nth-child(1) > a").joinToString { it.text() }
manga.status = parseStatus(infoElement.select(".spe > span:nth-child(2)").text()) manga.status = parseStatus(infoElement.select(".spe > span:nth-child(2)").text())
manga.description = document.select(".infox > div.desc").first().select("p").text() manga.description = document.select(".infox > div.desc").first().select("p").text()

View File

@ -5,13 +5,17 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.Interceptor
import okhttp3.HttpUrl
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
@ -801,7 +805,7 @@ class MaidManga : WPMangaStream("Maid Manga (WP Manga Stream)", "https://www.mai
} }
class MangaSwat : WPMangaStream("MangaSwat", "https://mangaswat.com", "ar") { class MangaSwat : WPMangaStream("MangaSwat", "https://mangaswat.com", "ar") {
private class Sucuri: Interceptor { private class Sucuri : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request() val originalRequest = chain.request()
val response = chain.proceed(originalRequest) val response = chain.proceed(originalRequest)
@ -825,15 +829,15 @@ class MangaSwat : WPMangaStream("MangaSwat", "https://mangaswat.com", "ar") {
description = document.select("div[itemprop=articleBody]").text() description = document.select("div[itemprop=articleBody]").text()
} }
override fun pageListRequest(chapter: SChapter): Request { override fun pageListRequest(chapter: SChapter): Request {
return GET(baseUrl + chapter.url + "?/", headers) //Bypass "linkvertise" ads return GET(baseUrl + chapter.url + "?/", headers) // Bypass "linkvertise" ads
} }
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply { override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
document.select("div#readerarea img[data-src]").forEachIndexed { index, element -> document.select("div#readerarea img[data-src]").forEachIndexed { index, element ->
add(Page(index,"",element.attr("data-src"))) add(Page(index, "", element.attr("data-src")))
} }
} }
override fun imageRequest(page: Page): Request { override fun imageRequest(page: Page): Request {
return GET( page.imageUrl!! , headers) return GET(page.imageUrl!!, headers)
} }
} }
@ -851,8 +855,8 @@ class MangaRaw : WPMangaStream("Manga Raw", "https://mangaraw.org", "ja") {
} }
override fun popularMangaNextPageSelector() = "a[rel=next]" override fun popularMangaNextPageSelector() = "a[rel=next]"
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/search?order=update&page=$page", headers) override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/search?order=update&page=$page", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request =
= GET("$baseUrl/search?s=$query&page=$page") GET("$baseUrl/search?s=$query&page=$page")
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> { override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return client.newCall(pageListRequest(chapter)) return client.newCall(pageListRequest(chapter))

View File

@ -128,7 +128,7 @@ class MangaAe : ParsedHttpSource() {
element.select("a").let { element.select("a").let {
// use full pages for easier links // use full pages for easier links
chapter.setUrlWithoutDomain(it.attr("href").removeSuffix("/1/") + "/0/full") chapter.setUrlWithoutDomain(it.attr("href").removeSuffix("/1/") + "/0/full")
chapter.name = "\u061C" + it.text() //Add unicode ARABIC LETTER MARK to ensure all titles are right to left chapter.name = "\u061C" + it.text() // Add unicode ARABIC LETTER MARK to ensure all titles are right to left
} }
return chapter return chapter
} }
@ -160,5 +160,4 @@ class MangaAe : ParsedHttpSource() {
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(
OrderByFilter() OrderByFilter()
) )
} }

View File

@ -1,7 +1,10 @@
package eu.kanade.tachiyomi.extension.ar.mangalink package eu.kanade.tachiyomi.extension.ar.mangalink
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -99,5 +102,4 @@ class MangaLink : ParsedHttpSource() {
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun getFilterList() = FilterList() override fun getFilterList() = FilterList()
} }

View File

@ -1,7 +1,11 @@
package eu.kanade.tachiyomi.extension.ar.shqqaa package eu.kanade.tachiyomi.extension.ar.shqqaa
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -116,5 +120,4 @@ class Shqqaa : ParsedHttpSource() {
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun getFilterList() = FilterList() override fun getFilterList() = FilterList()
} }

View File

@ -1,15 +1,19 @@
package eu.kanade.tachiyomi.extension.ar.teamx package eu.kanade.tachiyomi.extension.ar.teamx
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.concurrent.TimeUnit
class TeamX : ParsedHttpSource() { class TeamX : ParsedHttpSource() {
@ -132,5 +136,4 @@ class TeamX : ParsedHttpSource() {
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun getFilterList() = FilterList() override fun getFilterList() = FilterList()
} }

View File

@ -8,17 +8,24 @@ import com.google.gson.JsonObject
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.*
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.lang.Exception
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import rx.Observable
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
class MangaTube : ParsedHttpSource() { class MangaTube : ParsedHttpSource() {

View File

@ -6,13 +6,13 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.Headers import okhttp3.Headers
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class WieManga : ParsedHttpSource() { class WieManga : ParsedHttpSource() {
@ -134,5 +134,4 @@ class WieManga : ParsedHttpSource() {
override fun imageUrlParse(document: Document): String { override fun imageUrlParse(document: Document): String {
return document.select("img#comicpic").first().attr("abs:src") return document.select("img#comicpic").first().attr("abs:src")
} }
} }

View File

@ -9,7 +9,11 @@ import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -46,7 +50,6 @@ class BoredomSociety : ParsedHttpSource() {
} }
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val jsonArray = getJsonArray(response) val jsonArray = getJsonArray(response)
val list = parseData(jsonArray.toList()) val list = parseData(jsonArray.toList())
@ -95,10 +98,10 @@ class BoredomSociety : ParsedHttpSource() {
val chapterName = mutableListOf<String>() val chapterName = mutableListOf<String>()
if (!jsonElement["chapter_name"].string.startsWith("Chapter", true)) { if (!jsonElement["chapter_name"].string.startsWith("Chapter", true)) {
if (jsonElement["chapter_volume"].string?.isNotBlank()) { if (jsonElement["chapter_volume"].string.isNotBlank()) {
chapterName.add("Vol. " + jsonElement["chapter_volume"].string) chapterName.add("Vol. " + jsonElement["chapter_volume"].string)
} }
if (jsonElement["chapter_number"].string?.isNotBlank()) { if (jsonElement["chapter_number"].string.isNotBlank()) {
chapterName.add("Ch. " + jsonElement["chapter_number"].string + " - ") chapterName.add("Ch. " + jsonElement["chapter_number"].string + " - ")
} }
} }
@ -152,7 +155,6 @@ class BoredomSociety : ParsedHttpSource() {
return mutableChapters return mutableChapters
} }
override fun pageListParse(document: Document) = throw Exception("Not used") override fun pageListParse(document: Document) = throw Exception("Not used")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
@ -208,5 +210,4 @@ class BoredomSociety : ParsedHttpSource() {
private const val ALL_URL = "/api/titles/" private const val ALL_URL = "/api/titles/"
private const val CHAPTER_URL = "/api/chapter/" private const val CHAPTER_URL = "/api/chapter/"
} }
} }

View File

@ -1,8 +1,11 @@
package eu.kanade.tachiyomi.extension.en.clonemanga package eu.kanade.tachiyomi.extension.en.clonemanga
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request import okhttp3.Request
@ -11,7 +14,6 @@ import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
class CloneManga : ParsedHttpSource() { class CloneManga : ParsedHttpSource() {
override val name = "Clone Manga" override val name = "Clone Manga"
@ -66,7 +68,7 @@ class CloneManga : ParsedHttpSource() {
.toInt() .toInt()
val chapters = ArrayList<SChapter>() val chapters = ArrayList<SChapter>()
for(i in 1..numChapters) { for (i in 1..numChapters) {
val chapter = SChapter.create().apply { val chapter = SChapter.create().apply {
url = "$series&page=$i" url = "$series&page=$i"
name = "Chapter $i" name = "Chapter $i"
@ -120,5 +122,4 @@ class CloneManga : ParsedHttpSource() {
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { throw Exception("Not used") } override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { throw Exception("Not used") }
override fun searchMangaSelector(): String { throw Exception("Not used") } override fun searchMangaSelector(): String { throw Exception("Not used") }
} }

View File

@ -7,15 +7,18 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.ArrayList
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.regex.Pattern
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern
class ComicExtra : ParsedHttpSource() { class ComicExtra : ParsedHttpSource() {
@ -162,4 +165,3 @@ class ComicExtra : ParsedHttpSource() {
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Unused method was called somehow!") override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Unused method was called somehow!")
} }

View File

@ -1,7 +1,11 @@
package eu.kanade.tachiyomi.extension.en.comicpunch package eu.kanade.tachiyomi.extension.en.comicpunch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -96,7 +100,7 @@ class Comicpunch : ParsedHttpSource() {
manga.author = details.select("div.field-label:contains(publisher:) + div a").text() manga.author = details.select("div.field-label:contains(publisher:) + div a").text()
manga.genre = details.select("div.field-label:contains(genres:) + div a").joinToString { it.text() } manga.genre = details.select("div.field-label:contains(genres:) + div a").joinToString { it.text() }
manga.description = details.select("div.field-type-text-with-summary:not(:has(ul.splash))").text().let { desc -> manga.description = details.select("div.field-type-text-with-summary:not(:has(ul.splash))").text().let { desc ->
if (desc.isNotEmpty()) desc else document.select("ul.splash li.summary").first()?.ownText() if (desc.isNotEmpty()) desc else document.select("ul.splash li.summary").first()?.ownText()
} }
manga.thumbnail_url = details.select("img").attr("abs:src") ?: document.select("li.pic img").attr("abs:src") manga.thumbnail_url = details.select("img").attr("abs:src") ?: document.select("li.pic img").attr("abs:src")
} }
@ -149,5 +153,4 @@ class Comicpunch : ParsedHttpSource() {
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun getFilterList() = FilterList() override fun getFilterList() = FilterList()
} }

View File

@ -4,7 +4,11 @@ import android.os.Build.VERSION
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.extension.BuildConfig
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat import java.text.SimpleDateFormat

View File

@ -24,5 +24,4 @@ class DynastyAnthologies : DynastyScans() {
parseDescription(document, manga) parseDescription(document, manga)
return manga return manga
} }
} }

View File

@ -5,12 +5,12 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.*
class DynastyChapters : DynastyScans() { class DynastyChapters : DynastyScans() {
override val name = "Dynasty-Chapters" override val name = "Dynasty-Chapters"
@ -96,5 +96,4 @@ class DynastyChapters : DynastyScans() {
override fun popularMangaParse(response: Response) = searchMangaParse(response) override fun popularMangaParse(response: Response) = searchMangaParse(response)
override fun latestUpdatesParse(response: Response) = searchMangaParse(response) override fun latestUpdatesParse(response: Response) = searchMangaParse(response)
}
}

View File

@ -72,5 +72,4 @@ class DynastyDoujins : DynastyScans() {
override fun imageUrlParse(document: Document): String { override fun imageUrlParse(document: Document): String {
return document.select("div.image img").attr("abs:src") return document.select("div.image img").attr("abs:src")
} }
} }

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.extension.en.dynasty
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
class DynastyFactory : SourceFactory { class DynastyFactory : SourceFactory {
override fun createSources(): List<Source> = getAllDynasty() override fun createSources(): List<Source> = getAllDynasty()
} }

View File

@ -24,5 +24,4 @@ class DynastyIssues : DynastyScans() {
parseDescription(document, manga) parseDescription(document, manga)
return manga return manga
} }
} }

View File

@ -8,6 +8,9 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat
import java.util.ArrayList
import java.util.Locale
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
@ -16,8 +19,6 @@ import org.jsoup.nodes.Element
import org.jsoup.nodes.Node import org.jsoup.nodes.Node
import org.jsoup.nodes.TextNode import org.jsoup.nodes.TextNode
import org.jsoup.select.Elements import org.jsoup.select.Elements
import java.text.SimpleDateFormat
import java.util.*
abstract class DynastyScans : ParsedHttpSource() { abstract class DynastyScans : ParsedHttpSource() {
@ -110,7 +111,6 @@ abstract class DynastyScans : ParsedHttpSource() {
} }
} }
protected fun parseDescription(document: Document, manga: SManga) { protected fun parseDescription(document: Document, manga: SManga) {
manga.description = document.select("div.tags > div.row div.description").text() manga.description = document.select("div.tags > div.row div.description").text()
} }
@ -228,5 +228,4 @@ abstract class DynastyScans : ParsedHttpSource() {
override fun latestUpdatesRequest(page: Int): Request { override fun latestUpdatesRequest(page: Int): Request {
return popularMangaRequest(page) return popularMangaRequest(page)
} }
} }

View File

@ -24,5 +24,4 @@ class DynastySeries : DynastyScans() {
parseDescription(document, manga) parseDescription(document, manga)
return manga return manga
} }
}
}