Compare commits

..
8 Commits
Author SHA1 Message Date
tarsin ce823e9b20 Release 1.8.6.2
Releases / Build (push) Has been cancelled
2023-02-20 19:06:59 +08:00
FooIbar 0caa5b1a3b Fix 509 detection false positive 2023-02-20 19:06:13 +08:00
FooIbar 9edea5d584 Clean up unfinished download files 2023-02-20 18:48:49 +08:00
FooIbar 9a773aeb39 Workaround for del tag parsing in comments 2023-02-20 18:48:40 +08:00
FooIbar 9fd3196bb1 Use initializer instead of getter for coroutineContext 2023-02-20 18:48:34 +08:00
FooIbar 7580572874 Temporarily disable vpn bypass on login 2023-02-20 18:48:27 +08:00
tarsin 06acc620f4 Resolve #842 2023-02-20 18:48:19 +08:00
FooIbar 367358d277 Resolve #789 2023-02-20 18:48:13 +08:00
7 changed files with 46 additions and 27 deletions

No files matched your search

+2 -2
View File
@@ -34,8 +34,8 @@ android {
applicationId = "moe.tarsin.ehviewer"
minSdk = 28
targetSdk = 33
versionCode = 180033
versionName = "1.8.6.1"
versionCode = 180034
versionName = "1.8.6.2"
resourceConfigurations.addAll(
listOf(
"zh",
+1 -1
View File
@@ -36,7 +36,7 @@
<activity
android:name=".ui.login.LoginActivity"
android:exported="false"
android:theme="@style/AppTheme"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name=".ui.MainActivity"
@@ -91,7 +91,8 @@ object GalleryDetailParser {
// Error info
PATTERN_ERROR.find(body)?.run { throw EhException(groupValues[1]) }
val galleryDetail = GalleryDetail()
val document = Jsoup.parse(body)
// Temporary workaround, see https://github.com/jhy/jsoup/issues/1850
val document = Jsoup.parse(body.replace("del>", "s>"))
parseDetail(galleryDetail, document, body)
galleryDetail.tags = parseTagGroups(document)
galleryDetail.comments = parseComments(document)
@@ -36,6 +36,7 @@ import com.hippo.yorozuya.FileUtils
import com.hippo.yorozuya.MathUtils
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive
import moe.tarsin.coroutines.runSuspendCatching
import okhttp3.executeAsync
import okio.buffer
import java.io.File
@@ -194,7 +195,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
return receivedSize
}
findDownloadFileForIndex(index, extension)?.runCatching {
findDownloadFileForIndex(index, extension)?.runSuspendCatching {
openOutputStream().use { outputStream ->
(outputStream as FileOutputStream).channel.use { return doSave(it) == length }
}
@@ -208,7 +209,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
val key = EhCacheKeyFactory.getImageKey(mGid, index)
val editor = sCache.edit(key) ?: return false
var received: Long = 0
runCatching {
runSuspendCatching {
editor.metadata.toFile().writeText(extension)
editor.data.toFile().outputStream().use { outputStream ->
outputStream.channel.use { received = doSave(it) }
@@ -365,7 +365,7 @@ public final class SpiderQueen implements Runnable {
request(index, false);
}
private int getPageState(int index) {
public int getPageState(int index) {
synchronized (mPageStateLock) {
if (mPageStateArray != null && index >= 0 && index < mPageStateArray.length) {
return mPageStateArray[index];
@@ -12,9 +12,10 @@ import com.hippo.ehviewer.spider.SpiderQueen.NETWORK_ERROR
import com.hippo.ehviewer.spider.SpiderQueen.PTOKEN_FAILED_MESSAGE
import com.hippo.ehviewer.spider.SpiderQueen.STATE_FAILED
import com.hippo.ehviewer.spider.SpiderQueen.STATE_FINISHED
import com.hippo.ehviewer.spider.SpiderQueen.STATE_DOWNLOADING
import com.hippo.image.Image.Companion.decode
import com.hippo.util.ExceptionUtils
import com.hippo.yorozuya.StringUtils
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -27,7 +28,6 @@ import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.sync.withPermit
import moe.tarsin.coroutines.runSuspendCatching
import kotlin.coroutines.CoroutineContext
class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
private val spiderDen
@@ -42,8 +42,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
private var isDownloadMode = false
private val size
get() = queen.size()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + Job()
override val coroutineContext = Dispatchers.IO + Job()
fun cancelDecode(index: Int) {
decoder.cancel(index)
@@ -80,6 +79,15 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
mSemaphore.withPermit {
doInJob(index, force)
}
}.apply {
invokeOnCompletion {
if (queen.getPageState(index) == STATE_DOWNLOADING) {
Log.d(DEBUG_TAG, "Download image cancelled $index")
launchNonCancellable {
spiderDen.remove(index)
}
}
}
}
}
}
@@ -100,7 +108,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
?: queen.getPTokenFromInternet(index)
?: queen.getPTokenFromMultiPageViewer(index)
}
queen.updatePageState(index, SpiderQueen.STATE_DOWNLOADING)
queen.updatePageState(index, STATE_DOWNLOADING)
if (!force && index in spiderDen) {
return queen.updatePageState(index, STATE_FINISHED)
}
@@ -149,7 +157,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
}
runSuspendCatching {
getGalleryPage(pageUrl, spiderInfo.gid, spiderInfo.token).also {
if (StringUtils.endsWith(it.imageUrl, URL_509_SUFFIX_ARRAY)) {
if (check509(it.imageUrl)) {
// Get 509
queen.notifyGet509(index)
error = ERROR_509
@@ -200,7 +208,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
localShowKey,
previousPToken
).also {
if (StringUtils.endsWith(it.imageUrl, URL_509_SUFFIX_ARRAY)) {
if (check509(it.imageUrl)) {
// Get 509
queen.notifyGet509(index)
error = ERROR_509
@@ -270,6 +278,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
}.onFailure {
it.printStackTrace()
error = NETWORK_ERROR
forceHtml = true
}
Log.d(DEBUG_TAG, "End download image $index")
}
@@ -278,10 +287,13 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
}
companion object {
private val URL_509_SUFFIX_ARRAY = arrayOf(
"/509.gif",
"/509s.gif"
private val URL_509_ARRAY = arrayOf(
"https://ehgt.org/g/509.gif",
"https://ehgt.org/g/509s.gif",
"https://exhentai.org/img/509.gif",
"https://exhentai.org/img/509s.gif"
)
private fun check509(url: String) = url in URL_509_ARRAY
private const val DEBUG_TAG = "SpiderQueenWorker"
}
@@ -89,8 +89,8 @@ import java.io.OutputStream
class MainActivity : EhActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
private lateinit var connectivityManager: ConnectivityManager
private val availableNetworks: MutableList<Network> = mutableListOf()
private val connectivityManager by lazy { getSystemService<ConnectivityManager>()!! }
private val availableNetworks = mutableListOf<Network>()
private fun saveImageToTempFile(uri: Uri): File? {
val src = ImageDecoder.createSource(contentResolver, uri)
@@ -223,7 +223,6 @@ class MainActivity : EhActivity() {
}
override fun onCreate(savedInstanceState: Bundle?) {
connectivityManager = getSystemService()!!
if (Settings.getDF() && Settings.getBypassVpn()) {
bypassVpn()
}
@@ -233,13 +232,7 @@ class MainActivity : EhActivity() {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
navController = navHostFragment.navController
if (EhUtils.needSignedIn()) {
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
setNavGraph()
}.launch(Intent(this, LoginActivity::class.java))
} else {
setNavGraph()
}
if (!EhUtils.needSignedIn()) setNavGraph()
binding.drawView.addDrawerListener(mDrawerOnBackPressedCallback)
binding.navView.setupWithNavController(navController)
@@ -371,7 +364,19 @@ class MainActivity : EhActivity() {
}
}
private val loginLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (availableNetworks.isNotEmpty()) {
connectivityManager.bindProcessToNetwork(availableNetworks.last())
}
setNavGraph()
}
override fun onResume() {
if (EhUtils.needSignedIn()) {
connectivityManager.bindProcessToNetwork(null)
loginLauncher.launch(Intent(this, LoginActivity::class.java))
}
super.onResume()
lifecycleScope.launch {
delay(100)