Add Happymh (#11680)
This commit is contained in:
		
							parent
							
								
									16eaf905e4
								
							
						
					
					
						commit
						64bda21dd9
					
				
							
								
								
									
										2
									
								
								src/zh/happymh/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/zh/happymh/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest package="eu.kanade.tachiyomi.extension" />
 | 
			
		||||
							
								
								
									
										11
									
								
								src/zh/happymh/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/zh/happymh/build.gradle
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
apply plugin: 'com.android.application'
 | 
			
		||||
apply plugin: 'kotlin-android'
 | 
			
		||||
 | 
			
		||||
ext {
 | 
			
		||||
    extName = 'Happymh'
 | 
			
		||||
    pkgNameSuffix = 'zh.happymh'
 | 
			
		||||
    extClass = '.Happymh'
 | 
			
		||||
    extVersionCode = 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
apply from: "$rootDir/common.gradle"
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 2.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 7.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-xxxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/zh/happymh/res/mipmap-xxxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/zh/happymh/res/web_hi_res_512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/zh/happymh/res/web_hi_res_512.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 67 KiB  | 
@ -0,0 +1,117 @@
 | 
			
		||||
package eu.kanade.tachiyomi.extension.zh.happymh
 | 
			
		||||
 | 
			
		||||
import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
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.util.asJsoup
 | 
			
		||||
import kotlinx.serialization.json.Json
 | 
			
		||||
import kotlinx.serialization.json.boolean
 | 
			
		||||
import kotlinx.serialization.json.jsonArray
 | 
			
		||||
import kotlinx.serialization.json.jsonObject
 | 
			
		||||
import kotlinx.serialization.json.jsonPrimitive
 | 
			
		||||
import okhttp3.FormBody
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
class Happymh : HttpSource() {
 | 
			
		||||
    override val name: String = "嗨皮漫画"
 | 
			
		||||
    override val lang: String = "zh"
 | 
			
		||||
    override val supportsLatest: Boolean = true
 | 
			
		||||
    override val baseUrl: String = "https://m.happymh.com"
 | 
			
		||||
    override val client: OkHttpClient = network.cloudflareClient
 | 
			
		||||
    private val json: Json by injectLazy()
 | 
			
		||||
 | 
			
		||||
    // Popular
 | 
			
		||||
 | 
			
		||||
    // Requires login, otherwise result is the same as latest updates
 | 
			
		||||
    override fun popularMangaRequest(page: Int): Request {
 | 
			
		||||
        val header = headersBuilder().add("referer", "$baseUrl/latest").build()
 | 
			
		||||
        return GET("$baseUrl/apis/c/index?pn=$page&series_status=-1&order=views", header)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun popularMangaParse(response: Response): MangasPage {
 | 
			
		||||
        val data = json.parseToJsonElement(response.body!!.string()).jsonObject["data"]!!.jsonObject
 | 
			
		||||
        val items = data["items"]!!.jsonArray.map {
 | 
			
		||||
            SManga.create().apply {
 | 
			
		||||
                val obj = it.jsonObject
 | 
			
		||||
                title = obj["name"]!!.jsonPrimitive.content
 | 
			
		||||
                url = "/manga/${obj["manga_code"]!!.jsonPrimitive.content}"
 | 
			
		||||
                thumbnail_url = obj["cover"]!!.jsonPrimitive.content
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        val isEnd = data["isEnd"]!!.jsonPrimitive.boolean
 | 
			
		||||
        return MangasPage(items, !isEnd)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Latest
 | 
			
		||||
 | 
			
		||||
    override fun latestUpdatesRequest(page: Int): Request {
 | 
			
		||||
        val header = headersBuilder().add("referer", "$baseUrl/latest").build()
 | 
			
		||||
        return GET("$baseUrl/apis/c/index?pn=$page&series_status=-1&order=last_date", header)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
 | 
			
		||||
 | 
			
		||||
    // Search
 | 
			
		||||
 | 
			
		||||
    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
 | 
			
		||||
        val body = FormBody.Builder().addEncoded("searchkey", query).build()
 | 
			
		||||
        val header = headersBuilder().add("referer", "$baseUrl/ssearch").build()
 | 
			
		||||
        return POST("$baseUrl/apis/m/ssearch?pn=$page", header, body)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun searchMangaParse(response: Response): MangasPage {
 | 
			
		||||
        // I do not find a way to go to next page, so I always set hasNextPage to false
 | 
			
		||||
        return MangasPage(popularMangaParse(response).mangas, false)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Details
 | 
			
		||||
 | 
			
		||||
    override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply {
 | 
			
		||||
        val document = response.asJsoup()
 | 
			
		||||
        title = document.selectFirst("div.mg-property > h2.mg-title").text()
 | 
			
		||||
        thumbnail_url = document.selectFirst("div.mg-cover > mip-img").attr("abs:src")
 | 
			
		||||
        author = document.selectFirst("div.mg-property > p.mg-sub-title:nth-of-type(2)").text()
 | 
			
		||||
        artist = author
 | 
			
		||||
        genre = document.select("div.mg-property > p.mg-cate > a").eachText().joinToString(", ")
 | 
			
		||||
        description = document.selectFirst("div.manga-introduction > mip-showmore#showmore").text()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Chapters
 | 
			
		||||
 | 
			
		||||
    override fun chapterListParse(response: Response): List<SChapter> {
 | 
			
		||||
        val comicId = response.request.url.pathSegments.last()
 | 
			
		||||
        val document = response.asJsoup()
 | 
			
		||||
        val script = document.selectFirst("mip-data > script:containsData(chapterList)").html()
 | 
			
		||||
        return json.parseToJsonElement(script).jsonObject["chapterList"]!!.jsonArray.map {
 | 
			
		||||
            SChapter.create().apply {
 | 
			
		||||
                val chapterId = it.jsonObject["id"]!!.jsonPrimitive.content
 | 
			
		||||
                url = "/v2.0/apis/manga/read?code=$comicId&cid=$chapterId"
 | 
			
		||||
                name = it.jsonObject["chapterName"]!!.jsonPrimitive.content
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Pages
 | 
			
		||||
 | 
			
		||||
    override fun pageListRequest(chapter: SChapter): Request {
 | 
			
		||||
        // Some chapters return 403 without this header
 | 
			
		||||
        val header = headersBuilder().add("X-Requested-With", "XMLHttpRequest").build()
 | 
			
		||||
        return GET(baseUrl + chapter.url, header)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun pageListParse(response: Response): List<Page> = mutableListOf<Page>().apply {
 | 
			
		||||
        json.parseToJsonElement(response.body!!.string()).jsonObject["data"]!!.jsonObject["scans"]!!.jsonArray.mapIndexed() { index, it ->
 | 
			
		||||
            add(Page(index, "", it.jsonObject["url"]!!.jsonPrimitive.content))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun imageUrlParse(response: Response): String = throw Exception("Not Used")
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user