Manhwa latino: (#9848)
* First commit Mahnwa-Latino Extension. * manhwa-latino: Implementing find function TODO: only works with text, filter not implemented yet * manhwa-latino Add Parser to finde the information of Manhwa-Latino The parser 'ManhwaLatinoSiteParser.kt' make the whole magic to find the information of the Website. Mudularize The code and adding documentation * manhwa-latino: Adding Logos der Extension TODO: I am not to happy, i will check it later. * manhwa-latino: Adding Tags to Genre Combobox * manhwa-latino: Adding Headers to prevent error 404 The headers are necesary to prevent error 403 by downloading images. * manhwa-latino: Tags addded into Manga Description Page Status from Manga readed from Tags * manhwa-latino: Modularize Code * manhwa-latino: Adding Uploaddate for Chapters * manhwa-latino: Bug to get Chapter Number fixed * manhwa-latino: Logo 0.2 * manhwa-latino: Versionb 1.2.10 Adding Comments to ManhwaLatinoSiteParser * manhwa-latino: Remove logo_model directory * manhwa-latino: Show Seconds after Release a new Chapter * manhwa-latino: Fix for Cloudflare * manhwa-latino: Try to fix Cloudflare ByPass Adding isNsfw to build.gradle * manhwa-latino: Update from parser after website update * manhwa-latino: Deactivate lastest manga and new Client The new website from Manhwa-Latino doesnt show lastest mangas. * manhwa-latino: Adding Manifest to load url-adress The extesion will bi able to open and find mangas with the url. TODO: first version. NOT READY YET. * manhwa-latino: Fix to find Manga Status information * Manhwa-Latino: The Extension can open a Link Now the extension can recognize a link from Manhwa-Latino and show the manga from the link in the app. * Manhwa-Latino: Modularize Code and Activity for Url added * Manhwa-Latino: Add Constant-File. This file contain all contants for this extension. Co-authored-by: Luis Beroiza <luisalberto.beroizaosses@intern.osp-dd.de> Co-authored-by: AlberyKous <extreme_rvd@hotmail.com>
This commit is contained in:
		
							parent
							
								
									726813f019
								
							
						
					
					
						commit
						33088997db
					
				@ -1,2 +1,24 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest package="eu.kanade.tachiyomi.extension" />
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    package="eu.kanade.tachiyomi.extension">
 | 
			
		||||
 | 
			
		||||
    <application>
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".es.manhwalatino.ManhwaLatinoUrlActivity"
 | 
			
		||||
            android:excludeFromRecents="true"
 | 
			
		||||
            android:exported="true"
 | 
			
		||||
            android:theme="@android:style/Theme.NoDisplay">
 | 
			
		||||
            <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:host="manhwa-latino.com"
 | 
			
		||||
                    android:pathPattern="/..*/..*"
 | 
			
		||||
                    android:scheme="https" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
@ -5,8 +5,8 @@ ext {
 | 
			
		||||
    extName = 'Manhwa-Latino'
 | 
			
		||||
    pkgNameSuffix = 'es.manhwalatino'
 | 
			
		||||
    extClass = '.ManhwaLatino'
 | 
			
		||||
    extVersionCode = 11
 | 
			
		||||
    containsNsfw = true
 | 
			
		||||
    extVersionCode = 14
 | 
			
		||||
    isNsfw = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
apply from: "$rootDir/common.gradle"
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,39 @@
 | 
			
		||||
package eu.kanade.tachiyomi.extension.es.manhwalatino
 | 
			
		||||
 | 
			
		||||
object MLConstants {
 | 
			
		||||
 | 
			
		||||
    const val PREFIX_MANGA_ID_SEARCH = "id:"
 | 
			
		||||
 | 
			
		||||
    const val searchMangaNextPageSelector = "link[rel=next]"
 | 
			
		||||
    const val latestUpdatesSelector = "div.slider__item"
 | 
			
		||||
    const val searchMangaSelector = "div.page-item-detail.manga"
 | 
			
		||||
    const val popularMangaNextPageSelector = "a.nextpostslink"
 | 
			
		||||
    const val latestUpdatesNextPageSelector = "div[role=navigation] a.last"
 | 
			
		||||
 | 
			
		||||
    const val popularMangaSelector = "div.page-item-detail.manga"
 | 
			
		||||
    const val popularGenreTitleHTMLSelector: String = "div.item-summary div.post-title h3"
 | 
			
		||||
    const val popularGenreUrlHTMLSelector: String = "div.item-summary div.post-title h3 a"
 | 
			
		||||
    const val popularGenreThumbnailUrlMangaHTMLSelector: String = "div.item-thumb.c-image-hover img"
 | 
			
		||||
 | 
			
		||||
    const val searchPageTitleHTMLSelector: String = "div.tab-summary div.post-title h3"
 | 
			
		||||
    const val searchPageUrlHTMLSelector: String = "div.tab-summary div.post-title h3 a"
 | 
			
		||||
    const val searchPageThumbnailUrlMangaHTMLSelector: String = "div.tab-thumb.c-image-hover img"
 | 
			
		||||
 | 
			
		||||
    const val mangaDetailsThumbnailUrlHTMLSelector: String = "div.summary_image img"
 | 
			
		||||
    const val mangaDetailsAuthorHTMLSelector: String = "div.author-content"
 | 
			
		||||
    const val mangaDetailsArtistHTMLSelector: String = "div.artist-content"
 | 
			
		||||
    const val mangaDetailsDescriptionHTMLSelector: String = "div.post-content_item > div > p"
 | 
			
		||||
    const val mangaDetailsGenreHTMLSelector: String = "div.genres-content a"
 | 
			
		||||
    const val mangaDetailsTagsHTMLSelector: String = "div.tags-content a"
 | 
			
		||||
    const val mangaDetailsAttributes: String = "div.summary_content div.post-content_item"
 | 
			
		||||
    const val searchSiteMangasHTMLSelector = "div.c-tabs-item__content"
 | 
			
		||||
    const val genreSiteMangasHTMLSelector = "div.page-item-detail.manga"
 | 
			
		||||
    const val latestUpdatesSelectorUrl = "div.slider__thumb_item > a"
 | 
			
		||||
    const val latestUpdatesSelectorThumbnailUrl = "div.slider__thumb_item > a > img"
 | 
			
		||||
    const val latestUpdatesSelectorTitle = "div.slider__content h4"
 | 
			
		||||
    const val chapterListParseSelector = "li.wp-manga-chapter"
 | 
			
		||||
    const val chapterLinkParser = "a"
 | 
			
		||||
    const val chapterReleaseDateLinkParser = "span.chapter-release-date a"
 | 
			
		||||
    const val chapterReleaseDateIParser = "span.chapter-release-date i"
 | 
			
		||||
    const val pageListParseSelector = "div.page-break.no-gaps img"
 | 
			
		||||
}
 | 
			
		||||
@ -11,10 +11,12 @@ import eu.kanade.tachiyomi.source.model.SManga
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
 | 
			
		||||
import eu.kanade.tachiyomi.util.asJsoup
 | 
			
		||||
import okhttp3.Headers
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import org.jsoup.nodes.Document
 | 
			
		||||
import org.jsoup.nodes.Element
 | 
			
		||||
import rx.Observable
 | 
			
		||||
 | 
			
		||||
class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
 | 
			
		||||
@ -28,10 +30,20 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
     */
 | 
			
		||||
    override val baseUrl = "https://manhwa-latino.com"
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Header for Request
 | 
			
		||||
     */
 | 
			
		||||
    override fun headersBuilder() = Headers.Builder().add("Referer", "$baseUrl")
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Http Client
 | 
			
		||||
     */
 | 
			
		||||
    override val client: OkHttpClient = network.client.newBuilder().build()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parser for Mainsite or Genre Site
 | 
			
		||||
     */
 | 
			
		||||
    val manhwaLatinoSiteParser = ManhwaLatinoSiteParser(baseUrl)
 | 
			
		||||
    val manhwaLatinoSiteParser = ManhwaLatinoSiteParser(baseUrl, client, headers)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An ISO 639-1 compliant language code (two letters in lower case).
 | 
			
		||||
@ -43,37 +55,25 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
     */
 | 
			
		||||
    override val supportsLatest = true
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * User Agent for this wWebsite
 | 
			
		||||
     */
 | 
			
		||||
    private val userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
 | 
			
		||||
        "(KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
 | 
			
		||||
 | 
			
		||||
    override fun headersBuilder(): Headers.Builder {
 | 
			
		||||
        return Headers.Builder()
 | 
			
		||||
            .add("User-Agent", userAgent)
 | 
			
		||||
            .add("Referer", "$baseUrl/")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the Jsoup selector that returns a list of [Element] corresponding to each manga.
 | 
			
		||||
     */
 | 
			
		||||
    override fun popularMangaSelector(): String {
 | 
			
		||||
        return manhwaLatinoSiteParser.popularMangaSelector
 | 
			
		||||
        return MLConstants.popularMangaSelector
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the Jsoup selector that returns a list of [Element] corresponding to each manga.
 | 
			
		||||
     */
 | 
			
		||||
    override fun latestUpdatesSelector(): String {
 | 
			
		||||
        return manhwaLatinoSiteParser.latestUpdatesSelector
 | 
			
		||||
        return MLConstants.latestUpdatesSelector
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the Jsoup selector that returns a list of [Element] corresponding to each manga.
 | 
			
		||||
     */
 | 
			
		||||
    override fun searchMangaSelector(): String {
 | 
			
		||||
        return manhwaLatinoSiteParser.searchMangaSelector
 | 
			
		||||
        return MLConstants.searchMangaSelector
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -87,7 +87,7 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
     * there's no next page.
 | 
			
		||||
     */
 | 
			
		||||
    override fun popularMangaNextPageSelector(): String {
 | 
			
		||||
        return manhwaLatinoSiteParser.popularMangaNextPageSelector
 | 
			
		||||
        return MLConstants.popularMangaNextPageSelector
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -95,7 +95,7 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
     * there's no next page.
 | 
			
		||||
     */
 | 
			
		||||
    override fun latestUpdatesNextPageSelector(): String {
 | 
			
		||||
        return manhwaLatinoSiteParser.latestUpdatesNextPageSelector
 | 
			
		||||
        return MLConstants.latestUpdatesNextPageSelector
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -103,7 +103,7 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
     * there's no next page.
 | 
			
		||||
     */
 | 
			
		||||
    override fun searchMangaNextPageSelector(): String {
 | 
			
		||||
        return manhwaLatinoSiteParser.searchMangaNextPageSelector
 | 
			
		||||
        return MLConstants.searchMangaNextPageSelector
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -157,6 +157,10 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
        return GET(uri.toString(), headers)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
 | 
			
		||||
        return manhwaLatinoSiteParser.fetchSearchManga(page, query, filters)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses the response from the site and returns a [MangasPage] object.
 | 
			
		||||
     *
 | 
			
		||||
@ -166,13 +170,13 @@ class ManhwaLatino : ParsedHttpSource() {
 | 
			
		||||
        return manhwaLatinoSiteParser.searchMangaParse(response)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    /**
 | 
			
		||||
//     * Returns the request for the details of a manga. Override only if it's needed to change the
 | 
			
		||||
//     * url, send different headers or request method like POST.
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param manga the manga to be updated.
 | 
			
		||||
//     */
 | 
			
		||||
//    override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url, headers)
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the request for the details of a manga. Override only if it's needed to change the
 | 
			
		||||
     * url, send different headers or request method like POST.
 | 
			
		||||
     *
 | 
			
		||||
     * @param manga the manga to be updated.
 | 
			
		||||
     */
 | 
			
		||||
    override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url, headers)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the request for updating the chapter list. Override only if it's needed to override
 | 
			
		||||
 | 
			
		||||
@ -2,62 +2,70 @@ package eu.kanade.tachiyomi.extension.es.manhwalatino
 | 
			
		||||
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import eu.kanade.tachiyomi.extension.es.manhwalatino.filters.UriFilter
 | 
			
		||||
import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import eu.kanade.tachiyomi.network.asObservableSuccess
 | 
			
		||||
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.util.asJsoup
 | 
			
		||||
import okhttp3.Headers
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import org.jsoup.nodes.Document
 | 
			
		||||
import org.jsoup.nodes.Element
 | 
			
		||||
import org.jsoup.select.Elements
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import java.text.SimpleDateFormat
 | 
			
		||||
import java.util.Calendar
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
 | 
			
		||||
class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
class ManhwaLatinoSiteParser(
 | 
			
		||||
    private val baseUrl: String,
 | 
			
		||||
    private val client: OkHttpClient,
 | 
			
		||||
    private val headers: Headers
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * TODO: ADD SEARCH_TAG
 | 
			
		||||
     * Search Type
 | 
			
		||||
     */
 | 
			
		||||
    enum class SearchType {
 | 
			
		||||
        SEARCH_FREE, SEARCH_FILTER
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Type of manga
 | 
			
		||||
     */
 | 
			
		||||
    enum class MangaType {
 | 
			
		||||
        ALL, ADULT, GAY;
 | 
			
		||||
 | 
			
		||||
        // Static Enum Function
 | 
			
		||||
        companion object {
 | 
			
		||||
            fun isForAdults(mangaTypes: List<MangaType>): Boolean {
 | 
			
		||||
                for (type in mangaTypes) {
 | 
			
		||||
                    when (type) {
 | 
			
		||||
                        ADULT, GAY -> return true
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return false
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // CSS Class to search in the title of the manga
 | 
			
		||||
        fun getBadge(): String {
 | 
			
		||||
            return when (this) {
 | 
			
		||||
                ADULT -> "adult"
 | 
			
		||||
                GAY -> "gay"
 | 
			
		||||
                ALL -> ""
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Type of search ( FREE, FILTER)
 | 
			
		||||
     */
 | 
			
		||||
    var searchType = SearchType.SEARCH_FREE
 | 
			
		||||
 | 
			
		||||
    private val urlHTMLSelector: String = "a"
 | 
			
		||||
    private val titleHTMLSelector: String = "h3"
 | 
			
		||||
    private val thumbnailUrlMangaListHTMLSelector: String = "div.item-thumb.c-image-hover img"
 | 
			
		||||
    private val authorHTMLSelector: String = "div.author-content"
 | 
			
		||||
    private val artistHTMLSelector: String = "div.artist-content"
 | 
			
		||||
    private val descriptionHTMLSelector: String = "div.summary__content.show-more p"
 | 
			
		||||
    private val genreHTMLSelector: String = "div.genres-content a"
 | 
			
		||||
    private val statusHTMLSelector: String =
 | 
			
		||||
        "div.summary_content div.post-status div.post-content_item div.summary-content"
 | 
			
		||||
    private val thumbnailUrlMangaDetailsHTMLSelector: String = "div.summary_image img"
 | 
			
		||||
    private val tagsHTMLSelector: String = "div.tags-content a"
 | 
			
		||||
    private val searchSiteMangasHTMLSelector = "div.c-tabs-item__content"
 | 
			
		||||
    private val genreSiteMangasHTMLSelector = "div.page-item-detail.manga"
 | 
			
		||||
    private val latestUpdatesSelectorUrl = "div.slider__thumb_item a"
 | 
			
		||||
    private val latestUpdatesSelectorThumbnailUrl = "div.slider__thumb_item a img"
 | 
			
		||||
    private val latestUpdatesSelectorTitle = "div.slider__content h4"
 | 
			
		||||
    private val chapterListParseSelector = "li.wp-manga-chapter"
 | 
			
		||||
    private val chapterLinkParser = "a"
 | 
			
		||||
    private val chapterReleaseDateLinkParser = "span.chapter-release-date a"
 | 
			
		||||
    private val chapterReleaseDateIParser = "span.chapter-release-date i"
 | 
			
		||||
    private val pageListParseSelector = "div.page-break.no-gaps img"
 | 
			
		||||
 | 
			
		||||
    val searchMangaNextPageSelector = "link[rel=next]"
 | 
			
		||||
    val latestUpdatesSelector = "div.slider__item"
 | 
			
		||||
 | 
			
		||||
    val popularMangaSelector = "div.page-item-detail.manga"
 | 
			
		||||
    val searchMangaSelector = "div.page-item-detail.manga"
 | 
			
		||||
    val popularMangaNextPageSelector = "a.nextpostslink"
 | 
			
		||||
    val latestUpdatesNextPageSelector = "div[role=navigation] a.last"
 | 
			
		||||
    private var searchType = SearchType.SEARCH_FREE
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Latest Updates are in a Slider, this Methods get a Manga from the slide
 | 
			
		||||
@ -65,9 +73,9 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
    fun getMangaFromLastTranslatedSlide(element: Element): SManga {
 | 
			
		||||
        val manga = SManga.create()
 | 
			
		||||
        manga.url =
 | 
			
		||||
            getUrlWithoutDomain(element.select(latestUpdatesSelectorUrl).first().attr("abs:href"))
 | 
			
		||||
        manga.title = element.select(latestUpdatesSelectorTitle).text().trim()
 | 
			
		||||
        manga.thumbnail_url = element.select(latestUpdatesSelectorThumbnailUrl).attr("abs:data-src")
 | 
			
		||||
            getUrlWithoutDomain(element.select(MLConstants.latestUpdatesSelectorUrl).first().attr("abs:href"))
 | 
			
		||||
        manga.title = element.select(MLConstants.latestUpdatesSelectorTitle).text().trim()
 | 
			
		||||
        manga.thumbnail_url = element.select(MLConstants.latestUpdatesSelectorThumbnailUrl).attr("abs:src").replace("//", "/")
 | 
			
		||||
        return manga
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -76,29 +84,56 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
     */
 | 
			
		||||
    fun latestUpdatesHasNextPages() = false
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Search the information of a Manga with the URL-Address
 | 
			
		||||
     */
 | 
			
		||||
    fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
 | 
			
		||||
        return if (query.startsWith(MLConstants.PREFIX_MANGA_ID_SEARCH)) {
 | 
			
		||||
            val realQuery = query.removePrefix(MLConstants.PREFIX_MANGA_ID_SEARCH)
 | 
			
		||||
            client.newCall(GET("$baseUrl/$realQuery", headers))
 | 
			
		||||
                .asObservableSuccess().map { response ->
 | 
			
		||||
                    val details = getMangaDetails(response.asJsoup())
 | 
			
		||||
                    details.url = "/$realQuery"
 | 
			
		||||
                    MangasPage(listOf(details), false)
 | 
			
		||||
                }
 | 
			
		||||
        } else {
 | 
			
		||||
            val request = GET(searchMangaRequest(page, query, filters).toString(), headers)
 | 
			
		||||
            client.newCall(request)
 | 
			
		||||
                .asObservableSuccess().map { response ->
 | 
			
		||||
                    searchMangaParse(response)
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get eine Liste mit Mangas from Search Site
 | 
			
		||||
     */
 | 
			
		||||
    fun getMangasFromSearchSite(document: Document): List<SManga> {
 | 
			
		||||
        return document.select(searchSiteMangasHTMLSelector).map { getMangaFromList(it) }
 | 
			
		||||
    private fun getMangasFromSearchSite(document: Document): List<SManga> {
 | 
			
		||||
        return document.select(MLConstants.searchSiteMangasHTMLSelector).map {
 | 
			
		||||
            val manga = SManga.create()
 | 
			
		||||
            manga.url = getUrlWithoutDomain(it.select(MLConstants.searchPageUrlHTMLSelector).attr("abs:href"))
 | 
			
		||||
            manga.title = it.select(MLConstants.searchPageTitleHTMLSelector).text().trim()
 | 
			
		||||
            manga.thumbnail_url = it.select(MLConstants.searchPageThumbnailUrlMangaHTMLSelector).attr("abs:data-src")
 | 
			
		||||
            manga
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get eine Liste mit Mangas from Genre Site
 | 
			
		||||
     */
 | 
			
		||||
    fun getMangasFromGenreSite(document: Document): List<SManga> {
 | 
			
		||||
        return document.select(genreSiteMangasHTMLSelector).map { getMangaFromList(it) }
 | 
			
		||||
    private fun getMangasFromGenreSite(document: Document): List<SManga> {
 | 
			
		||||
        return document.select(MLConstants.genreSiteMangasHTMLSelector).map { getMangaFromList(it) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse The Information from Mangas From Search or Genre Site
 | 
			
		||||
     * Parse The Information from Mangas From Popular or Genre Site
 | 
			
		||||
     * Title, Address and thumbnail_url
 | 
			
		||||
     */
 | 
			
		||||
    fun getMangaFromList(element: Element): SManga {
 | 
			
		||||
        val manga = SManga.create()
 | 
			
		||||
        manga.url = getUrlWithoutDomain(element.select(urlHTMLSelector).first().attr("abs:href"))
 | 
			
		||||
        manga.title = element.select(titleHTMLSelector).text().trim()
 | 
			
		||||
        manga.thumbnail_url = element.select(thumbnailUrlMangaListHTMLSelector).attr("abs:data-src")
 | 
			
		||||
        manga.url = getUrlWithoutDomain(element.select(MLConstants.popularGenreUrlHTMLSelector).attr("abs:href"))
 | 
			
		||||
        manga.title = element.select(MLConstants.popularGenreTitleHTMLSelector).text().trim()
 | 
			
		||||
        manga.thumbnail_url = element.select(MLConstants.popularGenreThumbnailUrlMangaHTMLSelector).attr("abs:data-src")
 | 
			
		||||
        return manga
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -110,33 +145,61 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
    fun getMangaDetails(document: Document): SManga {
 | 
			
		||||
        val manga = SManga.create()
 | 
			
		||||
 | 
			
		||||
        val descriptionList = document.select(descriptionHTMLSelector).map { it.text() }
 | 
			
		||||
        val author = document.select(authorHTMLSelector).text()
 | 
			
		||||
        val artist = document.select(artistHTMLSelector).text()
 | 
			
		||||
        val titleElements = document.select("#manga-title h1")
 | 
			
		||||
        val mangaType = getMangaBadges(titleElements)
 | 
			
		||||
        val descriptionList = document.select(MLConstants.mangaDetailsDescriptionHTMLSelector).map { it.text() }
 | 
			
		||||
        val author = document.select(MLConstants.mangaDetailsAuthorHTMLSelector).text()
 | 
			
		||||
        val artist = document.select(MLConstants.mangaDetailsArtistHTMLSelector).text()
 | 
			
		||||
 | 
			
		||||
        val genrelist = document.select(genreHTMLSelector).map { it.text() }
 | 
			
		||||
        val tagList = document.select(tagsHTMLSelector).map { it.text() }
 | 
			
		||||
        val genrelist = document.select(MLConstants.mangaDetailsGenreHTMLSelector).map { it.text() }
 | 
			
		||||
        val tagList = document.select(MLConstants.mangaDetailsTagsHTMLSelector).map { it.text() }
 | 
			
		||||
        val genreTagList = genrelist + tagList
 | 
			
		||||
 | 
			
		||||
        manga.title = titleElements.last().ownText().trim()
 | 
			
		||||
        manga.thumbnail_url =
 | 
			
		||||
            document.select(thumbnailUrlMangaDetailsHTMLSelector).attr("abs:data-src")
 | 
			
		||||
            document.select(MLConstants.mangaDetailsThumbnailUrlHTMLSelector).attr("abs:data-src")
 | 
			
		||||
        manga.description = descriptionList.joinToString("\n")
 | 
			
		||||
        manga.author = if (author.isBlank()) "Autor Desconocido" else author
 | 
			
		||||
        manga.artist = artist
 | 
			
		||||
        manga.genre = genreTagList.joinToString(", ")
 | 
			
		||||
        manga.status = findMangaStatus(tagList, document)
 | 
			
		||||
        manga.status = findMangaStatus(tagList, document.select(MLConstants.mangaDetailsAttributes))
 | 
			
		||||
        return manga
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun findMangaStatus(tagList: List<String>, document: Document): Int {
 | 
			
		||||
        return if (tagList.contains("Fin")) {
 | 
			
		||||
            SManga.COMPLETED
 | 
			
		||||
        } else {
 | 
			
		||||
            when (document.select(statusHTMLSelector)?.first()?.text()?.trim()) {
 | 
			
		||||
                "Publicandose" -> SManga.ONGOING
 | 
			
		||||
                else -> SManga.UNKNOWN
 | 
			
		||||
    /**
 | 
			
		||||
     * Types of the Manga
 | 
			
		||||
     * Return aList with all Types from a Manga
 | 
			
		||||
     *  for example Adults, Gay
 | 
			
		||||
     *  if the list is empty the manga is for everyone
 | 
			
		||||
     */
 | 
			
		||||
    private fun getMangaBadges(titleBadges: Elements): List<MangaType> {
 | 
			
		||||
        val types = mutableListOf<MangaType>()
 | 
			
		||||
 | 
			
		||||
        for (badge in titleBadges.select("span")) {
 | 
			
		||||
            if (badge.hasClass(MangaType.ADULT.getBadge()))
 | 
			
		||||
                types.add(MangaType.ADULT)
 | 
			
		||||
            if (badge.hasClass(MangaType.GAY.getBadge()))
 | 
			
		||||
                types.add(MangaType.GAY)
 | 
			
		||||
        }
 | 
			
		||||
        return types
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun findMangaStatus(tagList: List<String>, elements: Elements): Int {
 | 
			
		||||
        if (tagList.contains("Fin")) {
 | 
			
		||||
            return SManga.COMPLETED
 | 
			
		||||
        }
 | 
			
		||||
        elements.forEach { element ->
 | 
			
		||||
            val key = element.select("div.summary-heading h5")?.text()?.trim()
 | 
			
		||||
            val value = element.select("div.summary-content")?.text()?.trim()
 | 
			
		||||
 | 
			
		||||
            if (key == "Estado") {
 | 
			
		||||
                return when (value) {
 | 
			
		||||
                    "Publicandose" -> SManga.ONGOING
 | 
			
		||||
                    else -> SManga.UNKNOWN
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return SManga.UNKNOWN
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -145,9 +208,9 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
     * @param response the response from the site.
 | 
			
		||||
     */
 | 
			
		||||
    fun getChapterListParse(response: Response): List<SChapter> {
 | 
			
		||||
        return response.asJsoup().select(chapterListParseSelector).map { element ->
 | 
			
		||||
        return response.asJsoup().select(MLConstants.chapterListParseSelector).map { element ->
 | 
			
		||||
            // Link to the Chapter with the info (address and chapter title)
 | 
			
		||||
            val chapterInfo = element.select(chapterLinkParser)
 | 
			
		||||
            val chapterInfo = element.select(MLConstants.chapterLinkParser)
 | 
			
		||||
            // Chaptername
 | 
			
		||||
            val chapterName = chapterInfo.text().trim()
 | 
			
		||||
            // release date came as text with format dd/mm/yyyy from a link or <i>dd/mm/yyyy</i>
 | 
			
		||||
@ -171,8 +234,8 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
     * Get The String with the information about the Release date of the Chapter
 | 
			
		||||
     */
 | 
			
		||||
    private fun getChapterReleaseDate(element: Element): String {
 | 
			
		||||
        val chapterReleaseDateLink = element.select(chapterReleaseDateLinkParser).attr("title")
 | 
			
		||||
        val chapterReleaseDateI = element.select(chapterReleaseDateIParser).text()
 | 
			
		||||
        val chapterReleaseDateLink = element.select(MLConstants.chapterReleaseDateLinkParser).attr("title")
 | 
			
		||||
        val chapterReleaseDateI = element.select(MLConstants.chapterReleaseDateIParser).text()
 | 
			
		||||
        return when {
 | 
			
		||||
            chapterReleaseDateLink.isNotEmpty() -> chapterReleaseDateLink
 | 
			
		||||
            chapterReleaseDateI.isNotEmpty() -> chapterReleaseDateI
 | 
			
		||||
@ -204,7 +267,7 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
                getReleaseTime(releaseDateStr, Calendar.DAY_OF_YEAR)
 | 
			
		||||
 | 
			
		||||
            regExDate.containsMatchIn(releaseDateStr) ->
 | 
			
		||||
                SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).parse(releaseDateStr).time
 | 
			
		||||
                SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).parse(releaseDateStr)!!.time
 | 
			
		||||
 | 
			
		||||
            else -> 0
 | 
			
		||||
        }
 | 
			
		||||
@ -229,7 +292,7 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
     */
 | 
			
		||||
    fun getPageListParse(response: Response): List<Page> {
 | 
			
		||||
        val list =
 | 
			
		||||
            response.asJsoup().select(pageListParseSelector).mapIndexed { index, imgElement ->
 | 
			
		||||
            response.asJsoup().select(MLConstants.pageListParseSelector).mapIndexed { index, imgElement ->
 | 
			
		||||
                Page(index, "", imgElement.attr("abs:data-src"))
 | 
			
		||||
            }
 | 
			
		||||
        return list
 | 
			
		||||
@ -270,11 +333,11 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
        val hasNextPages = hasNextPages(document)
 | 
			
		||||
        val mangas: List<SManga>
 | 
			
		||||
 | 
			
		||||
        when (searchType) {
 | 
			
		||||
        mangas = when (searchType) {
 | 
			
		||||
            SearchType.SEARCH_FREE ->
 | 
			
		||||
                mangas = getMangasFromSearchSite(document)
 | 
			
		||||
                getMangasFromSearchSite(document)
 | 
			
		||||
            SearchType.SEARCH_FILTER ->
 | 
			
		||||
                mangas = getMangasFromGenreSite(document)
 | 
			
		||||
                getMangasFromGenreSite(document)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return MangasPage(mangas, hasNextPages)
 | 
			
		||||
@ -283,12 +346,12 @@ class ManhwaLatinoSiteParser(private val baseUrl: String) {
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if there ir another page to show
 | 
			
		||||
     */
 | 
			
		||||
    fun hasNextPages(document: Document): Boolean {
 | 
			
		||||
        return !document.select(searchMangaNextPageSelector).isEmpty()
 | 
			
		||||
    private fun hasNextPages(document: Document): Boolean {
 | 
			
		||||
        return !document.select(MLConstants.searchMangaNextPageSelector).isEmpty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a Address url without the base url.
 | 
			
		||||
     */
 | 
			
		||||
    protected fun getUrlWithoutDomain(url: String) = url.substringAfter(baseUrl)
 | 
			
		||||
    private fun getUrlWithoutDomain(url: String) = url.substringAfter(baseUrl)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,37 @@
 | 
			
		||||
package eu.kanade.tachiyomi.extension.es.manhwalatino
 | 
			
		||||
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.content.ActivityNotFoundException
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.util.Log
 | 
			
		||||
import kotlin.system.exitProcess
 | 
			
		||||
 | 
			
		||||
class ManhwaLatinoUrlActivity : Activity() {
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
        val pathSegments = intent?.data?.pathSegments
 | 
			
		||||
 | 
			
		||||
        if (pathSegments != null && pathSegments.size > 1) {
 | 
			
		||||
            val type = pathSegments[0]
 | 
			
		||||
            val mangaName = pathSegments[1]
 | 
			
		||||
 | 
			
		||||
            val mainIntent = Intent().apply {
 | 
			
		||||
                action = "eu.kanade.tachiyomi.SEARCH"
 | 
			
		||||
                putExtra("query", "${MLConstants.PREFIX_MANGA_ID_SEARCH}$type/$mangaName")
 | 
			
		||||
                putExtra("filter", packageName)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                startActivity(mainIntent)
 | 
			
		||||
            } catch (e: ActivityNotFoundException) {
 | 
			
		||||
                Log.e("MLUrlActivity", e.toString())
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Log.e("TMOUrlActivity", "could not parse uri from intent $intent")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        finish()
 | 
			
		||||
        exitProcess(0)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user