Compare commits

..

5 Commits

Author SHA1 Message Date
Pupil
03444f070f App built 2020-02-23 10:40:09 +09:00
Pupil
2f1a63eb64 Confilict resolved 2020-02-23 10:32:10 +09:00
Pupil
9d0898b26c Fixed image loading bug 2020-02-23 10:30:57 +09:00
Pupil
994aa99797 Fixed image loading bug 2020-02-23 10:28:29 +09:00
Pupil
8204a15276 Proxy applied to thumbnails 2020-02-22 20:30:42 +09:00
6 changed files with 5612 additions and 37 deletions

View File

@@ -19,8 +19,8 @@ android {
applicationId "xyz.quaver.pupil" applicationId "xyz.quaver.pupil"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 42 versionCode 43
versionName "4.6" versionName "4.7-beta1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

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

View File

@@ -119,8 +119,9 @@ class ReaderAdapter(private val context: Context,
holder.view.reader_index.text = (position+1).toString() holder.view.reader_index.text = (position+1).toString()
val images = Cache(context).getImage(galleryID, position) val images = Cache(context).getImage(galleryID, position)
val progress = DownloadWorker.getInstance(context).progress[galleryID]?.get(position)
if (images != null) { if (progress?.isInfinite() == true && images != null) {
glide glide
.load(images) .load(images)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
@@ -132,8 +133,6 @@ class ReaderAdapter(private val context: Context,
} }
.into(holder.view.image) .into(holder.view.image)
} else { } else {
val progress = DownloadWorker.getInstance(context).progress[galleryID]?.get(position)
if (progress?.isNaN() == true) { if (progress?.isNaN() == true) {
if (Fabric.isInitialized()) if (Fabric.isInitialized())
Crashlytics.logException(DownloadWorker.getInstance(context).exception[galleryID]?.get(position)) Crashlytics.logException(DownloadWorker.getInstance(context).exception[galleryID]?.get(position))

View File

@@ -27,13 +27,16 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.io.InputStream
import xyz.quaver.Code import xyz.quaver.Code
import xyz.quaver.hitomi.GalleryBlock import xyz.quaver.hitomi.GalleryBlock
import xyz.quaver.hitomi.Reader import xyz.quaver.hitomi.Reader
import xyz.quaver.proxy
import xyz.quaver.pupil.util.getCachedGallery import xyz.quaver.pupil.util.getCachedGallery
import xyz.quaver.pupil.util.getDownloadDirectory import xyz.quaver.pupil.util.getDownloadDirectory
import xyz.quaver.pupil.util.json import xyz.quaver.pupil.util.json
import java.io.File import java.io.File
import java.io.FileOutputStream
import java.net.URL import java.net.URL
class Cache(context: Context) : ContextWrapper(context) { class Cache(context: Context) : ContextWrapper(context) {
@@ -78,7 +81,9 @@ class Cache(context: Context) : ContextWrapper(context) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val thumbnails = getGalleryBlock(galleryID)?.thumbnails val thumbnails = getGalleryBlock(galleryID)?.thumbnails
try { try {
Base64.encodeToString(URL(thumbnails?.firstOrNull()).readBytes(), Base64.DEFAULT) Base64.encodeToString(URL(thumbnails?.firstOrNull()).openConnection(proxy).getInputStream().use {
it.readBytes()
}, Base64.DEFAULT)
} catch (e: Exception) { } catch (e: Exception) {
null null
} }
@@ -212,16 +217,13 @@ class Cache(context: Context) : ContextWrapper(context) {
return null return null
} }
fun putImage(galleryID: Int, name: String, data: ByteArray) { fun putImage(galleryID: Int, index: Int, ext: String, data: InputStream) {
val cache = File(getCachedGallery(galleryID), name).also { val cache = File(getCachedGallery(galleryID), "%05d.$ext".format(index)).also {
if (!it.exists()) if (!it.exists())
it.createNewFile() it.createNewFile()
} }
if (!Regex("""^[0-9]+.+$""").matches(name)) data.copyTo(FileOutputStream(cache))
throw IllegalArgumentException("File name is not a number")
cache.writeBytes(data)
} }
fun moveToDownload(galleryID: Int) { fun moveToDownload(galleryID: Int) {

View File

@@ -23,6 +23,7 @@ import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Log
import android.util.SparseArray import android.util.SparseArray
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
@@ -46,6 +47,7 @@ import xyz.quaver.pupil.ui.ReaderActivity
import java.io.IOException import java.io.IOException
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit
@UseExperimental(ExperimentalCoroutinesApi::class) @UseExperimental(ExperimentalCoroutinesApi::class)
class DownloadWorker private constructor(context: Context) : ContextWrapper(context) { class DownloadWorker private constructor(context: Context) : ContextWrapper(context) {
@@ -159,6 +161,8 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
fun buildClient() = fun buildClient() =
OkHttpClient.Builder() OkHttpClient.Builder()
.addInterceptor(interceptor) .addInterceptor(interceptor)
.connectTimeout(0, TimeUnit.SECONDS)
.readTimeout(0, TimeUnit.SECONDS)
.dispatcher(Dispatcher(Executors.newFixedThreadPool(4))) .dispatcher(Dispatcher(Executors.newFixedThreadPool(4)))
.proxy(proxy) .proxy(proxy)
.build() .build()
@@ -279,6 +283,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
for (i in reader.galleryInfo.files.indices) { for (i in reader.galleryInfo.files.indices) {
val callback = object : Callback { val callback = object : Callback {
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
Log.i("PUPILD", "FAIL ${call.request().tag()} (${e.message})")
if (Fabric.isInitialized() && e.message != "Canceled") if (Fabric.isInitialized() && e.message != "Canceled")
Crashlytics.logException(e) Crashlytics.logException(e)
@@ -287,43 +292,57 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
notify(galleryID) notify(galleryID)
if (isCompleted(galleryID)) { CoroutineScope(Dispatchers.IO).launch {
if (isCompleted(galleryID) && clients.indexOfKey(galleryID) >= 0) {
clients.remove(galleryID)
with(Cache(this@DownloadWorker)) { with(Cache(this@DownloadWorker)) {
if (isDownloading(galleryID)) { if (isDownloading(galleryID)) {
moveToDownload(galleryID) moveToDownload(galleryID)
setDownloading(galleryID, false) setDownloading(galleryID, false)
} }
} }
clients.remove(galleryID) }
} }
} }
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
response.body().use { Log.i("PUPILD", "OK ${call.request().tag()}")
val res = it.bytes()
val ext =
call.request().url().encodedPath().split('.').last()
Cache(this@DownloadWorker).putImage(galleryID, "%05d.%s".format(i, ext), res) try {
progress[galleryID]?.set(i, Float.POSITIVE_INFINITY) val ext = call.request().url().encodedPath().split('.').last()
response.body().use {
Cache(this@DownloadWorker).putImage(galleryID, i, ext, it.byteStream())
} }
progress[galleryID]?.set(i, Float.POSITIVE_INFINITY)
notify(galleryID) notify(galleryID)
if (isCompleted(galleryID)) { CoroutineScope(Dispatchers.IO).launch {
if (isCompleted(galleryID) && clients.indexOfKey(galleryID) >= 0) {
clients.remove(galleryID)
with(Cache(this@DownloadWorker)) { with(Cache(this@DownloadWorker)) {
if (isDownloading(galleryID)) { if (isDownloading(galleryID)) {
moveToDownload(galleryID) moveToDownload(galleryID)
setDownloading(galleryID, false) setDownloading(galleryID, false)
} }
} }
clients.remove(galleryID) }
}
Log.i("PUPILD", "SUCCESS ${call.request().tag()}")
} catch (e: Exception) {
Log.i("PUPILD", "FAIL ON OK ${call.request().tag()} (${e.message})")
} }
} }
} }
if (progress[galleryID]?.get(i)?.isFinite() == true) if (progress[galleryID]?.get(i)?.isFinite() == true) {
queueDownload(galleryID, reader, i, callback) queueDownload(galleryID, reader, i, callback)
Log.i("PUPILD", "$galleryID QUEUED $i")
} else {
Log.i("PUPILD", "$galleryID SKIPPED $i (${progress[galleryID]?.get(i)})")
}
} }
} }
@@ -354,7 +373,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
} }
val pendingIntent = TaskStackBuilder.create(this).run { val pendingIntent = TaskStackBuilder.create(this).run {
addNextIntentWithParentStack(intent) addNextIntentWithParentStack(intent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) getPendingIntent(galleryID, PendingIntent.FLAG_UPDATE_CURRENT)
} }
notification.put(galleryID, NotificationCompat.Builder(this, "download").apply { notification.put(galleryID, NotificationCompat.Builder(this, "download").apply {
@@ -369,7 +388,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
private fun loop() = CoroutineScope(Dispatchers.Default).launch { private fun loop() = CoroutineScope(Dispatchers.Default).launch {
while (true) { while (true) {
if (queue.isEmpty() || clients.size() > preferences.getInt("max_download", 4)) if (queue.isEmpty() || clients.size() >= preferences.getInt("max_download", 4))
continue continue
val galleryID = queue.poll() ?: continue val galleryID = queue.poll() ?: continue

5555
dependencies.txt Normal file

File diff suppressed because it is too large Load Diff