|
|
@ -3,9 +3,9 @@ package io.legado.app.model.analyzeRule |
|
|
|
import android.annotation.SuppressLint |
|
|
|
import android.annotation.SuppressLint |
|
|
|
import android.util.Base64 |
|
|
|
import android.util.Base64 |
|
|
|
import androidx.annotation.Keep |
|
|
|
import androidx.annotation.Keep |
|
|
|
|
|
|
|
import cn.hutool.core.util.HexUtil |
|
|
|
import com.bumptech.glide.load.model.GlideUrl |
|
|
|
import com.bumptech.glide.load.model.GlideUrl |
|
|
|
import com.script.SimpleBindings |
|
|
|
import com.script.SimpleBindings |
|
|
|
import cn.hutool.core.util.HexUtil |
|
|
|
|
|
|
|
import io.legado.app.constant.AppConst.SCRIPT_ENGINE |
|
|
|
import io.legado.app.constant.AppConst.SCRIPT_ENGINE |
|
|
|
import io.legado.app.constant.AppConst.UA_NAME |
|
|
|
import io.legado.app.constant.AppConst.UA_NAME |
|
|
|
import io.legado.app.constant.AppPattern.JS_PATTERN |
|
|
|
import io.legado.app.constant.AppPattern.JS_PATTERN |
|
|
@ -279,6 +279,7 @@ class AnalyzeUrl( |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 开始访问,并发判断 |
|
|
|
* 开始访问,并发判断 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
private fun fetchStart(): ConcurrentRecord? { |
|
|
|
private fun fetchStart(): ConcurrentRecord? { |
|
|
|
source ?: return null |
|
|
|
source ?: return null |
|
|
|
val concurrentRate = source.concurrentRate |
|
|
|
val concurrentRate = source.concurrentRate |
|
|
@ -294,10 +295,13 @@ class AnalyzeUrl( |
|
|
|
} |
|
|
|
} |
|
|
|
val waitTime: Int = synchronized(fetchRecord) { |
|
|
|
val waitTime: Int = synchronized(fetchRecord) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
if (rateIndex == -1) { |
|
|
|
if (!fetchRecord.isConcurrent) { |
|
|
|
|
|
|
|
//并发控制非 次数/毫秒 |
|
|
|
if (fetchRecord.frequency > 0) { |
|
|
|
if (fetchRecord.frequency > 0) { |
|
|
|
|
|
|
|
//已经有访问线程,直接等待 |
|
|
|
return@synchronized concurrentRate.toInt() |
|
|
|
return@synchronized concurrentRate.toInt() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//没有线程访问,判断还剩多少时间可以访问 |
|
|
|
val nextTime = fetchRecord.time + concurrentRate.toInt() |
|
|
|
val nextTime = fetchRecord.time + concurrentRate.toInt() |
|
|
|
if (System.currentTimeMillis() >= nextTime) { |
|
|
|
if (System.currentTimeMillis() >= nextTime) { |
|
|
|
fetchRecord.time = System.currentTimeMillis() |
|
|
|
fetchRecord.time = System.currentTimeMillis() |
|
|
@ -306,9 +310,11 @@ class AnalyzeUrl( |
|
|
|
} |
|
|
|
} |
|
|
|
return@synchronized (nextTime - System.currentTimeMillis()).toInt() |
|
|
|
return@synchronized (nextTime - System.currentTimeMillis()).toInt() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
//并发控制为 次数/毫秒 |
|
|
|
val sj = concurrentRate.substring(rateIndex + 1) |
|
|
|
val sj = concurrentRate.substring(rateIndex + 1) |
|
|
|
val nextTime = fetchRecord.time + sj.toInt() |
|
|
|
val nextTime = fetchRecord.time + sj.toInt() |
|
|
|
if (System.currentTimeMillis() >= nextTime) { |
|
|
|
if (System.currentTimeMillis() >= nextTime) { |
|
|
|
|
|
|
|
//已经过了限制时间,重置开始时间 |
|
|
|
fetchRecord.time = System.currentTimeMillis() |
|
|
|
fetchRecord.time = System.currentTimeMillis() |
|
|
|
fetchRecord.frequency = 1 |
|
|
|
fetchRecord.frequency = 1 |
|
|
|
return@synchronized 0 |
|
|
|
return@synchronized 0 |
|
|
@ -335,7 +341,7 @@ class AnalyzeUrl( |
|
|
|
* 访问结束 |
|
|
|
* 访问结束 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun fetchEnd(concurrentRecord: ConcurrentRecord?) { |
|
|
|
private fun fetchEnd(concurrentRecord: ConcurrentRecord?) { |
|
|
|
if (concurrentRecord != null && !concurrentRecord.concurrent) { |
|
|
|
if (concurrentRecord != null && !concurrentRecord.isConcurrent) { |
|
|
|
synchronized(concurrentRecord) { |
|
|
|
synchronized(concurrentRecord) { |
|
|
|
concurrentRecord.frequency = concurrentRecord.frequency - 1 |
|
|
|
concurrentRecord.frequency = concurrentRecord.frequency - 1 |
|
|
|
} |
|
|
|
} |
|
|
@ -345,6 +351,7 @@ class AnalyzeUrl( |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 访问网站,返回StrResponse |
|
|
|
* 访问网站,返回StrResponse |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
suspend fun getStrResponseAwait( |
|
|
|
suspend fun getStrResponseAwait( |
|
|
|
jsStr: String? = null, |
|
|
|
jsStr: String? = null, |
|
|
|
sourceRegex: String? = null, |
|
|
|
sourceRegex: String? = null, |
|
|
@ -414,6 +421,7 @@ class AnalyzeUrl( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads |
|
|
|
@JvmOverloads |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
fun getStrResponse( |
|
|
|
fun getStrResponse( |
|
|
|
jsStr: String? = null, |
|
|
|
jsStr: String? = null, |
|
|
|
sourceRegex: String? = null, |
|
|
|
sourceRegex: String? = null, |
|
|
@ -427,6 +435,7 @@ class AnalyzeUrl( |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 访问网站,返回Response |
|
|
|
* 访问网站,返回Response |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
suspend fun getResponseAwait(): Response { |
|
|
|
suspend fun getResponseAwait(): Response { |
|
|
|
val concurrentRecord = fetchStart() |
|
|
|
val concurrentRecord = fetchStart() |
|
|
|
try { |
|
|
|
try { |
|
|
@ -457,6 +466,7 @@ class AnalyzeUrl( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
fun getResponse(): Response { |
|
|
|
fun getResponse(): Response { |
|
|
|
return runBlocking { |
|
|
|
return runBlocking { |
|
|
|
getResponseAwait() |
|
|
|
getResponseAwait() |
|
|
@ -464,6 +474,7 @@ class AnalyzeUrl( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Suppress("UnnecessaryVariable") |
|
|
|
@Suppress("UnnecessaryVariable") |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
private fun getByteArrayIfDataUri(): ByteArray? { |
|
|
|
private fun getByteArrayIfDataUri(): ByteArray? { |
|
|
|
@Suppress("RegExpRedundantEscape") |
|
|
|
@Suppress("RegExpRedundantEscape") |
|
|
|
val dataUriFindResult = dataUriRegex.find(urlNoQuery) |
|
|
|
val dataUriFindResult = dataUriRegex.find(urlNoQuery) |
|
|
@ -480,6 +491,7 @@ class AnalyzeUrl( |
|
|
|
* 访问网站,返回ByteArray |
|
|
|
* 访问网站,返回ByteArray |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Suppress("UnnecessaryVariable", "LiftReturnOrAssignment") |
|
|
|
@Suppress("UnnecessaryVariable", "LiftReturnOrAssignment") |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
suspend fun getByteArrayAwait(): ByteArray { |
|
|
|
suspend fun getByteArrayAwait(): ByteArray { |
|
|
|
getByteArrayIfDataUri()?.let { |
|
|
|
getByteArrayIfDataUri()?.let { |
|
|
|
return it |
|
|
|
return it |
|
|
@ -497,6 +509,7 @@ class AnalyzeUrl( |
|
|
|
* 访问网站,返回InputStream |
|
|
|
* 访问网站,返回InputStream |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Suppress("LiftReturnOrAssignment") |
|
|
|
@Suppress("LiftReturnOrAssignment") |
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
suspend fun getInputStreamAwait(): InputStream { |
|
|
|
suspend fun getInputStreamAwait(): InputStream { |
|
|
|
getByteArrayIfDataUri()?.let { |
|
|
|
getByteArrayIfDataUri()?.let { |
|
|
|
return ByteArrayInputStream(it) |
|
|
|
return ByteArrayInputStream(it) |
|
|
@ -504,6 +517,7 @@ class AnalyzeUrl( |
|
|
|
return getResponseAwait().body!!.byteStream() |
|
|
|
return getResponseAwait().body!!.byteStream() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Throws(ConcurrentException::class) |
|
|
|
fun getInputStream(): InputStream { |
|
|
|
fun getInputStream(): InputStream { |
|
|
|
return runBlocking { |
|
|
|
return runBlocking { |
|
|
|
getInputStreamAwait() |
|
|
|
getInputStreamAwait() |
|
|
@ -679,8 +693,17 @@ class AnalyzeUrl( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
data class ConcurrentRecord( |
|
|
|
data class ConcurrentRecord( |
|
|
|
val concurrent: Boolean, |
|
|
|
/** |
|
|
|
|
|
|
|
* 是否按频率 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
val isConcurrent: Boolean, |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 开始访问时间 |
|
|
|
|
|
|
|
*/ |
|
|
|
var time: Long, |
|
|
|
var time: Long, |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 正在访问的个数 |
|
|
|
|
|
|
|
*/ |
|
|
|
var frequency: Int |
|
|
|
var frequency: Int |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|