HQ Now - new extension (#1872)

* HQ Now - new extension

* icons
This commit is contained in:
Mike 2019-12-21 14:28:57 -05:00 committed by arkon
parent bb9dc35e48
commit 7bf2d4b256
8 changed files with 204 additions and 0 deletions

17
src/pt/hqnow/build.gradle Normal file
View File

@ -0,0 +1,17 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
appName = 'Tachiyomi: HQ Now!'
pkgNameSuffix = 'pt.hqnow'
extClass = '.HQNow'
extVersionCode = 1
libVersion = '1.2'
}
dependencies {
compileOnly 'com.google.code.gson:gson:2.8.2'
compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0'
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -0,0 +1,187 @@
package eu.kanade.tachiyomi.extension.pt.hqnow
import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.get
import com.google.gson.Gson
import com.google.gson.JsonObject
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.model.*
import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
class HQNow : HttpSource() {
override val name = "HQ Now!"
// Website is http://www.hq-now.com
override val baseUrl = "http://admin.hq-now.com/graphql"
override val lang = "pt-BR"
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient
private val gson = Gson()
private val jsonHeaders = headersBuilder().add("content-type", "application/json").build()
private fun mangaFromResponse(response: Response, selector: String, coversAvailable: Boolean = true): List<SManga> {
return gson.fromJson<JsonObject>(response.body()!!.string())["data"][selector].asJsonArray
.map {
SManga.create().apply {
url = it["id"].asString
title = it["name"].asString
if (coversAvailable) thumbnail_url = it["hqCover"].asString
}
}
}
// Popular
override fun popularMangaRequest(page: Int): Request {
return POST(baseUrl, jsonHeaders, RequestBody.create(null, "{\"operationName\":\"getHqsByFilters\",\"variables\":{\"orderByViews\":true,\"loadCovers\":true,\"limit\":30},\"query\":\"query getHqsByFilters(\$orderByViews: Boolean, \$limit: Int, \$publisherId: Int, \$loadCovers: Boolean) {\\n getHqsByFilters(orderByViews: \$orderByViews, limit: \$limit, publisherId: \$publisherId, loadCovers: \$loadCovers) {\\n id\\n name\\n editoraId\\n status\\n publisherName\\n hqCover\\n synopsis\\n updatedAt\\n }\\n}\\n\"}"))
}
override fun popularMangaParse(response: Response): MangasPage {
return MangasPage(mangaFromResponse(response, "getHqsByFilters"), false)
}
// Latest
override fun latestUpdatesRequest(page: Int): Request {
return POST(baseUrl, jsonHeaders, RequestBody.create(null, "{\"operationName\":\"getRecentlyUpdatedHqs\",\"variables\":{},\"query\":\"query getRecentlyUpdatedHqs {\\n getRecentlyUpdatedHqs {\\n name\\n hqCover\\n synopsis\\n id\\n updatedAt\\n updatedChapters\\n }\\n}\\n\"}"))
}
override fun latestUpdatesParse(response: Response): MangasPage {
return MangasPage(mangaFromResponse(response, "getRecentlyUpdatedHqs"), false)
}
// Search
private var queryIsTitle = true
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return if (query.isNotBlank()) {
queryIsTitle = true
POST(baseUrl, jsonHeaders, RequestBody.create(null, "{\"operationName\":\"getHqsByName\",\"variables\":{\"name\":\"$query\"},\"query\":\"query getHqsByName(\$name: String!) {\\n getHqsByName(name: \$name) {\\n id\\n name\\n editoraId\\n status\\n publisherName\\n impressionsCount\\n }\\n}\\n\"}"))
} else {
queryIsTitle = false
var searchLetter = ""
filters.forEach { filter ->
when (filter) {
is LetterFilter -> {
searchLetter = filter.toUriPart()
}
}
}
POST(baseUrl, jsonHeaders, RequestBody.create(null, "{\"operationName\":\"getHqsByNameStartingLetter\",\"variables\":{\"letter\":\"$searchLetter-$searchLetter\"},\"query\":\"query getHqsByNameStartingLetter(\$letter: String!) {\\n getHqsByNameStartingLetter(letter: \$letter) {\\n id\\n name\\n editoraId\\n status\\n publisherName\\n impressionsCount\\n }\\n}\\n\"}"))
}
}
override fun searchMangaParse(response: Response): MangasPage {
return MangasPage(mangaFromResponse(response, if (queryIsTitle) "getHqsByName" else "getHqsByNameStartingLetter", false), false)
}
// Details
override fun mangaDetailsRequest(manga: SManga): Request {
return POST(baseUrl, jsonHeaders, RequestBody.create(null, "{\"operationName\":\"getHqsById\",\"variables\":{\"id\":${manga.url}},\"query\":\"query getHqsById(\$id: Int!) {\\n getHqsById(id: \$id) {\\n id\\n name\\n synopsis\\n editoraId\\n status\\n publisherName\\n hqCover\\n impressionsCount\\n capitulos {\\n name\\n id\\n number\\n }\\n }\\n}\\n\"}"))
}
override fun mangaDetailsParse(response: Response): SManga {
return gson.fromJson<JsonObject>(response.body()!!.string())["data"]["getHqsById"][0]
.let {
SManga.create().apply {
title = it["name"].asString
thumbnail_url = it["hqCover"].asString
description = it["synopsis"].asString
author = it["publisherName"].asString
status = when (it["status"].asString) {
"Concluído" -> SManga.COMPLETED
"Em Andamento" -> SManga.ONGOING
else -> SManga.UNKNOWN
}
}
}
}
// Chapters
override fun chapterListRequest(manga: SManga): Request {
return mangaDetailsRequest(manga)
}
override fun chapterListParse(response: Response): List<SChapter> {
return gson.fromJson<JsonObject>(response.body()!!.string())["data"]["getHqsById"][0]["capitulos"].asJsonArray
.map {
SChapter.create().apply {
url = it["id"].asString
name = it["name"].asString.let { jsonName ->
if (jsonName.isNotEmpty()) jsonName.trim() else "Capitulo: " + it["number"].asString
}
}
}.reversed()
}
// Pages
override fun pageListRequest(chapter: SChapter): Request {
return POST(baseUrl, jsonHeaders, RequestBody.create(null, "{\"operationName\":\"getChapterById\",\"variables\":{\"chapterId\":${chapter.url}},\"query\":\"query getChapterById(\$chapterId: Int!) {\\n getChapterById(chapterId: \$chapterId) {\\n name\\n number\\n oneshot\\n pictures {\\n pictureUrl\\n }\\n hq {\\n id\\n name\\n capitulos {\\n id\\n number\\n }\\n }\\n }\\n}\\n\"}"))
}
override fun pageListParse(response: Response): List<Page> {
return gson.fromJson<JsonObject>(response.body()!!.string())["data"]["getChapterById"]["pictures"].asJsonArray
.mapIndexed { i, json -> Page(i, "", json["pictureUrl"].asString) }
}
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
// Filters
override fun getFilterList() = FilterList(
Filter.Header("NOTA: Ignorado se estiver usando"),
Filter.Header("a pesquisa de texto!"),
Filter.Separator(),
LetterFilter()
)
private class LetterFilter : UriPartFilter("Carta", arrayOf(
Pair("---","<Selecione>"),
Pair("a","A"),
Pair("b","B"),
Pair("c","C"),
Pair("d","D"),
Pair("e","E"),
Pair("f","F"),
Pair("g","G"),
Pair("h","H"),
Pair("i","I"),
Pair("j","J"),
Pair("k","K"),
Pair("l","L"),
Pair("m","M"),
Pair("n","N"),
Pair("o","O"),
Pair("p","P"),
Pair("q","Q"),
Pair("r","R"),
Pair("s","S"),
Pair("t","T"),
Pair("u","U"),
Pair("v","V"),
Pair("w","W"),
Pair("x","X"),
Pair("y","Y"),
Pair("z","Z")
))
open class UriPartFilter(displayName: String, private val vals: Array<Pair<String, String>>) :
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) {
fun toUriPart() = vals[state].first
}
}