Added support for gallery unregistered in hitomi
This commit is contained in:
@@ -39,7 +39,7 @@ import kotlinx.android.synthetic.main.activity_reader.*
|
|||||||
import kotlinx.android.synthetic.main.activity_reader.view.*
|
import kotlinx.android.synthetic.main.activity_reader.view.*
|
||||||
import kotlinx.android.synthetic.main.dialog_numberpicker.view.*
|
import kotlinx.android.synthetic.main.dialog_numberpicker.view.*
|
||||||
import kotlinx.serialization.ImplicitReflectionSerializer
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
import xyz.quaver.hitomi.Reader
|
import xyz.quaver.Code
|
||||||
import xyz.quaver.pupil.Pupil
|
import xyz.quaver.pupil.Pupil
|
||||||
import xyz.quaver.pupil.R
|
import xyz.quaver.pupil.R
|
||||||
import xyz.quaver.pupil.adapters.ReaderAdapter
|
import xyz.quaver.pupil.adapters.ReaderAdapter
|
||||||
@@ -264,8 +264,8 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
menu?.findItem(R.id.reader_type)?.icon = ContextCompat.getDrawable(this@ReaderActivity,
|
menu?.findItem(R.id.reader_type)?.icon = ContextCompat.getDrawable(this@ReaderActivity,
|
||||||
when (reader.code) {
|
when (reader.code) {
|
||||||
Reader.Code.HITOMI -> R.drawable.hitomi
|
Code.HITOMI -> R.drawable.hitomi
|
||||||
Reader.Code.HIYOBI -> R.drawable.ic_hiyobi
|
Code.HIYOBI -> R.drawable.ic_hiyobi
|
||||||
else -> android.R.color.transparent
|
else -> android.R.color.transparent
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import kotlinx.coroutines.launch
|
|||||||
import xyz.quaver.hitomi.Gallery
|
import xyz.quaver.hitomi.Gallery
|
||||||
import xyz.quaver.hitomi.GalleryBlock
|
import xyz.quaver.hitomi.GalleryBlock
|
||||||
import xyz.quaver.hitomi.getGallery
|
import xyz.quaver.hitomi.getGallery
|
||||||
import xyz.quaver.hitomi.getGalleryBlock
|
|
||||||
import xyz.quaver.pupil.BuildConfig
|
import xyz.quaver.pupil.BuildConfig
|
||||||
import xyz.quaver.pupil.Pupil
|
import xyz.quaver.pupil.Pupil
|
||||||
import xyz.quaver.pupil.R
|
import xyz.quaver.pupil.R
|
||||||
@@ -51,6 +50,7 @@ import xyz.quaver.pupil.adapters.ThumbnailAdapter
|
|||||||
import xyz.quaver.pupil.types.Tag
|
import xyz.quaver.pupil.types.Tag
|
||||||
import xyz.quaver.pupil.ui.ReaderActivity
|
import xyz.quaver.pupil.ui.ReaderActivity
|
||||||
import xyz.quaver.pupil.util.ItemClickSupport
|
import xyz.quaver.pupil.util.ItemClickSupport
|
||||||
|
import xyz.quaver.pupil.util.download.Cache
|
||||||
import xyz.quaver.pupil.util.wordCapitalize
|
import xyz.quaver.pupil.util.wordCapitalize
|
||||||
|
|
||||||
class GalleryDialog(context: Context, private val galleryID: Int) : Dialog(context) {
|
class GalleryDialog(context: Context, private val galleryID: Int) : Dialog(context) {
|
||||||
@@ -237,7 +237,7 @@ class GalleryDialog(context: Context, private val galleryID: Int) : Dialog(conte
|
|||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
gallery.related.forEachIndexed { i, galleryID ->
|
gallery.related.forEachIndexed { i, galleryID ->
|
||||||
async(Dispatchers.IO) {
|
async(Dispatchers.IO) {
|
||||||
getGalleryBlock(galleryID)
|
Cache(context).getGalleryBlock(galleryID)
|
||||||
}.let {
|
}.let {
|
||||||
val galleryBlock = it.await() ?: return@let
|
val galleryBlock = it.await() ?: return@let
|
||||||
|
|
||||||
|
|||||||
@@ -108,13 +108,16 @@ class Cache(context: Context) : ContextWrapper(context) {
|
|||||||
val metadata = Cache(this).getCachedMetadata(galleryID)
|
val metadata = Cache(this).getCachedMetadata(galleryID)
|
||||||
|
|
||||||
val galleryBlock = if (metadata?.galleryBlock == null)
|
val galleryBlock = if (metadata?.galleryBlock == null)
|
||||||
withContext(Dispatchers.IO) {
|
listOf(
|
||||||
try {
|
{ xyz.quaver.hitomi.getGalleryBlock(galleryID) },
|
||||||
xyz.quaver.hitomi.getGalleryBlock(galleryID)
|
{ xyz.quaver.hiyobi.getGalleryBlock(galleryID) }
|
||||||
} catch (e: Exception) {
|
).map {
|
||||||
null
|
CoroutineScope(Dispatchers.IO).async {
|
||||||
|
kotlin.runCatching {
|
||||||
|
it.invoke()
|
||||||
|
}.getOrNull()
|
||||||
}
|
}
|
||||||
}
|
}.awaitAll().filterNotNull()
|
||||||
else
|
else
|
||||||
metadata.galleryBlock
|
metadata.galleryBlock
|
||||||
|
|
||||||
@@ -123,7 +126,11 @@ class Cache(context: Context) : ContextWrapper(context) {
|
|||||||
Metadata(Cache(this).getCachedMetadata(galleryID), galleryBlock = galleryBlock)
|
Metadata(Cache(this).getCachedMetadata(galleryID), galleryBlock = galleryBlock)
|
||||||
)
|
)
|
||||||
|
|
||||||
return galleryBlock
|
val mirrors = preference.getString("mirrors", "")!!.split('>')
|
||||||
|
|
||||||
|
return galleryBlock.firstOrNull {
|
||||||
|
mirrors.contains(it.code.name)
|
||||||
|
} ?: galleryBlock.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getReaderOrNull(galleryID: Int): Reader? {
|
fun getReaderOrNull(galleryID: Int): Reader? {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import io.fabric.sdk.android.Fabric
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import okio.*
|
import okio.*
|
||||||
|
import xyz.quaver.Code
|
||||||
import xyz.quaver.hitomi.Reader
|
import xyz.quaver.hitomi.Reader
|
||||||
import xyz.quaver.hitomi.getReferer
|
import xyz.quaver.hitomi.getReferer
|
||||||
import xyz.quaver.hitomi.urlFromUrlFromHash
|
import xyz.quaver.hitomi.urlFromUrlFromHash
|
||||||
@@ -237,7 +238,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
|
|
||||||
val request = Request.Builder().apply {
|
val request = Request.Builder().apply {
|
||||||
when (reader.code) {
|
when (reader.code) {
|
||||||
Reader.Code.HITOMI -> {
|
Code.HITOMI -> {
|
||||||
url(
|
url(
|
||||||
urlFromUrlFromHash(
|
urlFromUrlFromHash(
|
||||||
galleryID,
|
galleryID,
|
||||||
@@ -247,7 +248,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
)
|
)
|
||||||
addHeader("Referer", getReferer(galleryID))
|
addHeader("Referer", getReferer(galleryID))
|
||||||
}
|
}
|
||||||
Reader.Code.HIYOBI -> {
|
Code.HIYOBI -> {
|
||||||
url(createImgList(galleryID, reader, lowQuality)[index].path)
|
url(createImgList(galleryID, reader, lowQuality)[index].path)
|
||||||
addHeader("User-Agent", user_agent)
|
addHeader("User-Agent", user_agent)
|
||||||
addHeader("Cookie", cookie)
|
addHeader("Cookie", cookie)
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ import xyz.quaver.hitomi.Reader
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class Metadata(
|
data class Metadata(
|
||||||
val thumbnail: String? = null,
|
val thumbnail: String? = null,
|
||||||
val galleryBlock: GalleryBlock? = null,
|
val galleryBlock: List<GalleryBlock>? = null,
|
||||||
val readers: List<Reader>? = null,
|
val readers: List<Reader>? = null,
|
||||||
val isDownloading: Boolean? = null
|
val isDownloading: Boolean? = null
|
||||||
) {
|
) {
|
||||||
constructor(
|
constructor(
|
||||||
metadata: Metadata?,
|
metadata: Metadata?,
|
||||||
thumbnail: String? = null,
|
thumbnail: String? = null,
|
||||||
galleryBlock: GalleryBlock? = null,
|
galleryBlock: List<GalleryBlock>? = null,
|
||||||
readers: List<Reader>? = null,
|
readers: List<Reader>? = null,
|
||||||
isDownloading: Boolean? = null
|
isDownloading: Boolean? = null
|
||||||
) : this(
|
) : this(
|
||||||
|
|||||||
24
libpupil/src/main/java/xyz/quaver/Code.kt
Normal file
24
libpupil/src/main/java/xyz/quaver/Code.kt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 tom5079
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.quaver
|
||||||
|
|
||||||
|
|
||||||
|
enum class Code {
|
||||||
|
HITOMI,
|
||||||
|
HIYOBI,
|
||||||
|
SORALA
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ package xyz.quaver.hitomi
|
|||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
import xyz.quaver.Code
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
@@ -67,6 +68,7 @@ fun fetchNozomi(area: String? = null, tag: String = "index", language: String =
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class GalleryBlock(
|
data class GalleryBlock(
|
||||||
|
val code: Code,
|
||||||
val id: Int,
|
val id: Int,
|
||||||
val galleryUrl: String,
|
val galleryUrl: String,
|
||||||
val thumbnails: List<String>,
|
val thumbnails: List<String>,
|
||||||
@@ -102,7 +104,7 @@ fun getGalleryBlock(galleryID: Int) : GalleryBlock? {
|
|||||||
href.slice(5 until href.indexOf("-all"))
|
href.slice(5 until href.indexOf("-all"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return GalleryBlock(galleryID, galleryUrl, thumbnails, title, artists, series, type, language, relatedTags)
|
return GalleryBlock(Code.HITOMI, galleryID, galleryUrl, thumbnails, title, artists, series, type, language, relatedTags)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package xyz.quaver.hitomi
|
|||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
import xyz.quaver.Code
|
||||||
|
|
||||||
fun getReferer(galleryID: Int) = "https://hitomi.la/reader/$galleryID.html"
|
fun getReferer(galleryID: Int) = "https://hitomi.la/reader/$galleryID.html"
|
||||||
|
|
||||||
@@ -31,13 +32,7 @@ data class GalleryInfo(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Reader(val code: Code, val title: String, val galleryInfo: List<GalleryInfo>) {
|
data class Reader(val code: Code, val title: String, val galleryInfo: List<GalleryInfo>)
|
||||||
enum class Code {
|
|
||||||
HITOMI,
|
|
||||||
HIYOBI,
|
|
||||||
SORALA
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set header `Referer` to reader url to avoid 403 error
|
//Set header `Referer` to reader url to avoid 403 error
|
||||||
fun getReader(galleryID: Int) : Reader {
|
fun getReader(galleryID: Int) : Reader {
|
||||||
@@ -45,5 +40,5 @@ fun getReader(galleryID: Int) : Reader {
|
|||||||
|
|
||||||
val doc = Jsoup.connect(readerUrl).get()
|
val doc = Jsoup.connect(readerUrl).get()
|
||||||
|
|
||||||
return Reader(Reader.Code.HITOMI, doc.title(), getGalleryInfo(galleryID))
|
return Reader(Code.HITOMI, doc.title(), getGalleryInfo(galleryID))
|
||||||
}
|
}
|
||||||
49
libpupil/src/main/java/xyz/quaver/hiyobi/galleryblock.kt
Normal file
49
libpupil/src/main/java/xyz/quaver/hiyobi/galleryblock.kt
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 tom5079
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.quaver.hiyobi
|
||||||
|
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import xyz.quaver.Code
|
||||||
|
import xyz.quaver.hitomi.GalleryBlock
|
||||||
|
import xyz.quaver.hitomi.protocol
|
||||||
|
|
||||||
|
fun getGalleryBlock(galleryID: Int) : GalleryBlock? {
|
||||||
|
val url = "$protocol//$hiyobi/search/$galleryID"
|
||||||
|
|
||||||
|
try {
|
||||||
|
val doc = Jsoup.connect(url).get()
|
||||||
|
|
||||||
|
val galleryBlock = doc.selectFirst(".gallery-content")
|
||||||
|
|
||||||
|
val galleryUrl = galleryBlock.selectFirst("a").attr("href")
|
||||||
|
|
||||||
|
val thumbnails = listOf(galleryBlock.selectFirst("img").attr("abs:src"))
|
||||||
|
|
||||||
|
val title = galleryBlock.selectFirst("b").text()
|
||||||
|
val artists = galleryBlock.select("tr:matches(작가) a[href~=artist]").map { it.text() }
|
||||||
|
val series = galleryBlock.select("tr:matches(원작) a").map { it.attr("href").substringAfter("series:").replace('_', ' ') }
|
||||||
|
val type = galleryBlock.selectFirst("tr:matches(종류) a").attr("href").substringAfter("type:").replace('_', ' ')
|
||||||
|
|
||||||
|
val language = "korean"
|
||||||
|
|
||||||
|
val relatedTags = galleryBlock.select("tr:matches(태그) a").map { it.attr("href").substringAfterLast('/').replace('_', ' ') }
|
||||||
|
|
||||||
|
return GalleryBlock(Code.HIYOBI, galleryID, galleryUrl, thumbnails, title, artists, series, type, language, relatedTags)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ package xyz.quaver.hiyobi
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.list
|
import kotlinx.serialization.list
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
import xyz.quaver.Code
|
||||||
import xyz.quaver.hitomi.GalleryInfo
|
import xyz.quaver.hitomi.GalleryInfo
|
||||||
import xyz.quaver.hitomi.Reader
|
import xyz.quaver.hitomi.Reader
|
||||||
import xyz.quaver.hitomi.protocol
|
import xyz.quaver.hitomi.protocol
|
||||||
@@ -76,7 +77,7 @@ fun getReader(galleryID: Int) : Reader {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return Reader(Reader.Code.HIYOBI, title, galleryInfo)
|
return Reader(Code.HIYOBI, title, galleryInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createImgList(galleryID: Int, reader: Reader, lowQuality: Boolean = false) =
|
fun createImgList(galleryID: Int, reader: Reader, lowQuality: Boolean = false) =
|
||||||
|
|||||||
@@ -102,4 +102,11 @@ class UnitTest {
|
|||||||
|
|
||||||
print(result)
|
print(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_hiyobi_galleryBlock() {
|
||||||
|
val galleryBlock = xyz.quaver.hiyobi.getGalleryBlock(10000027)
|
||||||
|
|
||||||
|
print(galleryBlock)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user