diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 0469fdc04..19bb80eec 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -524,38 +524,36 @@ class AnalyzeRule(private var book: BaseBook? = null) { /** * js实现跨域访问,不能删 */ -// fun ajax(urlStr: String): String? { -// try { -// val analyzeUrl = AnalyzeUrl(urlStr) -// val response = BaseModelImpl.getInstance().getResponseO(analyzeUrl) -// .blockingFirst() -// return response.body() -// } catch (e: Exception) { -// return e.localizedMessage -// } -// -// } + suspend fun ajax(urlStr: String): String? { + return try { + val analyzeUrl = AnalyzeUrl(urlStr) + val response = analyzeUrl.getResponseAsync().await() + response.body() + } catch (e: Exception) { + e.localizedMessage + } + } /** * js实现解码,不能删 */ -// fun base64Decoder(base64: String): String { -// return StringUtils.base64Decode(base64) -// } + fun base64Decoder(str: String): String { + return Encoder.base64Decoder(str) + } /** * 章节数转数字 */ -// fun toNumChapter(s: String?): String? { -// if (s == null) { -// return null -// } -// val pattern = Pattern.compile("(第)(.+?)(章)") -// val matcher = pattern.matcher(s) -// return if (matcher.find()) { -// matcher.group(1) + StringUtils.stringToInt(matcher.group(2)) + matcher.group(3) -// } else s -// } + fun toNumChapter(s: String?): String? { + if (s == null) { + return null + } + val pattern = Pattern.compile("(第)(.+?)(章)") + val matcher = pattern.matcher(s) + return if (matcher.find()) { + matcher.group(1) + StringUtils.stringToInt(matcher.group(2)) + matcher.group(3) + } else s + } companion object { private val putPattern = Pattern.compile("@put:(\\{[^}]+?\\})", Pattern.CASE_INSENSITIVE) diff --git a/app/src/main/java/io/legado/app/utils/Encoder.kt b/app/src/main/java/io/legado/app/utils/Encoder.kt index 8f97c4c83..f14785af9 100644 --- a/app/src/main/java/io/legado/app/utils/Encoder.kt +++ b/app/src/main/java/io/legado/app/utils/Encoder.kt @@ -1,5 +1,8 @@ package io.legado.app.utils +import android.util.Base64 +import java.nio.charset.StandardCharsets + object Encoder { fun escape(src: String): String { @@ -20,4 +23,13 @@ object Encoder { } return tmp.toString() } + + fun base64Decoder(str: String): String { + val bytes = Base64.decode(str, Base64.DEFAULT) + return try { + String(bytes, StandardCharsets.UTF_8) + } catch (e: Exception) { + String(bytes) + } + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/StringUtils.kt b/app/src/main/java/io/legado/app/utils/StringUtils.kt new file mode 100644 index 000000000..031e0f705 --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/StringUtils.kt @@ -0,0 +1,255 @@ +package io.legado.app.utils + +import android.annotation.SuppressLint +import android.text.TextUtils +import android.text.TextUtils.isEmpty +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* +import java.util.regex.Matcher +import java.util.regex.Pattern + +object StringUtils { + private val TAG = "StringUtils" + private const val HOUR_OF_DAY = 24 + private const val DAY_OF_YESTERDAY = 2 + private const val TIME_UNIT = 60 + private val ChnMap = chnMap + + private val chnMap: HashMap + get() { + val map = HashMap() + var cnStr = "零一二三四五六七八九十" + var c = cnStr.toCharArray() + for (i in 0..10) { + map[c[i]] = i + } + cnStr = "〇壹贰叁肆伍陆柒捌玖拾" + c = cnStr.toCharArray() + for (i in 0..10) { + map[c[i]] = i + } + map['两'] = 2 + map['百'] = 100 + map['佰'] = 100 + map['千'] = 1000 + map['仟'] = 1000 + map['万'] = 10000 + map['亿'] = 100000000 + return map + } + + //将时间转换成日期 + fun dateConvert(time: Long, pattern: String): String { + val date = Date(time) + @SuppressLint("SimpleDateFormat") val format = SimpleDateFormat(pattern) + return format.format(date) + } + + //将日期转换成昨天、今天、明天 + fun dateConvert(source: String, pattern: String): String { + @SuppressLint("SimpleDateFormat") val format = SimpleDateFormat(pattern) + val calendar = Calendar.getInstance() + try { + val date = format.parse(source) + val curTime = calendar.timeInMillis + calendar.time = date + //将MISC 转换成 sec + val difSec = Math.abs((curTime - date.time) / 1000) + val difMin = difSec / 60 + val difHour = difMin / 60 + val difDate = difHour / 60 + val oldHour = calendar.get(Calendar.HOUR) + //如果没有时间 + if (oldHour == 0) { + //比日期:昨天今天和明天 + if (difDate == 0L) { + return "今天" + } else if (difDate < DAY_OF_YESTERDAY) { + return "昨天" + } else { + @SuppressLint("SimpleDateFormat") val convertFormat = SimpleDateFormat("yyyy-MM-dd") + return convertFormat.format(date) + } + } + + return when { + difSec < TIME_UNIT -> difSec.toString() + "秒前" + difMin < TIME_UNIT -> difMin.toString() + "分钟前" + difHour < HOUR_OF_DAY -> difHour.toString() + "小时前" + difDate < DAY_OF_YESTERDAY -> "昨天" + else -> { + @SuppressLint("SimpleDateFormat") val convertFormat = SimpleDateFormat("yyyy-MM-dd") + convertFormat.format(date) + } + } + } catch (e: ParseException) { + e.printStackTrace() + } + + return "" + } + + @SuppressLint("DefaultLocale") + fun toFirstCapital(str: String): String { + return str.substring(0, 1).toUpperCase() + str.substring(1) + } + + /** + * 将文本中的半角字符,转换成全角字符 + */ + fun halfToFull(input: String): String { + val c = input.toCharArray() + for (i in c.indices) { + if (c[i].toInt() == 32) + //半角空格 + { + c[i] = 12288.toChar() + continue + } + //根据实际情况,过滤不需要转换的符号 + //if (c[i] == 46) //半角点号,不转换 + // continue; + + if (c[i].toInt() in 33..126) + //其他符号都转换为全角 + c[i] = (c[i].toInt() + 65248).toChar() + } + return String(c) + } + + //功能:字符串全角转换为半角 + fun fullToHalf(input: String): String { + val c = input.toCharArray() + for (i in c.indices) { + if (c[i].toInt() == 12288) + //全角空格 + { + c[i] = 32.toChar() + continue + } + + if (c[i].toInt() in 65281..65374) + c[i] = (c[i].toInt() - 65248).toChar() + } + return String(c) + } + + fun chineseNumToInt(chNum: String): Int { + var result = 0 + var tmp = 0 + var billion = 0 + val cn = chNum.toCharArray() + + // "一零二五" 形式 + if (cn.size > 1 && chNum.matches("^[〇零一二三四五六七八九壹贰叁肆伍陆柒捌玖]$".toRegex())) { + for (i in cn.indices) { + cn[i] = (48 + ChnMap[cn[i]]!!).toChar() + } + return Integer.parseInt(String(cn)) + } + + // "一千零二十五", "一千二" 形式 + try { + for (i in cn.indices) { + val tmpNum = ChnMap[cn[i]]!! + if (tmpNum == 100000000) { + result += tmp + result *= tmpNum + billion = billion * 100000000 + result + result = 0 + tmp = 0 + } else if (tmpNum == 10000) { + result += tmp + result *= tmpNum + tmp = 0 + } else if (tmpNum >= 10) { + if (tmp == 0) + tmp = 1 + result += tmpNum * tmp + tmp = 0 + } else { + tmp = if (i >= 2 && i == cn.size - 1 && ChnMap[cn[i - 1]]!! > 10) + tmpNum * ChnMap[cn[i - 1]]!! / 10 + else + tmp * 10 + tmpNum + } + } + result += tmp + billion + return result + } catch (e: Exception) { + return -1 + } + + } + + fun stringToInt(str: String?): Int { + if (str != null) { + val num = fullToHalf(str).replace("\\s".toRegex(), "") + return try { + Integer.parseInt(num) + } catch (e: Exception) { + chineseNumToInt(num) + } + + } + return -1 + } + + fun isContainNumber(company: String): Boolean { + val p = Pattern.compile("[0-9]") + val m = p.matcher(company) + return m.find() + } + + fun isNumeric(str: String): Boolean { + val pattern = Pattern.compile("[0-9]*") + val isNum = pattern.matcher(str) + return isNum.matches() + } + + // 移除字符串首尾空字符的高效方法(利用ASCII值判断,包括全角空格) + fun trim(s: String): String { + if (isEmpty(s)) return "" + var start = 0 + val len = s.length + var end = len - 1 + while (start < end && (s[start].toInt() <= 0x20 || s[start] == ' ')) { + ++start + } + while (start < end && (s[end].toInt() <= 0x20 || s[end] == ' ')) { + --end + } + if (end < len) ++end + return if (start > 0 || end < len) s.substring(start, end) else s + } + + fun repeat(str: String, n: Int): String { + val stringBuilder = StringBuilder() + for (i in 0 until n) { + stringBuilder.append(str) + } + return stringBuilder.toString() + } + + fun removeUTFCharacters(data: String?): String? { + if (data == null) return null + val p = Pattern.compile("\\\\u(\\p{XDigit}{4})") + val m = p.matcher(data) + val buf = StringBuffer(data.length) + while (m.find()) { + val ch = Integer.parseInt(m.group(1), 16).toChar().toString() + m.appendReplacement(buf, Matcher.quoteReplacement(ch)) + } + m.appendTail(buf) + return buf.toString() + } + + fun formatHtml(html: String): String { + return if (TextUtils.isEmpty(html)) "" else html.replace("(?i)<(br[\\s/]*|/*p.*?|/*div.*?)>".toRegex(), "\n")// 替换特定标签为换行符 + .replace("<[script>]*.*?>| ".toRegex(), "")// 删除script标签对和空格转义符 + .replace("\\s*\\n+\\s*".toRegex(), "\n  ")// 移除空行,并增加段前缩进2个汉字 + .replace("^[\\n\\s]+".toRegex(), "  ")//移除开头空行,并增加段前缩进2个汉字 + .replace("[\\n\\s]+$".toRegex(), "") //移除尾部空行 + } +}