DeviantArt: Add preference for artist name in manga title (#7375)
* Add preference for artist name in manga title * Move || to end of previous line * Remove redundant function definitions * Rename pref entries, clarify summary, make pageListParse readable
This commit is contained in:
parent
343024eb03
commit
487ed3fb38
|
@ -1,7 +1,7 @@
|
||||||
ext {
|
ext {
|
||||||
extName = 'DeviantArt'
|
extName = 'DeviantArt'
|
||||||
extClass = '.DeviantArt'
|
extClass = '.DeviantArt'
|
||||||
extVersionCode = 4
|
extVersionCode = 5
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package eu.kanade.tachiyomi.extension.all.deviantart
|
package eu.kanade.tachiyomi.extension.all.deviantart
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.preference.ListPreference
|
||||||
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
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.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
@ -15,16 +20,22 @@ import okhttp3.Response
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.parser.Parser
|
import org.jsoup.parser.Parser
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class DeviantArt : HttpSource() {
|
class DeviantArt : HttpSource(), ConfigurableSource {
|
||||||
override val name = "DeviantArt"
|
override val name = "DeviantArt"
|
||||||
override val baseUrl = "https://deviantart.com"
|
override val baseUrl = "https://deviantart.com"
|
||||||
override val lang = "all"
|
override val lang = "all"
|
||||||
override val supportsLatest = false
|
override val supportsLatest = false
|
||||||
|
|
||||||
|
private val preferences: SharedPreferences by lazy {
|
||||||
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
|
}
|
||||||
|
|
||||||
override fun headersBuilder() = Headers.Builder().apply {
|
override fun headersBuilder() = Headers.Builder().apply {
|
||||||
add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0")
|
add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0")
|
||||||
}
|
}
|
||||||
|
@ -76,28 +87,32 @@ class DeviantArt : HttpSource() {
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val subFolderGallery = document.selectFirst("#sub-folder-gallery")
|
val gallery = document.selectFirst("#sub-folder-gallery")
|
||||||
val manga = SManga.create().apply {
|
|
||||||
// If manga is sub-gallery then use sub-gallery name, else use gallery name
|
// If manga is sub-gallery then use sub-gallery name, else use gallery name
|
||||||
title = subFolderGallery?.selectFirst("._2vMZg + ._2vMZg")?.text()?.substringBeforeLast(" ")
|
val galleryName = gallery?.selectFirst("._2vMZg + ._2vMZg")?.text()?.substringBeforeLast(" ")
|
||||||
?: subFolderGallery?.selectFirst("[aria-haspopup=listbox] > div")!!.ownText()
|
?: gallery?.selectFirst("[aria-haspopup=listbox] > div")!!.ownText()
|
||||||
|
val artistInTitle = preferences.artistInTitle == ArtistInTitle.ALWAYS.name ||
|
||||||
|
preferences.artistInTitle == ArtistInTitle.ONLY_ALL_GALLERIES.name && galleryName == "All"
|
||||||
|
|
||||||
|
return SManga.create().apply {
|
||||||
|
setUrlWithoutDomain(response.request.url.toString())
|
||||||
author = document.title().substringBefore(" ")
|
author = document.title().substringBefore(" ")
|
||||||
description = subFolderGallery?.selectFirst(".legacy-journal")?.wholeText()
|
title = when (artistInTitle) {
|
||||||
thumbnail_url = subFolderGallery?.selectFirst("img[property=contentUrl]")?.absUrl("src")
|
true -> "$author - $galleryName"
|
||||||
|
false -> galleryName
|
||||||
|
}
|
||||||
|
description = gallery?.selectFirst(".legacy-journal")?.wholeText()
|
||||||
|
thumbnail_url = gallery?.selectFirst("img[property=contentUrl]")?.absUrl("src")
|
||||||
}
|
}
|
||||||
manga.setUrlWithoutDomain(response.request.url.toString())
|
|
||||||
return manga
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga): Request {
|
override fun chapterListRequest(manga: SManga): Request {
|
||||||
val pathSegments = getMangaUrl(manga).toHttpUrl().pathSegments
|
val pathSegments = getMangaUrl(manga).toHttpUrl().pathSegments
|
||||||
val username = pathSegments[0]
|
val username = pathSegments[0]
|
||||||
val folderId = pathSegments[2]
|
val query = when (val folderId = pathSegments[2]) {
|
||||||
|
"all" -> "gallery:$username"
|
||||||
val query = if (folderId == "all") {
|
else -> "gallery:$username/$folderId"
|
||||||
"gallery:$username"
|
|
||||||
} else {
|
|
||||||
"gallery:$username/$folderId"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val url = backendBuilder()
|
val url = backendBuilder()
|
||||||
|
@ -155,17 +170,17 @@ class DeviantArt : HttpSource() {
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val firstImageUrl = document.selectFirst("img[fetchpriority=high]")?.absUrl("src")
|
val firstImageUrl = document.selectFirst("img[fetchpriority=high]")?.absUrl("src")
|
||||||
val buttons = document.selectFirst("[draggable=false]")?.children()
|
return when (val buttons = document.selectFirst("[draggable=false]")?.children()) {
|
||||||
return buttons?.mapIndexed { i, button ->
|
null -> listOf(Page(0, imageUrl = firstImageUrl))
|
||||||
|
else -> buttons.mapIndexed { i, button ->
|
||||||
// Remove everything past "/v1/" to get original instead of thumbnail
|
// Remove everything past "/v1/" to get original instead of thumbnail
|
||||||
val imageUrl = button.selectFirst("img")?.absUrl("src")?.substringBefore("/v1/")
|
val imageUrl = button.selectFirst("img")?.absUrl("src")?.substringBefore("/v1/")
|
||||||
Page(i, imageUrl = imageUrl)
|
Page(i, imageUrl = imageUrl)
|
||||||
}?.also {
|
}.also {
|
||||||
// First image needs token to get original, which is included in firstImageUrl
|
// First image needs token to get original, which is included in firstImageUrl
|
||||||
it[0].imageUrl = firstImageUrl
|
it[0].imageUrl = firstImageUrl
|
||||||
}
|
}
|
||||||
// If there are no buttons then chapter only has one page
|
}
|
||||||
?: listOf(Page(0, imageUrl = firstImageUrl))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun imageUrlParse(response: Response): String {
|
override fun imageUrlParse(response: Response): String {
|
||||||
|
@ -176,7 +191,38 @@ class DeviantArt : HttpSource() {
|
||||||
return Jsoup.parse(body.string(), request.url.toString(), Parser.xmlParser())
|
return Jsoup.parse(body.string(), request.url.toString(), Parser.xmlParser())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
|
val artistInTitlePref = ListPreference(screen.context).apply {
|
||||||
|
key = ArtistInTitle.PREF_KEY
|
||||||
|
title = "Artist name in manga title"
|
||||||
|
entries = ArtistInTitle.values().map { it.text }.toTypedArray()
|
||||||
|
entryValues = ArtistInTitle.values().map { it.name }.toTypedArray()
|
||||||
|
summary = "Current: %s\n\n" +
|
||||||
|
"Changing this preference will not automatically apply to manga in Library " +
|
||||||
|
"and History, so refresh all DeviantArt manga and/or clear database in Settings " +
|
||||||
|
"> Advanced after doing so."
|
||||||
|
setDefaultValue(ArtistInTitle.defaultValue.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
screen.addPreference(artistInTitlePref)
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class ArtistInTitle(val text: String) {
|
||||||
|
NEVER("Never"),
|
||||||
|
ALWAYS("Always"),
|
||||||
|
ONLY_ALL_GALLERIES("Only in \"All\" galleries"),
|
||||||
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val SEARCH_FORMAT_MSG = "Please enter a query in the format of gallery:{username} or gallery:{username}/{folderId}"
|
const val PREF_KEY = "artistInTitlePref"
|
||||||
|
val defaultValue = ONLY_ALL_GALLERIES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val SharedPreferences.artistInTitle
|
||||||
|
get() = getString(ArtistInTitle.PREF_KEY, ArtistInTitle.defaultValue.name)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val SEARCH_FORMAT_MSG = "Please enter a query in the format of gallery:{username} or gallery:{username}/{folderId}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue