Remove jsoup usage and clean up
This commit is contained in:
1 parent
5dc02c0bd5
commit
95631ef468
17 files changed
+46
-57
No files matched your search
@@ -98,7 +98,6 @@ Here is the libraries
|
||||
- [Coil](https://coil-kt.github.io/coil/)
|
||||
- [Compose Destinations](https://composedestinations.rafaelcosta.xyz/)
|
||||
- [libarchive](https://www.libarchive.org/)
|
||||
- [jsoup](https://jsoup.org/)
|
||||
|
||||
# License
|
||||
|
||||
|
||||
@@ -240,7 +240,6 @@ dependencies {
|
||||
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.jsoup)
|
||||
|
||||
coreLibraryDesugaring(libs.desugar)
|
||||
|
||||
|
||||
@@ -178,7 +178,8 @@ object EhEngine {
|
||||
location.takeIf { "bounce_login" !in it } ?: throw NotLoggedInException()
|
||||
}
|
||||
|
||||
suspend fun getTorrentList(url: String, gid: Long, token: String): TorrentResult {
|
||||
suspend fun getTorrentList(gid: Long, token: String): TorrentResult {
|
||||
val url = EhUrl.getTorrentUrl(gid, token)
|
||||
val referer = EhUrl.getGalleryDetailUrl(gid, token)
|
||||
return ehRequest(url, referer).fetchUsingAsByteBuffer(TorrentParser::parse)
|
||||
}
|
||||
@@ -188,7 +189,8 @@ object EhEngine {
|
||||
"${id}x$key"
|
||||
}
|
||||
|
||||
suspend fun getArchiveList(url: String, gid: Long, token: String): ArchiveParser.Result {
|
||||
suspend fun getArchiveList(gid: Long, token: String): ArchiveParser.Result {
|
||||
val url = EhUrl.getArchiveUrl(gid, token)
|
||||
val funds = if (EhUtils.isExHentai) getFunds() else null
|
||||
return ehRequest(url, EhUrl.getGalleryDetailUrl(gid, token))
|
||||
.fetchUsingAsByteBuffer(ArchiveParser::parse.partially2(funds))
|
||||
@@ -304,7 +306,7 @@ object EhEngine {
|
||||
.fetchUsingAsText(FavoritesParser::parseNote)
|
||||
|
||||
suspend fun downloadArchive(gid: Long, token: String, res: String, isHath: Boolean): String? {
|
||||
val url = EhUrl.getDownloadArchive(gid, token)
|
||||
val url = EhUrl.getArchiveUrl(gid, token)
|
||||
val referer = EhUrl.getGalleryDetailUrl(gid, token)
|
||||
val request = ehRequest(url, referer, EhUrl.origin) {
|
||||
formBody {
|
||||
|
||||
@@ -125,7 +125,12 @@ object EhUrl {
|
||||
addQueryParameter("act", "addfav")
|
||||
}.buildString()
|
||||
|
||||
fun getDownloadArchive(gid: Long, token: String) = ehUrl("archiver.php") {
|
||||
fun getArchiveUrl(gid: Long, token: String) = ehUrl("archiver.php") {
|
||||
addQueryParameter("gid", "$gid")
|
||||
addQueryParameter("token", token)
|
||||
}.buildString()
|
||||
|
||||
fun getTorrentUrl(gid: Long, token: String) = ehUrl("gallerytorrents.php") {
|
||||
addQueryParameter("gid", "$gid")
|
||||
addQueryParameter("token", token)
|
||||
}.buildString()
|
||||
|
||||
@@ -44,8 +44,6 @@ data class GalleryDetail(
|
||||
var apiUid: Long = -1L,
|
||||
var apiKey: String? = null,
|
||||
var torrentCount: Int = 0,
|
||||
var torrentUrl: String? = null,
|
||||
var archiveUrl: String? = null,
|
||||
var parent: String? = null,
|
||||
var newerVersions: List<BaseGalleryInfo> = emptyList(),
|
||||
var visible: String? = null,
|
||||
|
||||
@@ -25,9 +25,9 @@ object HomeParser {
|
||||
?: throw ParseException("Parse torrent key error")
|
||||
|
||||
fun parseFunds(body: String): Funds {
|
||||
FundsRegex.find(body)?.groupValues?.run {
|
||||
val fundsC = ParserUtils.parseInt(get(1), 0)
|
||||
val fundsGP = ParserUtils.parseInt(get(2), 0)
|
||||
FundsRegex.find(body)?.run {
|
||||
val fundsC = ParserUtils.parseInt(groupValues[1], 0)
|
||||
val fundsGP = ParserUtils.parseInt(groupValues[2], 0)
|
||||
return Funds(fundsGP, fundsC)
|
||||
}
|
||||
throw ParseException("Parse funds error")
|
||||
|
||||
@@ -18,8 +18,6 @@ package com.hippo.ehviewer.client.parser
|
||||
import com.hippo.ehviewer.util.toEpochMillis
|
||||
import com.hippo.ehviewer.util.toIntOrDefault
|
||||
import com.hippo.ehviewer.util.toLocalDateTime
|
||||
import com.hippo.ehviewer.util.toLongOrDefault
|
||||
import com.hippo.ehviewer.util.unescapeXml
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.format.char
|
||||
|
||||
@@ -41,9 +39,5 @@ object ParserUtils {
|
||||
|
||||
fun parseDate(str: String): Long = formatter.parse(str).toEpochMillis()
|
||||
|
||||
fun trim(str: String?): String = str?.unescapeXml()?.trim().orEmpty()
|
||||
|
||||
fun parseInt(str: String?, defValue: Int): Int = trim(str).replace(",", "").toIntOrDefault(defValue)
|
||||
|
||||
fun parseLong(str: String?, defValue: Long): Long = trim(str).replace(",", "").toLongOrDefault(defValue)
|
||||
fun parseInt(str: String, defValue: Int): Int = str.replace(",", "").toIntOrDefault(defValue)
|
||||
}
|
||||
@@ -58,7 +58,7 @@ private fun GalleryDetail.content() = arrayOf(
|
||||
R.string.key_rating_count to ratingCount.toString(),
|
||||
R.string.key_rating to rating.toString(),
|
||||
R.string.key_torrents to torrentCount.toString(),
|
||||
R.string.key_torrent_url to torrentUrl,
|
||||
R.string.key_torrent_url to EhUrl.getTorrentUrl(gid, token),
|
||||
R.string.favorite_name to favoriteName,
|
||||
)
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@ fun BelowHeader(galleryDetail: GalleryDetail, voteTag: VoteTag) {
|
||||
val archiveResult = remember(galleryDetail) {
|
||||
async(Dispatchers.IO + Job(), CoroutineStart.LAZY) {
|
||||
with(galleryDetail) {
|
||||
EhEngine.getArchiveList(archiveUrl!!, gid, token)
|
||||
EhEngine.getArchiveList(gid, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -598,7 +598,7 @@ fun BelowHeader(galleryDetail: GalleryDetail, voteTag: VoteTag) {
|
||||
val torrentResult = remember(galleryDetail) {
|
||||
async(Dispatchers.IO + Job(), CoroutineStart.LAZY) {
|
||||
parZip(
|
||||
{ EhEngine.getTorrentList(galleryDetail.torrentUrl!!, galleryDetail.gid, galleryDetail.token) },
|
||||
{ EhEngine.getTorrentList(galleryDetail.gid, galleryDetail.token) },
|
||||
{ EhEngine.getTorrentKey() },
|
||||
{ list, key -> list to key },
|
||||
)
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package com.hippo.ehviewer.util
|
||||
|
||||
import org.jsoup.parser.Parser
|
||||
private val EntityRegex = "&(?:amp|lt|gt|quot|#039);".toRegex()
|
||||
private val EntityMap = mapOf(
|
||||
"&" to "&",
|
||||
"<" to "<",
|
||||
">" to ">",
|
||||
""" to "\"",
|
||||
"'" to "'", // HTML uses ' instead of '
|
||||
)
|
||||
|
||||
fun String.unescapeXml(): String = Parser.unescapeEntities(this, true)
|
||||
|
||||
inline infix fun <T> CharSequence.trimAnd(block: CharSequence.() -> T): T = block(trim())
|
||||
fun String.unescapeXml() = replace(EntityRegex) { EntityMap[it.value]!! }
|
||||
|
||||
fun String.toIntOrDefault(defaultValue: Int): Int = toIntOrNull() ?: defaultValue
|
||||
|
||||
fun String.toLongOrDefault(defaultValue: Long): Long = toLongOrNull() ?: defaultValue
|
||||
|
||||
fun String.toFloatOrDefault(defaultValue: Float): Float = toFloatOrNull() ?: defaultValue
|
||||
|
||||
fun String?.containsIgnoreCase(other: String) = this?.contains(other, true) == true
|
||||
@@ -14,8 +14,6 @@ pub struct GalleryDetail {
|
||||
pub apiUid: i64,
|
||||
pub apiKey: Option<String>,
|
||||
pub torrentCount: i32,
|
||||
pub torrentUrl: Option<String>,
|
||||
pub archiveUrl: Option<String>,
|
||||
pub parent: Option<String>,
|
||||
pub newerVersions: Vec<BaseGalleryInfo>,
|
||||
pub visible: Option<String>,
|
||||
@@ -148,22 +146,16 @@ fn parse_detail(gd: &mut GalleryDetail, dom: &VDom, parser: &Parser, body: &str)
|
||||
gd.apiKey = Some(caps[4].to_string());
|
||||
gd.galleryInfo.rating = caps[5].parse().ok()?;
|
||||
|
||||
let torrent_regex = regex!(
|
||||
r#"<a[^<>]*onclick="return popUp\('([^']+)'[^)]+\)">Torrent Download \((\d+)\)</a>"#
|
||||
);
|
||||
let caps = torrent_regex.captures(body)?;
|
||||
gd.torrentUrl = unescape(&caps[1]).ok().map(|s| s.to_string());
|
||||
gd.torrentCount = caps[2].parse().ok()?;
|
||||
|
||||
let archive_regex =
|
||||
regex!(r#"<a[^<>]*onclick="return popUp\('([^']+)'[^)]+\)">Archive Download</a>"#);
|
||||
let caps = archive_regex.captures(body)?;
|
||||
gd.archiveUrl = unescape(&caps[1]).ok().map(|s| s.to_string());
|
||||
let regex = regex!(r#"[^(]+\(([^)]+)"#);
|
||||
let gd5 = dom.get_element_by_id("gd5")?.get(parser)?.as_tag()?;
|
||||
let node = gd5.query_selector(parser, "a[onclick]")?.nth(1)?;
|
||||
let text = node.get(parser)?.inner_text(parser);
|
||||
let caps = regex.captures(&text)?;
|
||||
gd.torrentCount = caps[1].parse().ok()?;
|
||||
|
||||
let gd1 = dom.get_element_by_id("gd1")?.get(parser)?.as_tag()?;
|
||||
let style = get_tag_attr(get_first_child(gd1, parser)?, "style")?;
|
||||
let cover_regex = regex!(r#"[^(]+\(([^)]+)"#);
|
||||
let caps = cover_regex.captures(style)?;
|
||||
let caps = regex.captures(style)?;
|
||||
gd.galleryInfo.thumbKey = get_thumb_key(&caps[1]);
|
||||
|
||||
let title = dom.get_element_by_id("gn")?.get(parser)?.inner_text(parser);
|
||||
|
||||
@@ -96,11 +96,8 @@ fn parse_uploader_and_pages(str: &str) -> (Option<String>, bool, i32) {
|
||||
regex!(r#"<a href="https://e[x-]hentai.org/uploader/.*?">(.*?)</a>|(\(Disowned\))"#)
|
||||
.captures(str)
|
||||
.map(|grp| {
|
||||
grp.get(1)
|
||||
.or_else(|| grp.get(2))
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.to_string()
|
||||
let str = grp.get(1).or_else(|| grp.get(2)).unwrap().as_str();
|
||||
unescape(str).as_deref().unwrap_or(str).to_string()
|
||||
});
|
||||
let pages = match regex!(r"<div>(\d+) pages</div>").captures(str) {
|
||||
None => 0,
|
||||
@@ -155,7 +152,8 @@ fn parse_gallery_info(node: &Node, parser: &Parser) -> Option<BaseGalleryInfo> {
|
||||
None => ("".to_string(), None),
|
||||
Some(node) => (
|
||||
node.inner_text(parser).trim().to_string(),
|
||||
get_node_attr(node, "title").map(str::to_string),
|
||||
get_node_attr(node, "title")
|
||||
.map(|s| unescape(s).as_deref().unwrap_or(s).to_string()),
|
||||
),
|
||||
};
|
||||
let ir = get_first_element_by_class_name(node, parser, "ir")?
|
||||
@@ -168,8 +166,11 @@ fn parse_gallery_info(node: &Node, parser: &Parser) -> Option<BaseGalleryInfo> {
|
||||
None => (None, false, 0),
|
||||
Some(node) => parse_uploader_and_pages(&node.get(parser)?.inner_html(parser)),
|
||||
};
|
||||
let favorite_note = get_element_by_id(node, parser, format!("favnote_{gid}").as_str())
|
||||
.map(|e| e.inner_text(parser).to_string());
|
||||
let favorite_note =
|
||||
get_element_by_id(node, parser, format!("favnote_{gid}").as_str()).map(|e| {
|
||||
let str = e.inner_text(parser);
|
||||
unescape(&str).as_deref().unwrap_or(&str).to_string()
|
||||
});
|
||||
Some(BaseGalleryInfo {
|
||||
gid,
|
||||
token,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{EhError, get_node_handle_attr, get_tag_attr, select_first};
|
||||
use anyhow::{Context, Result};
|
||||
use quick_xml::escape::unescape;
|
||||
use serde::Serialize;
|
||||
use tl::{Parser, VDom};
|
||||
|
||||
@@ -26,7 +27,8 @@ pub fn parse_profile(dom: &VDom, parser: &Parser) -> Result<Profile> {
|
||||
.next()
|
||||
.and_then(|n| {
|
||||
let mut iter = n.get(parser)?.as_tag()?.query_selector(parser, "div")?;
|
||||
let display_name = iter.next()?.get(parser)?.inner_text(parser).to_string();
|
||||
let str = iter.next()?.get(parser)?.inner_text(parser);
|
||||
let display_name = unescape(&str).as_deref().unwrap_or(&str).to_string();
|
||||
let avatar = iter.next().and_then(|n| {
|
||||
let img = select_first(n.get(parser)?.as_tag()?, parser, "img")?;
|
||||
get_tag_attr(img, "src").map(|src| {
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
- [Coil](https://coil-kt.github.io/coil/)
|
||||
- [Compose Destinations](https://composedestinations.rafaelcosta.xyz/)
|
||||
- [libarchive](https://www.libarchive.org/)
|
||||
- [jsoup](https://jsoup.org/)
|
||||
|
||||
# ライセンス
|
||||
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
- [Coil](https://coil-kt.github.io/coil/)
|
||||
- [Compose Destinations](https://composedestinations.rafaelcosta.xyz/)
|
||||
- [libarchive](https://www.libarchive.org/)
|
||||
- [jsoup](https://jsoup.org/)
|
||||
|
||||
# 许可证
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@
|
||||
- [Coil](https://coil-kt.github.io/coil/)
|
||||
- [Compose Destinations](https://composedestinations.rafaelcosta.xyz/)
|
||||
- [libarchive](https://www.libarchive.org/)
|
||||
- [jsoup](https://jsoup.org/)
|
||||
|
||||
# 許可證書
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@ material-kolor = "com.materialkolor:material-kolor:2.1.1"
|
||||
desugar = "com.android.tools:desugar_jdk_libs:2.1.5"
|
||||
|
||||
diff = "io.github.petertrr:kotlin-multiplatform-diff:1.1.0"
|
||||
jsoup = "org.jsoup:jsoup:1.20.1"
|
||||
|
||||
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
|
||||
|
||||
Reference in new issue
Block a user