Fix Plot Twist no Fansub, Update LectorManga, TMOHentai and TMO (#4110)

* Fix Latest url

* Fix Kumanga error 400 bad request

* Add support to opening links from the website in main app

* TMO: Add support to opening links from the website in main app

* TMOHentai: Add support to opening links from the website in main app

* Revert "Fix Kumanga error 400 bad request"

* Complete Kumanga revert.

* Fix plot twist latest again

* Update LetorManga gradle
This commit is contained in:
Edgar Mejía 2020-08-27 01:20:30 -06:00 committed by GitHub
parent 6e5772ecfd
commit ddc9d8b10a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 271 additions and 6 deletions

View File

@ -142,7 +142,7 @@ class Kumanga : HttpSource() {
name = it.text() name = it.text()
date_upload = parseChapterDate(it.attr("title")) date_upload = parseChapterDate(it.attr("title"))
} }
scanlator = element.select("span.pull-right.greenSpan")?.text() scanlator = element.select("span.pull-right.greenSpan")?.text()
} }
override fun chapterListParse(response: Response): List<SChapter> = mutableListOf<SChapter>().apply { override fun chapterListParse(response: Response): List<SChapter> = mutableListOf<SChapter>().apply {

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name=".LectorMangaUrlActivity"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="lectormanga.com"
android:pathPattern="/gotobook/..*" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -5,7 +5,7 @@ ext {
extName = 'LectorManga' extName = 'LectorManga'
pkgNameSuffix = 'es.lectormanga' pkgNameSuffix = 'es.lectormanga'
extClass = '.LectorManga' extClass = '.LectorManga'
extVersionCode = 13 extVersionCode = 14
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -5,9 +5,11 @@ 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 eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter 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.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
@ -21,6 +23,7 @@ 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 uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -137,6 +140,7 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun mangaDetailsParse(document: Document) = SManga.create().apply { override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.select("h1:has(small)").text()
genre = document.select("a.py-2").joinToString(", ") { genre = document.select("a.py-2").joinToString(", ") {
it.text() it.text()
} }
@ -239,6 +243,28 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
override fun imageUrlParse(document: Document): String = document.select("img.viewer-image").attr("src") override fun imageUrlParse(document: Document): String = document.select("img.viewer-image").attr("src")
private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/$MANGA_URL_CHUNK/$id", headers)
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return if (query.startsWith(PREFIX_ID_SEARCH)) {
val realQuery = query.removePrefix(PREFIX_ID_SEARCH)
client.newCall(searchMangaByIdRequest(realQuery))
.asObservableSuccess()
.map { response ->
val details = mangaDetailsParse(response)
details.url = "/$MANGA_URL_CHUNK/$realQuery"
MangasPage(listOf(details), false)
}
} else {
client.newCall(searchMangaRequest(page, query, filters))
.asObservableSuccess()
.map { response ->
searchMangaParse(response)
}
}
}
private class Types : UriPartFilter("Filtrar por tipo", arrayOf( private class Types : UriPartFilter("Filtrar por tipo", arrayOf(
Pair("Ver todos", ""), Pair("Ver todos", ""),
Pair("Manga", "manga"), Pair("Manga", "manga"),
@ -443,6 +469,9 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
private const val PAGEGET_PREF_Title = "Método para la descarga de imágenes" private const val PAGEGET_PREF_Title = "Método para la descarga de imágenes"
private const val PAGEGET_PREF = "pagemethodpref" private const val PAGEGET_PREF = "pagemethodpref"
const val PREFIX_ID_SEARCH = "id:"
const val MANGA_URL_CHUNK = "gotobook"
private val SORTABLES = listOf( private val SORTABLES = listOf(
Pair("Me gusta", "likes_count"), Pair("Me gusta", "likes_count"),
Pair("Alfabético", "alphabetically"), Pair("Alfabético", "alphabetically"),

View File

@ -0,0 +1,39 @@
package eu.kanade.tachiyomi.extension.es.lectormanga
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.Log
import kotlin.system.exitProcess
/**
* Springboard that accepts https://lectormanga.com/gotobook/:id intents and redirects them to
* the main Tachiyomi process.
*/
class LectorMangaUrlActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pathSegments = intent?.data?.pathSegments
if (pathSegments != null && pathSegments.size > 1) {
val id = pathSegments[1]
val mainIntent = Intent().apply {
action = "eu.kanade.tachiyomi.SEARCH"
putExtra("query", "${LectorManga.PREFIX_ID_SEARCH}$id")
putExtra("filter", packageName)
}
try {
startActivity(mainIntent)
} catch (e: ActivityNotFoundException) {
Log.e("LectorMangaUrlActivity", e.toString())
}
} else {
Log.e("LectorMangaUrlActivity", "could not parse uri from intent $intent")
}
finish()
exitProcess(0)
}
}

View File

@ -5,7 +5,7 @@ ext {
extName = 'Plot Twist No Fansub' extName = 'Plot Twist No Fansub'
pkgNameSuffix = 'es.plottwistnofansub' pkgNameSuffix = 'es.plottwistnofansub'
extClass = '.PlotTwistNoFansub' extClass = '.PlotTwistNoFansub'
extVersionCode = 1 extVersionCode = 2
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -48,7 +48,7 @@ class PlotTwistNoFansub : ParsedHttpSource() {
override fun popularMangaNextPageSelector() = "div.page-nav a:has(i)" override fun popularMangaNextPageSelector() = "div.page-nav a:has(i)"
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/ulti/", headers) override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/", headers)
override fun latestUpdatesSelector() = "div.row.last-updates div.item" override fun latestUpdatesSelector() = "div.row.last-updates div.item"

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name=".TMOHentaiUrlActivity"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="tmohentai.com"
android:pathPattern="/contents/..*" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -5,7 +5,7 @@ ext {
extName = 'TMOHentai' extName = 'TMOHentai'
pkgNameSuffix = 'es.tmohentai' pkgNameSuffix = 'es.tmohentai'
extClass = '.TMOHentai' extClass = '.TMOHentai'
extVersionCode = 3 extVersionCode = 4
libVersion = '1.2' libVersion = '1.2'
containsNsfw = true containsNsfw = true
} }

View File

@ -2,8 +2,10 @@ package eu.kanade.tachiyomi.extension.es.tmohentai
import eu.kanade.tachiyomi.annotations.Nsfw import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.Filter 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.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
@ -12,6 +14,7 @@ import okhttp3.HttpUrl
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 rx.Observable
@Nsfw @Nsfw
class TMOHentai : ParsedHttpSource() { class TMOHentai : ParsedHttpSource() {
@ -50,6 +53,7 @@ class TMOHentai : ParsedHttpSource() {
val parsedInformation = document.select("div.row > div.panel.panel-primary").text() val parsedInformation = document.select("div.row > div.panel.panel-primary").text()
val authorAndArtist = parsedInformation.substringAfter("Groups").substringBefore("Magazines").trim() val authorAndArtist = parsedInformation.substringAfter("Groups").substringBefore("Magazines").trim()
title = document.select("h3.truncate").text()
thumbnail_url = document.select("img.content-thumbnail-cover").attr("src") thumbnail_url = document.select("img.content-thumbnail-cover").attr("src")
author = authorAndArtist author = authorAndArtist
artist = authorAndArtist artist = authorAndArtist
@ -121,6 +125,28 @@ class TMOHentai : ParsedHttpSource() {
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/$PREFIX_CONTENTS/$id", headers)
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return if (query.startsWith(PREFIX_ID_SEARCH)) {
val realQuery = query.removePrefix(PREFIX_ID_SEARCH)
client.newCall(searchMangaByIdRequest(realQuery))
.asObservableSuccess()
.map { response ->
val details = mangaDetailsParse(response)
details.url = "/$PREFIX_CONTENTS/$realQuery"
MangasPage(listOf(details), false)
}
} else {
client.newCall(searchMangaRequest(page, query, filters))
.asObservableSuccess()
.map { response ->
searchMangaParse(response)
}
}
}
private class Genre(name: String, val id: String) : Filter.CheckBox(name) private class Genre(name: String, val id: String) : Filter.CheckBox(name)
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Géneros", genres) private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Géneros", genres)
@ -214,6 +240,9 @@ class TMOHentai : ParsedHttpSource() {
) )
companion object { companion object {
const val PREFIX_CONTENTS = "contents"
const val PREFIX_ID_SEARCH = "id:"
private val SORTABLES = listOf( private val SORTABLES = listOf(
Pair("Alfabético", "alphabetic"), Pair("Alfabético", "alphabetic"),
Pair("Creación", "publication_date"), Pair("Creación", "publication_date"),

View File

@ -0,0 +1,40 @@
package eu.kanade.tachiyomi.extension.es.tmohentai
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.Log
import kotlin.system.exitProcess
/**
* Springboard that accepts https://tmohentai.com/contents/:id intents and redirects them to
* the main Tachiyomi process.
*/
class TMOHentaiUrlActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pathSegments = intent?.data?.pathSegments
if (pathSegments != null && pathSegments.size > 1) {
val id = pathSegments[1]
val mainIntent = Intent().apply {
action = "eu.kanade.tachiyomi.SEARCH"
putExtra("query", "${TMOHentai.PREFIX_ID_SEARCH}$id")
putExtra("filter", packageName)
}
try {
startActivity(mainIntent)
} catch (e: ActivityNotFoundException) {
Log.e("TMOHentaiUrlActivity", e.toString())
}
} else {
Log.e("TMOHentaiUrlActivity", "could not parse uri from intent $intent")
}
finish()
exitProcess(0)
}
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name=".TuMangaOnlineUrlActivity"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="lectortmo.com"
android:pathPattern="/library/..*/..*/..*" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -5,7 +5,7 @@ ext {
extName = 'TuMangaOnline' extName = 'TuMangaOnline'
pkgNameSuffix = 'es.tumangaonline' pkgNameSuffix = 'es.tumangaonline'
extClass = '.TuMangaOnline' extClass = '.TuMangaOnline'
extVersionCode = 28 extVersionCode = 29
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -5,9 +5,11 @@ 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 eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter 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.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
@ -21,6 +23,7 @@ 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 uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -138,6 +141,7 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun mangaDetailsParse(document: Document) = SManga.create().apply { override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.select("h2.element-subtitle").text()
document.select("h5.card-title").let { document.select("h5.card-title").let {
author = it?.first()?.attr("title")?.substringAfter(", ") author = it?.first()?.attr("title")?.substringAfter(", ")
artist = it?.last()?.attr("title")?.substringAfter(", ") artist = it?.last()?.attr("title")?.substringAfter(", ")
@ -251,6 +255,28 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
return document.select("div.viewer-container > div.img-container > img.viewer-image").attr("src") return document.select("div.viewer-container > div.img-container > img.viewer-image").attr("src")
} }
private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/$PREFIX_LIBRARY/$id", headers)
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return if (query.startsWith(PREFIX_ID_SEARCH)) {
val realQuery = query.removePrefix(PREFIX_ID_SEARCH)
client.newCall(searchMangaByIdRequest(realQuery))
.asObservableSuccess()
.map { response ->
val details = mangaDetailsParse(response)
details.url = "/$PREFIX_LIBRARY/$realQuery"
MangasPage(listOf(details), false)
}
} else {
client.newCall(searchMangaRequest(page, query, filters))
.asObservableSuccess()
.map { response ->
searchMangaParse(response)
}
}
}
private class Types : UriPartFilter("Filtrar por tipo", arrayOf( private class Types : UriPartFilter("Filtrar por tipo", arrayOf(
Pair("Ver todo", ""), Pair("Ver todo", ""),
Pair("Manga", "manga"), Pair("Manga", "manga"),
@ -453,6 +479,9 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
private const val PAGEGET_PREF_Title = "Método para la descarga de imágenes" private const val PAGEGET_PREF_Title = "Método para la descarga de imágenes"
private const val PAGEGET_PREF = "pagemethodpref" private const val PAGEGET_PREF = "pagemethodpref"
const val PREFIX_LIBRARY = "library"
const val PREFIX_ID_SEARCH = "id:"
private val SORTABLES = listOf( private val SORTABLES = listOf(
Pair("Me gusta", "likes_count"), Pair("Me gusta", "likes_count"),
Pair("Alfabético", "alphabetically"), Pair("Alfabético", "alphabetically"),

View File

@ -0,0 +1,42 @@
package eu.kanade.tachiyomi.extension.es.tumangaonline
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.Log
import kotlin.system.exitProcess
/**
* Springboard that accepts https://lectortmo.com/library/:type/:id/:slug intents and redirects them to
* the main Tachiyomi process.
*/
class TuMangaOnlineUrlActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pathSegments = intent?.data?.pathSegments
if (pathSegments != null && pathSegments.size > 3) {
val type = pathSegments[1]
val id = pathSegments[2]
val slug = pathSegments[3]
val mainIntent = Intent().apply {
action = "eu.kanade.tachiyomi.SEARCH"
putExtra("query", "${TuMangaOnline.PREFIX_ID_SEARCH}$type/$id/$slug")
putExtra("filter", packageName)
}
try {
startActivity(mainIntent)
} catch (e: ActivityNotFoundException) {
Log.e("TMOUrlActivity", e.toString())
}
} else {
Log.e("TMOUrlActivity", "could not parse uri from intent $intent")
}
finish()
exitProcess(0)
}
}