Hiyobi file structure changed

This commit is contained in:
Pupil
2020-02-22 11:02:58 +09:00
parent c0e7c87ca4
commit 4f0dbead79
13 changed files with 65 additions and 44 deletions

View File

@@ -20,7 +20,7 @@ android {
minSdkVersion 16
targetSdkVersion 29
versionCode 42
versionName "4.6-alpha7"
versionName "4.7-alpha1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true

View File

@@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":42,"versionName":"4.6-alpha7","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":42,"versionName":"4.7-alpha1","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

View File

@@ -90,7 +90,7 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
if (visibility == View.GONE) {
visibility = View.VISIBLE
max = reader.galleryInfo.size
max = reader.galleryInfo.files.size
}
if (progress == max) {
@@ -160,7 +160,7 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
} ?: 0
with(galleryblock_progressbar) {
max = reader.galleryInfo.size
max = reader.galleryInfo.files.size
progress = count
visibility = View.VISIBLE

View File

@@ -52,7 +52,7 @@ class ReaderAdapter(private val context: Context,
//region Glide.RecyclerView
val sizeProvider = ListPreloader.PreloadSizeProvider<File> { _, _, position ->
Cache(context).getReaderOrNull(galleryID)?.galleryInfo?.getOrNull(position)?.let {
Cache(context).getReaderOrNull(galleryID)?.galleryInfo?.files?.getOrNull(position)?.let {
arrayOf(it.width, it.height).toIntArray()
}
}
@@ -114,7 +114,7 @@ class ReaderAdapter(private val context: Context,
if (!isFullScreen)
(holder.view.container.layoutParams as ConstraintLayout.LayoutParams)
.dimensionRatio = "${reader!!.galleryInfo[position].width}:${reader!!.galleryInfo[position].height}"
.dimensionRatio = "${reader!!.galleryInfo.files[position].width}:${reader!!.galleryInfo.files[position].height}"
holder.view.reader_index.text = (position+1).toString()
@@ -161,6 +161,6 @@ class ReaderAdapter(private val context: Context,
}
}
override fun getItemCount() = reader?.galleryInfo?.size ?: 0
override fun getItemCount() = reader?.galleryInfo?.files?.size ?: 0
}

View File

@@ -263,8 +263,8 @@ class ReaderActivity : AppCompatActivity() {
notifyDataSetChanged()
}
title = reader.title
menu?.findItem(R.id.reader_menu_page_indicator)?.title = "$currentPage/${reader.galleryInfo.size}"
title = reader.galleryInfo.title
menu?.findItem(R.id.reader_menu_page_indicator)?.title = "$currentPage/${reader.galleryInfo.files.size}"
menu?.findItem(R.id.reader_type)?.icon = ContextCompat.getDrawable(this@ReaderActivity,
when (reader.code) {

View File

@@ -22,6 +22,7 @@ import android.content.Context
import android.content.ContextWrapper
import android.util.Base64
import androidx.preference.PreferenceManager
import com.crashlytics.android.Crashlytics
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
@@ -106,9 +107,11 @@ class Cache(context: Context) : ContextWrapper(context) {
var galleryBlock: GalleryBlock? = null
for (source in sources) {
galleryBlock = kotlin.runCatching {
galleryBlock = try {
source.invoke()
}.getOrNull()
} catch (e: Exception) {
null
}
if (galleryBlock != null)
break
@@ -158,6 +161,7 @@ class Cache(context: Context) : ContextWrapper(context) {
retval = try {
source.value.invoke()
} catch (e: Exception) {
Crashlytics.logException(e)
null
}

View File

@@ -213,7 +213,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
url(
urlFromUrlFromHash(
galleryID,
reader.galleryInfo[index],
reader.galleryInfo.files[index],
if (lowQuality) "webp" else null
)
)
@@ -251,18 +251,18 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
val cache = Cache(this@DownloadWorker).getImages(galleryID)
progress.put(galleryID, reader.galleryInfo.indices.map { index ->
progress.put(galleryID, reader.galleryInfo.files.indices.map { index ->
if (cache?.getOrNull(index) != null)
Float.POSITIVE_INFINITY
else
0F
}.toMutableList())
exception.put(galleryID, reader.galleryInfo.map { null }.toMutableList())
exception.put(galleryID, reader.galleryInfo.files.map { null }.toMutableList())
if (notification[galleryID] == null)
initNotification(galleryID)
notification[galleryID].setContentTitle(reader.title)
notification[galleryID].setContentTitle(reader.galleryInfo.title)
notify(galleryID)
if (isCompleted(galleryID)) {
@@ -276,7 +276,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
return@launch
}
for (i in reader.galleryInfo.indices) {
for (i in reader.galleryInfo.files.indices) {
val callback = object : Callback {
override fun onFailure(call: Call, e: IOException) {
if (Fabric.isInitialized() && e.message != "Canceled")

View File

@@ -10,4 +10,7 @@
<dimen name="nav_header_height">176dp</dimen>
<dimen name="thumbnail_margin">8dp</dimen>
<dimen name="galleryblock_thumbnail_thin">50dp</dimen>
<dimen name="galleryblock_thumbnail_normal">150dp</dimen>
</resources>

View File

@@ -17,7 +17,6 @@
package xyz.quaver.hitomi
import kotlinx.serialization.json.Json
import kotlinx.serialization.list
import xyz.quaver.proxy
import java.net.URL
@@ -26,12 +25,10 @@ const val protocol = "https:"
@Suppress("EXPERIMENTAL_API_USAGE")
fun getGalleryInfo(galleryID: Int) =
Json.nonstrict.parse(
GalleryInfo.serializer().list,
Regex("""\[.+]""").find(
URL("$protocol//$domain/galleries/$galleryID.js").openConnection(proxy).getInputStream().use {
it.reader().readText()
}
)?.value ?: "[]"
GalleryInfo.serializer(),
URL("$protocol//$domain/galleries/$galleryID.js").openConnection(proxy).getInputStream().use {
it.reader().readText()
}.replace("var galleryinfo = ", "")
)
//common.js
@@ -71,6 +68,7 @@ fun urlFromURL(url: String, base: String? = null) : String {
return url.replace(Regex("""//..?\.hitomi\.la/"""), "//${subdomainFromURL(url, base)}.hitomi.la/")
}
fun fullPathFromHash(hash: String?) : String? {
return when {
(hash?.length ?: 0) < 3 -> hash
@@ -79,11 +77,20 @@ fun fullPathFromHash(hash: String?) : String? {
}
@Suppress("NAME_SHADOWING", "UNUSED_PARAMETER")
fun urlFromHash(galleryID: Int, image: GalleryInfo, dir: String? = null, ext: String? = null) : String {
fun urlFromHash(galleryID: Int, image: GalleryFiles, dir: String? = null, ext: String? = null) : String {
val ext = ext ?: dir ?: image.name.split('.').last()
val dir = dir ?: "images"
return "$protocol//a.hitomi.la/$dir/${fullPathFromHash(image.hash)}.$ext"
}
fun urlFromUrlFromHash(galleryID: Int, image: GalleryInfo, dir: String? = null, ext: String? = null, base: String? = null) =
urlFromURL(urlFromHash(galleryID, image, dir, ext), base)
fun urlFromUrlFromHash(galleryID: Int, image: GalleryFiles, dir: String? = null, ext: String? = null, base: String? = null) =
urlFromURL(urlFromHash(galleryID, image, dir, ext), base)
fun imageUrlFromImage(galleryID: Int, image: GalleryFiles, noWebp: Boolean) : String {
val webp = if (image.hash != null && image.haswebp != 0 && !noWebp)
"webp"
else
null
return urlFromUrlFromHash(galleryID, image, webp)
}

View File

@@ -71,7 +71,7 @@ fun getGallery(galleryID: Int) : Gallery {
href.slice(5 until href.indexOf('-'))
}
val thumbnails = getGalleryInfo(galleryID).map { galleryInfo ->
val thumbnails = getGalleryInfo(galleryID).files.map { galleryInfo ->
urlFromUrlFromHash(galleryID, galleryInfo, "smalltn", "jpg", "tn")
}

View File

@@ -17,29 +17,35 @@
package xyz.quaver.hitomi
import kotlinx.serialization.Serializable
import org.jsoup.Jsoup
import xyz.quaver.Code
import xyz.quaver.proxy
fun getReferer(galleryID: Int) = "https://hitomi.la/reader/$galleryID.html"
@Serializable
data class GalleryInfo(
val language_localname: String? = null,
val language: String? = null,
val date: String? = null,
val files: List<GalleryFiles>,
val id: Int? = null,
val type: String? = null,
val title: String? = null
)
@Serializable
data class GalleryFiles(
val width: Int,
val hash: String? = null,
val haswebp: Int = 0,
val name: String,
val height: Int
val height: Int,
val hasavif: Int = 0
)
@Serializable
data class Reader(val code: Code, val title: String, val galleryInfo: List<GalleryInfo>)
data class Reader(val code: Code, val galleryInfo: GalleryInfo)
//Set header `Referer` to reader url to avoid 403 error
fun getReader(galleryID: Int) : Reader {
val readerUrl = "https://hitomi.la/reader/$galleryID.html"
val doc = Jsoup.connect(readerUrl).proxy(proxy).get()
return Reader(Code.HITOMI, doc.title(), getGalleryInfo(galleryID))
return Reader(Code.HITOMI, getGalleryInfo(galleryID))
}

View File

@@ -21,6 +21,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.list
import org.jsoup.Jsoup
import xyz.quaver.Code
import xyz.quaver.hitomi.GalleryFiles
import xyz.quaver.hitomi.GalleryInfo
import xyz.quaver.hitomi.Reader
import xyz.quaver.hitomi.protocol
@@ -63,12 +64,12 @@ fun renewCookie() : String {
@UseExperimental(UnstableDefault::class)
fun getReader(galleryID: Int) : Reader {
val reader = "https://$hiyobi/reader/$galleryID"
val url = "https://$hiyobi/data/json/${galleryID}_list.json"
val url = "https://cdn.hiyobi.me/data/json/${galleryID}_list.json"
val title = Jsoup.connect(reader).proxy(proxy).get().title()
val galleryInfo = Json.nonstrict.parse(
GalleryInfo.serializer().list,
val galleryFiles = Json.nonstrict.parse(
GalleryFiles.serializer().list,
with(URL(url).openConnection(proxy) as HttpsURLConnection) {
setRequestProperty("User-Agent", user_agent)
setRequestProperty("Cookie", cookie)
@@ -79,14 +80,14 @@ fun getReader(galleryID: Int) : Reader {
}
)
return Reader(Code.HIYOBI, title, galleryInfo)
return Reader(Code.HIYOBI, GalleryInfo(title = title, files = galleryFiles))
}
fun createImgList(galleryID: Int, reader: Reader, lowQuality: Boolean = false) =
if (lowQuality)
reader.galleryInfo.map {
reader.galleryInfo.files.map {
val name = it.name.replace(Regex("""\.[^/.]+$"""), "")
Images("$protocol//$hiyobi/data_r/$galleryID/$name.jpg", galleryID, it.name)
}
else
reader.galleryInfo.map { Images("$protocol//$hiyobi/data/$galleryID/${it.name}", galleryID, it.name) }
reader.galleryInfo.files.map { Images("$protocol//$hiyobi/data/$galleryID/${it.name}", galleryID, it.name) }

View File

@@ -82,14 +82,14 @@ class UnitTest {
@Test
fun test_hiyobi() {
val reader = xyz.quaver.hiyobi.getReader(10000062)
val reader = xyz.quaver.hiyobi.getReader(1574736)
print(reader)
}
@Test
fun test_urlFromUrlFromHash() {
val url = urlFromUrlFromHash(1531795, GalleryInfo(
val url = urlFromUrlFromHash(1531795, GalleryFiles(
212, "719d46a7556be0d0021c5105878507129b5b3308b02cf67f18901b69dbb3b5ef", 1, "00.jpg", 300
), "webp")