From 09842f5d72b87494f2042c80f35a94ff6cf07b00 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Thu, 9 Feb 2023 15:24:14 +0800 Subject: [PATCH] Convert GalleryDetailParser to kotlin --- .../com/hippo/ehviewer/client/EhEngine.kt | 6 +- .../ehviewer/client/data/GalleryDetail.kt | 29 +- .../client/parser/GalleryDetailParser.kt | 839 ++++++++---------- .../java/com/hippo/util/MutableBoolean.java | 26 - 4 files changed, 423 insertions(+), 477 deletions(-) delete mode 100644 app/src/main/java/com/hippo/util/MutableBoolean.java diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt index de634a3ff..43a3a1beb 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt @@ -323,7 +323,7 @@ object EhEngine { if (html != null) { application.showEventPane(html) } - return GalleryDetailParser.parse(body) + return GalleryDetailParser.parse(body!!) } } catch (e: Throwable) { ExceptionUtils.throwIfFatal(e) @@ -348,8 +348,8 @@ object EhEngine { headers = response.headers body = response.body.string() return Pair.create( - GalleryDetailParser.parsePreviewSet(body), - GalleryDetailParser.parsePreviewPages(body) + GalleryDetailParser.parsePreviewSet(body!!), + GalleryDetailParser.parsePreviewPages(body!!) ) } } catch (e: Throwable) { diff --git a/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.kt b/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.kt index 044c76b02..cdaa7874c 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.kt @@ -15,6 +15,7 @@ */ package com.hippo.ehviewer.client.data +import com.hippo.ehviewer.client.data.GalleryInfo.Companion.S_LANGS import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize @@ -74,4 +75,30 @@ class GalleryDetail( @IgnoredOnParcel @JvmField var previewSet: PreviewSet? = null, -) : AbstractGalleryInfo by galleryInfo, GalleryInfo +) : AbstractGalleryInfo by galleryInfo, GalleryInfo { + override fun generateSLang() { + val index = LANGUAGES.indexOf(language) + if (index != -1) { + simpleLanguage = S_LANGS[index] + } + } + + companion object { + private val LANGUAGES = arrayOf( + "English", + "Chinese", + "Spanish", + "Korean", + "Russian", + "French", + "Portuguese", + "Thai", + "German", + "Italian", + "Vietnamese", + "Polish", + "Hungarian", + "Dutch" + ) + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt index 0f6e9c58f..ae0ff50ca 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt @@ -13,689 +13,634 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.ehviewer.client.parser -package com.hippo.ehviewer.client.parser; +import com.hippo.ehviewer.EhDB +import com.hippo.ehviewer.client.EhFilter +import com.hippo.ehviewer.client.EhUtils +import com.hippo.ehviewer.client.EhUtils.getCategory +import com.hippo.ehviewer.client.EhUtils.handleThumbUrlResolution +import com.hippo.ehviewer.client.data.BaseGalleryInfo +import com.hippo.ehviewer.client.data.GalleryComment +import com.hippo.ehviewer.client.data.GalleryCommentList +import com.hippo.ehviewer.client.data.GalleryDetail +import com.hippo.ehviewer.client.data.GalleryInfo +import com.hippo.ehviewer.client.data.GalleryTagGroup +import com.hippo.ehviewer.client.data.LargePreviewSet +import com.hippo.ehviewer.client.data.NormalPreviewSet +import com.hippo.ehviewer.client.data.PreviewSet +import com.hippo.ehviewer.client.exception.EhException +import com.hippo.ehviewer.client.exception.OffensiveException +import com.hippo.ehviewer.client.exception.ParseException +import com.hippo.ehviewer.client.exception.PiningException +import com.hippo.util.ExceptionUtils +import com.hippo.util.JsoupUtils +import com.hippo.yorozuya.NumberUtils +import com.hippo.yorozuya.StringUtils +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import org.jsoup.nodes.Node +import org.jsoup.select.Elements +import org.jsoup.select.NodeTraversor +import org.jsoup.select.NodeVisitor +import java.time.Instant +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter +import java.util.Locale +import java.util.regex.Pattern -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.hippo.ehviewer.EhDB; -import com.hippo.ehviewer.client.EhFilter; -import com.hippo.ehviewer.client.EhUtils; -import com.hippo.ehviewer.client.data.BaseGalleryInfo; -import com.hippo.ehviewer.client.data.GalleryComment; -import com.hippo.ehviewer.client.data.GalleryCommentList; -import com.hippo.ehviewer.client.data.GalleryDetail; -import com.hippo.ehviewer.client.data.GalleryInfo; -import com.hippo.ehviewer.client.data.GalleryTagGroup; -import com.hippo.ehviewer.client.data.LargePreviewSet; -import com.hippo.ehviewer.client.data.NormalPreviewSet; -import com.hippo.ehviewer.client.data.PreviewSet; -import com.hippo.ehviewer.client.exception.EhException; -import com.hippo.ehviewer.client.exception.OffensiveException; -import com.hippo.ehviewer.client.exception.ParseException; -import com.hippo.ehviewer.client.exception.PiningException; -import com.hippo.util.ExceptionUtils; -import com.hippo.util.JsoupUtils; -import com.hippo.util.MutableBoolean; -import com.hippo.yorozuya.NumberUtils; -import com.hippo.yorozuya.StringUtils; - -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.nodes.Node; -import org.jsoup.select.Elements; -import org.jsoup.select.NodeTraversor; -import org.jsoup.select.NodeVisitor; - -import java.time.Instant; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class GalleryDetailParser { - - private static final Pattern PATTERN_ERROR = Pattern.compile("
\n

([^<]+)

"); - private static final Pattern PATTERN_DETAIL = Pattern.compile("var gid = (\\d+);.+?var token = \"([a-f0-9]+)\";.+?var apiuid = ([\\-\\d]+);.+?var apikey = \"([a-f0-9]+)\";", Pattern.DOTALL); - private static final Pattern PATTERN_TORRENT = Pattern.compile("]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Torrent Download[^<]+(\\d+)[^<]+]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Archive Download"); - private static final Pattern PATTERN_COVER = Pattern.compile("width:(\\d+)px; height:(\\d+)px.+?url\\((.+?)\\)"); - private static final Pattern PATTERN_PAGES = Pattern.compile("]*>Length:]*>([\\d,]+) pages"); - private static final Pattern PATTERN_PREVIEW_PAGES = Pattern.compile("]+>]+>([\\d,]+)]+>(?:]+>)?>(?:)?"); - private static final Pattern PATTERN_NORMAL_PREVIEW = Pattern.compile("
]*>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*>]*href=\"(.+?)\"[^<>]*>\"([\\d,]+)\"");\"([\\d,]+)\".+?src=\"(.+?)\"");"); - private static final Pattern PATTERN_FAVORITE_SLOT = Pattern.compile("/fav.png\\); background-position:0px -(\\d+)px"); - - private static final GalleryTagGroup[] EMPTY_GALLERY_TAG_GROUP_ARRAY = new GalleryTagGroup[0]; - private static final GalleryCommentList EMPTY_GALLERY_COMMENT_ARRAY = new GalleryCommentList(new GalleryComment[0], false); - - private static final DateTimeFormatter WEB_COMMENT_DATE_FORMAT = DateTimeFormatter - .ofPattern("dd MMMM yyyy, HH:mm", Locale.US).withZone(ZoneOffset.UTC); - private static final String OFFENSIVE_STRING = - "

(And if you choose to ignore this warning, you lose all rights to complain about it in the future.)

"; - private static final String PINING_STRING = - "

This gallery is pining for the fjords.

"; - - private static final String[] LANGUAGES = { - "English", - "Chinese", - "Spanish", - "Korean", - "Russian", - "French", - "Portuguese", - "Thai", - "German", - "Italian", - "Vietnamese", - "Polish", - "Hungarian", - "Dutch", - }; - - public static GalleryDetail parse(String body) throws EhException { +object GalleryDetailParser { + private val PATTERN_ERROR = Pattern.compile("
\n

([^<]+)

") + private val PATTERN_DETAIL = Pattern.compile( + "var gid = (\\d+);.+?var token = \"([a-f0-9]+)\";.+?var apiuid = ([\\-\\d]+);.+?var apikey = \"([a-f0-9]+)\";", + Pattern.DOTALL + ) + private val PATTERN_TORRENT = + Pattern.compile("]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Torrent Download[^<]+(\\d+)[^<]+]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Archive Download") + private val PATTERN_COVER = Pattern.compile("width:(\\d+)px; height:(\\d+)px.+?url\\((.+?)\\)") + private val PATTERN_PAGES = + Pattern.compile("]*>Length:]*>([\\d,]+) pages") + private val PATTERN_PREVIEW_PAGES = + Pattern.compile("]+>]+>([\\d,]+)]+>(?:]+>)?>(?:)?") + private val PATTERN_NORMAL_PREVIEW = + Pattern.compile("
]*>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*>]*href=\"(.+?)\"[^<>]*>\"([\\d,]+)\"")\"([\\d,]+)\".+?src=\"(.+?)\"")") + private val PATTERN_FAVORITE_SLOT = + Pattern.compile("/fav.png\\); background-position:0px -(\\d+)px") + private val EMPTY_GALLERY_TAG_GROUP_ARRAY = arrayOf() + private val EMPTY_GALLERY_COMMENT_ARRAY = GalleryCommentList(arrayOf(), false) + private val WEB_COMMENT_DATE_FORMAT = DateTimeFormatter + .ofPattern("dd MMMM yyyy, HH:mm", Locale.US).withZone(ZoneOffset.UTC) + private const val OFFENSIVE_STRING = + "

(And if you choose to ignore this warning, you lose all rights to complain about it in the future.)

" + private const val PINING_STRING = "

This gallery is pining for the fjords.

" + @Throws(EhException::class) + fun parse(body: String): GalleryDetail { if (body.contains(OFFENSIVE_STRING)) { - throw new OffensiveException(); + throw OffensiveException() } - if (body.contains(PINING_STRING)) { - throw new PiningException(); + throw PiningException() } // Error info - Matcher m = PATTERN_ERROR.matcher(body); + val m = PATTERN_ERROR.matcher(body) if (m.find()) { - throw new EhException(m.group(1)); + throw EhException(m.group(1)) } - - GalleryDetail galleryDetail = new GalleryDetail(); - Document document = Jsoup.parse(body); - parseDetail(galleryDetail, document, body); - galleryDetail.tags = parseTagGroups(document); - galleryDetail.comments = parseComments(document); - galleryDetail.previewPages = parsePreviewPages(document, body); - galleryDetail.previewSet = parsePreviewSet(document, body); + val galleryDetail = GalleryDetail() + val document = Jsoup.parse(body) + parseDetail(galleryDetail, document, body) + galleryDetail.tags = parseTagGroups(document) + galleryDetail.comments = parseComments(document) + galleryDetail.previewPages = parsePreviewPages(document, body) + galleryDetail.previewSet = parsePreviewSet(document, body) // Generate simpleLanguage for local favorites - for (int i = 0; i < LANGUAGES.length; i++) { - if (galleryDetail.language.equals(LANGUAGES[i])) { - galleryDetail.setSimpleLanguage(GalleryInfo.Companion.getS_LANGS()[i]); - break; - } - } - - return galleryDetail; + galleryDetail.generateSLang() + return galleryDetail } - @SuppressWarnings("ConstantConditions") - private static void parseDetail(GalleryDetail gd, Document d, String body) throws ParseException { - Matcher matcher = PATTERN_DETAIL.matcher(body); + @Throws(ParseException::class) + private fun parseDetail(gd: GalleryDetail, d: Document, body: String) { + var matcher = PATTERN_DETAIL.matcher(body) if (matcher.find()) { - gd.setGid(NumberUtils.parseLongSafely(matcher.group(1), -1L)); - gd.setToken(matcher.group(2)); - gd.apiUid = NumberUtils.parseLongSafely(matcher.group(3), -1L); - gd.apiKey = matcher.group(4); + gd.gid = NumberUtils.parseLongSafely(matcher.group(1), -1L) + gd.token = matcher.group(2) + gd.apiUid = NumberUtils.parseLongSafely(matcher.group(3), -1L) + gd.apiKey = matcher.group(4) } else { - throw new ParseException("Can't parse gallery detail", body); + throw ParseException("Can't parse gallery detail", body) } - if (gd.getGid() == -1L) { - throw new ParseException("Can't parse gallery detail", body); + if (gd.gid == -1L) { + throw ParseException("Can't parse gallery detail", body) } - - matcher = PATTERN_TORRENT.matcher(body); + matcher = PATTERN_TORRENT.matcher(body) if (matcher.find()) { - gd.torrentUrl = StringUtils.unescapeXml(StringUtils.trim(matcher.group(1))); - gd.torrentCount = NumberUtils.parseIntSafely(matcher.group(2), 0); + gd.torrentUrl = StringUtils.unescapeXml(StringUtils.trim(matcher.group(1))) + gd.torrentCount = NumberUtils.parseIntSafely(matcher.group(2), 0) } else { - gd.torrentCount = 0; - gd.torrentUrl = ""; + gd.torrentCount = 0 + gd.torrentUrl = "" } - - matcher = PATTERN_ARCHIVE.matcher(body); + matcher = PATTERN_ARCHIVE.matcher(body) if (matcher.find()) { - gd.archiveUrl = StringUtils.unescapeXml(StringUtils.trim(matcher.group(1))); + gd.archiveUrl = StringUtils.unescapeXml(StringUtils.trim(matcher.group(1))) } else { - gd.archiveUrl = ""; + gd.archiveUrl = "" } - try { - Element gm = JsoupUtils.getElementByClass(d, "gm"); + val gm = JsoupUtils.getElementByClass(d, "gm") // Thumb url - Element gd1 = gm.getElementById("gd1"); + val gd1 = gm!!.getElementById("gd1") try { - gd.setThumb(parseCoverStyle(StringUtils.trim(gd1.child(0).attr("style")))); - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - gd.setThumb(""); + gd.thumb = parseCoverStyle( + StringUtils.trim( + gd1!!.child(0).attr("style") + ) + ) + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + gd.thumb = "" } // Title - Element gn = gm.getElementById("gn"); + val gn = gm.getElementById("gn") if (null != gn) { - gd.setTitle(StringUtils.trim(gn.text())); + gd.title = StringUtils.trim(gn.text()) } else { - gd.setTitle(""); + gd.title = "" } // Jpn title - Element gj = gm.getElementById("gj"); + val gj = gm.getElementById("gj") if (null != gj) { - gd.setTitleJpn(StringUtils.trim(gj.text())); + gd.titleJpn = StringUtils.trim(gj.text()) } else { - gd.setTitleJpn(""); + gd.titleJpn = "" } // Category - Element gdc = gm.getElementById("gdc"); + val gdc = gm.getElementById("gdc") try { - Element ce = JsoupUtils.getElementByClass(gdc, "cn"); + var ce = JsoupUtils.getElementByClass(gdc, "cn") if (ce == null) { - ce = JsoupUtils.getElementByClass(gdc, "cs"); + ce = JsoupUtils.getElementByClass(gdc, "cs") } - gd.setCategory(EhUtils.getCategory(ce.text())); - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - gd.setCategory(EhUtils.UNKNOWN); + gd.category = getCategory(ce!!.text()) + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + gd.category = EhUtils.UNKNOWN } // Uploader - Element gdn = gm.getElementById("gdn"); + val gdn = gm.getElementById("gdn") if (null != gdn) { - gd.setDisowned(gdn.attr("style").contains("opacity:0.5")); - gd.setUploader(StringUtils.trim(gdn.text())); + gd.disowned = gdn.attr("style").contains("opacity:0.5") + gd.uploader = StringUtils.trim(gdn.text()) } else { - gd.setUploader(""); + gd.uploader = "" } - - Element gdd = gm.getElementById("gdd"); - gd.setPosted(""); - gd.parent = ""; - gd.visible = ""; - gd.size = ""; - gd.setPages(0); - gd.favoriteCount = 0; - Elements es = gdd.child(0).child(0).children(); - for (int i = 0, n = es.size(); i < n; i++) { - parseDetailInfo(gd, es.get(i)); + val gdd = gm.getElementById("gdd") + gd.posted = "" + gd.parent = "" + gd.visible = "" + gd.size = "" + gd.pages = 0 + gd.favoriteCount = 0 + val es = gdd!!.child(0).child(0).children() + es.forEach { + parseDetailInfo(gd, it) } // Rating count - Element rating_count = gm.getElementById("rating_count"); - if (null != rating_count) { + val ratingCount = gm.getElementById("rating_count") + if (null != ratingCount) { gd.ratingCount = NumberUtils.parseIntSafely( - StringUtils.trim(rating_count.text()), 0); + StringUtils.trim(ratingCount.text()), 0 + ) } else { - gd.ratingCount = 0; + gd.ratingCount = 0 } // Rating - Element rating_label = gm.getElementById("rating_label"); - if (null != rating_label) { - String ratingStr = StringUtils.trim(rating_label.text()); - if ("Not Yet Rated".equals(ratingStr)) { - gd.setRating(-1.0f); + val ratingLabel = gm.getElementById("rating_label") + if (null != ratingLabel) { + val ratingStr = StringUtils.trim(ratingLabel.text()) + if ("Not Yet Rated" == ratingStr) { + gd.rating = -1.0f } else { - int index = ratingStr.indexOf(' '); - if (index == -1 || index >= ratingStr.length()) { - gd.setRating(0f); + val index = ratingStr.indexOf(' ') + if (index == -1 || index >= ratingStr.length) { + gd.rating = 0f } else { - gd.setRating(NumberUtils.parseFloatSafely(ratingStr.substring(index + 1), 0f)); + gd.rating = NumberUtils.parseFloatSafely(ratingStr.substring(index + 1), 0f) } } } else { - gd.setRating(-1.0f); + gd.rating = -1.0f } // isFavorited - Element gdf = gm.getElementById("gdf"); - gd.isFavorited = false; + val gdf = gm.getElementById("gdf") + gd.isFavorited = false if (gdf != null) { - final String favoriteName = StringUtils.trim(gdf.text()); - if (favoriteName.equals("Add to Favorites")) { - gd.setFavoriteName(null); + val favoriteName = StringUtils.trim(gdf.text()) + if (favoriteName == "Add to Favorites") { + gd.favoriteName = null } else { - gd.isFavorited = true; - gd.setFavoriteName(StringUtils.trim(gdf.text())); - - matcher = PATTERN_FAVORITE_SLOT.matcher(body); + gd.isFavorited = true + gd.favoriteName = StringUtils.trim(gdf.text()) + matcher = PATTERN_FAVORITE_SLOT.matcher(body) if (matcher.find()) { - gd.setFavoriteSlot((NumberUtils.parseIntSafely(matcher.group(1), 2) - 2) / 19); + gd.favoriteSlot = (NumberUtils.parseIntSafely(matcher.group(1), 2) - 2) / 19 } } } - if (gd.getFavoriteSlot() == -2 && EhDB.containLocalFavorites(gd.getGid())) { - gd.setFavoriteSlot(-1); + if (gd.favoriteSlot == -2 && EhDB.containLocalFavorites(gd.gid)) { + gd.favoriteSlot = -1 } - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - throw new ParseException("Can't parse gallery detail", body); + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + throw ParseException("Can't parse gallery detail", body) } // newer version try { - Element gnd = d.getElementById("gnd"); + val gnd = d.getElementById("gnd") if (gnd != null) { - matcher = PATTERN_NEWER_DATE.matcher(body); - ArrayList dates = new ArrayList<>(); + matcher = PATTERN_NEWER_DATE.matcher(body) + val dates = ArrayList() while (matcher.find()) { - dates.add(matcher.group(1)); + dates.add(matcher.group(1)) } - Elements elements = gnd.select("a"); - for (int i = 0; i < elements.size(); i++) { - Element element = elements.get(i); - GalleryInfo gi = new BaseGalleryInfo(); - GalleryDetailUrlParser.Result result = GalleryDetailUrlParser.parse(element.attr("href")); + val elements = gnd.select("a") + for (i in elements.indices) { + val element = elements[i] + val gi: GalleryInfo = BaseGalleryInfo() + val result = GalleryDetailUrlParser.parse(element.attr("href")) if (result != null) { - gi.setGid(result.gid); - gi.setToken(result.token); - gi.setTitle(StringUtils.trim(element.text())); - gi.setPosted(dates.get(i)); - gd.newerVersions.add(gi); + gi.gid = result.gid + gi.token = result.token + gi.title = StringUtils.trim(element.text()) + gi.posted = dates[i] + gd.newerVersions.add(gi) } } } - } catch (Throwable e) { - e.printStackTrace(); + } catch (e: Throwable) { + e.printStackTrace() } } // width:250px; height:356px; background:transparent url(https://exhentai.org/t/fe/1f/fe1fcfa9bf8fba2f03982eda0aa347cc9d6a6372-145921-1050-1492-jpg_250.jpg) 0 0 no-repeat - private static String parseCoverStyle(String str) { - Matcher matcher = PATTERN_COVER.matcher(str); - if (matcher.find()) { - return EhUtils.handleThumbUrlResolution(matcher.group(3)); + private fun parseCoverStyle(str: String): String? { + val matcher = PATTERN_COVER.matcher(str) + return if (matcher.find()) { + handleThumbUrlResolution(matcher.group(3)) } else { - return ""; + "" } } - private static void parseDetailInfo(GalleryDetail gd, Element e) { - Elements es = e.children(); - if (es.size() < 2) { - return; + private fun parseDetailInfo(gd: GalleryDetail, e: Element) { + val es = e.children() + if (es.size < 2) { + return } - - String key = StringUtils.trim(es.get(0).text()); - String value = StringUtils.trim(es.get(1).ownText()); + val key = StringUtils.trim(es[0].text()) + val value = StringUtils.trim(es[1].ownText()) if (key.startsWith("Posted")) { - gd.setPosted(value); + gd.posted = value } else if (key.startsWith("Parent")) { - Element a = es.get(1).children().first(); + val a = es[1].children().first() if (a != null) { - gd.parent = a.attr("href"); + gd.parent = a.attr("href") } } else if (key.startsWith("Visible")) { - gd.visible = value; + gd.visible = value } else if (key.startsWith("Language")) { - gd.language = value; + gd.language = value } else if (key.startsWith("File Size")) { - gd.size = value; + gd.size = value } else if (key.startsWith("Length")) { - int index = value.indexOf(' '); + val index = value.indexOf(' ') if (index >= 0) { - gd.setPages(NumberUtils.parseIntSafely(value.substring(0, index), 1)); + gd.pages = NumberUtils.parseIntSafely(value.substring(0, index), 1) } else { - gd.setPages(1); + gd.pages = 1 } } else if (key.startsWith("Favorited")) { - switch (value) { - case "Never" -> gd.favoriteCount = 0; - case "Once" -> gd.favoriteCount = 1; - default -> { - int index = value.indexOf(' '); + when (value) { + "Never" -> gd.favoriteCount = 0 + "Once" -> gd.favoriteCount = 1 + else -> { + val index = value.indexOf(' ') if (index == -1) { - gd.favoriteCount = 0; + gd.favoriteCount = 0 } else { - gd.favoriteCount = NumberUtils.parseIntSafely(value.substring(0, index), 0); + gd.favoriteCount = NumberUtils.parseIntSafely(value.substring(0, index), 0) } } } } } - @Nullable - private static GalleryTagGroup parseTagGroup(Element element) { - try { - GalleryTagGroup group = new GalleryTagGroup(); - - String nameSpace = element.child(0).text(); + private fun parseTagGroup(element: Element): GalleryTagGroup? { + return try { + val group = GalleryTagGroup() + var nameSpace = element.child(0).text() // Remove last ':' - nameSpace = nameSpace.substring(0, nameSpace.length() - 1); - group.groupName = nameSpace; - - Elements tags = element.child(1).children(); - for (int i = 0, n = tags.size(); i < n; i++) { - String tag = tags.get(i).text(); + nameSpace = nameSpace.substring(0, nameSpace.length - 1) + group.groupName = nameSpace + val tags = element.child(1).children() + tags.forEach { + var tag = it.text() // Sometimes parody tag is followed with '|' and english translate, just remove them - int index = tag.indexOf('|'); + val index = tag.indexOf('|') if (index >= 0) { - tag = tag.substring(0, index).trim(); + tag = tag.substring(0, index).trim() } - group.addTag(tag); + group.addTag(tag) } - - return group.size() > 0 ? group : null; - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - e.printStackTrace(); - return null; + if (group.size() > 0) group else null + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + e.printStackTrace() + null } } /** * Parse tag groups with html parser */ - @NonNull - public static GalleryTagGroup[] parseTagGroups(Document document) { - try { - Element taglist = document.getElementById("taglist"); - assert taglist != null; - Elements tagGroups = taglist.child(0).child(0).children(); - return parseTagGroups(tagGroups); - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - e.printStackTrace(); - return EMPTY_GALLERY_TAG_GROUP_ARRAY; + private fun parseTagGroups(document: Document): Array { + return try { + val taglist = document.getElementById("taglist")!! + val tagGroups = taglist.child(0).child(0).children() + parseTagGroups(tagGroups) + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + e.printStackTrace() + EMPTY_GALLERY_TAG_GROUP_ARRAY } } - @NonNull - public static GalleryTagGroup[] parseTagGroups(Elements trs) { - try { - List list = new ArrayList<>(trs.size()); - for (int i = 0, n = trs.size(); i < n; i++) { - GalleryTagGroup group = parseTagGroup(trs.get(i)); - if (null != group) { - list.add(group); - } - } - return list.toArray(new GalleryTagGroup[0]); - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - e.printStackTrace(); - return EMPTY_GALLERY_TAG_GROUP_ARRAY; + private fun parseTagGroups(trs: Elements): Array { + return try { + trs.mapNotNull { parseTagGroup(it) }.toTypedArray() + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + e.printStackTrace() + EMPTY_GALLERY_TAG_GROUP_ARRAY } } - @Nullable - @SuppressWarnings("ConstantConditions") - public static GalleryComment parseComment(Element element) { - try { - GalleryComment comment = new GalleryComment(); + private fun parseComment(element: Element): GalleryComment? { + return try { + val comment = GalleryComment() // Id - Element a = element.previousElementSibling(); - String name = a.attr("name"); - comment.id = Integer.parseInt(StringUtils.trim(name).substring(1)); + val a = element.previousElementSibling() + val name = a!!.attr("name") + comment.id = StringUtils.trim(name).substring(1).toInt().toLong() // Editable, vote up and vote down - Element c4 = JsoupUtils.getElementByClass(element, "c4"); + val c4 = JsoupUtils.getElementByClass(element, "c4") if (null != c4) { - if ("Uploader Comment".equals(c4.text())) { - comment.uploader = true; + if ("Uploader Comment" == c4.text()) { + comment.uploader = true } - for (Element e : c4.children()) { - switch (e.text()) { - case "Vote+" -> { - comment.voteUpAble = true; - comment.voteUpEd = !StringUtils.trim(e.attr("style")).isEmpty(); + for (e in c4.children()) { + when (e.text()) { + "Vote+" -> { + comment.voteUpAble = true + comment.voteUpEd = StringUtils.trim(e.attr("style")).isNotEmpty() } - case "Vote-" -> { - comment.voteDownAble = true; - comment.voteDownEd = !StringUtils.trim(e.attr("style")).isEmpty(); + + "Vote-" -> { + comment.voteDownAble = true + comment.voteDownEd = StringUtils.trim(e.attr("style")).isNotEmpty() } - case "Edit" -> comment.editable = true; + + "Edit" -> comment.editable = true } } } // Vote state - Element c7 = JsoupUtils.getElementByClass(element, "c7"); + val c7 = JsoupUtils.getElementByClass(element, "c7") if (null != c7) { - comment.voteState = StringUtils.trim(c7.text()); + comment.voteState = StringUtils.trim(c7.text()) } // Score - Element c5 = JsoupUtils.getElementByClass(element, "c5"); + val c5 = JsoupUtils.getElementByClass(element, "c5") if (null != c5) { - Elements es = c5.children(); + val es = c5.children() if (!es.isEmpty()) { - comment.score = NumberUtils.parseIntSafely(StringUtils.trim(es.get(0).text()), 0); + comment.score = NumberUtils.parseIntSafely( + StringUtils.trim(es[0].text()), 0 + ) } } // time - Element c3 = JsoupUtils.getElementByClass(element, "c3"); - String temp = c3.ownText(); - temp = temp.substring("Posted on ".length(), temp.length() - " by:".length()); - comment.time = Instant.from(WEB_COMMENT_DATE_FORMAT.parse(temp)).toEpochMilli(); + val c3 = JsoupUtils.getElementByClass(element, "c3") + var temp = c3!!.ownText() + temp = temp.substring("Posted on ".length, temp.length - " by:".length) + comment.time = Instant.from(WEB_COMMENT_DATE_FORMAT.parse(temp)).toEpochMilli() // user - comment.user = c3.child(0).text(); + comment.user = c3.child(0).text() // comment - Element c6 = JsoupUtils.getElementByClass(element, "c6"); + val c6 = JsoupUtils.getElementByClass(element, "c6") // fix underline support - for (Element e : c6.children()) { - if ("span".equals(e.tagName()) && "text-decoration:underline;".equals(e.attr("style"))) { - e.tagName("u"); + for (e in c6!!.children()) { + if ("span" == e.tagName() && "text-decoration:underline;" == e.attr("style")) { + e.tagName("u") } } - comment.comment = c6.html(); + comment.comment = c6.html() // filter comment if (!comment.uploader) { - EhFilter sEhFilter = EhFilter.INSTANCE; + val sEhFilter = EhFilter if (!sEhFilter.filterCommenter(comment.user) || !sEhFilter.filterComment(comment.comment)) { - return null; + return null } } // last edited - Element c8 = JsoupUtils.getElementByClass(element, "c8"); + val c8 = JsoupUtils.getElementByClass(element, "c8") if (c8 != null) { - Element e = c8.children().first(); + val e = c8.children().first() if (e != null) { - comment.lastEdited = Instant.from(WEB_COMMENT_DATE_FORMAT.parse(temp)).toEpochMilli(); + comment.lastEdited = + Instant.from(WEB_COMMENT_DATE_FORMAT.parse(temp)).toEpochMilli() } } - return comment; - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - e.printStackTrace(); - return null; + comment + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + e.printStackTrace() + null } } /** * Parse comments with html parser */ - @NonNull - public static GalleryCommentList parseComments(Document document) { - try { - Element cdiv = document.getElementById("cdiv"); - assert cdiv != null; - Elements c1s = cdiv.getElementsByClass("c1"); - - List list = new ArrayList<>(c1s.size()); - for (int i = 0, n = c1s.size(); i < n; i++) { - GalleryComment comment = parseComment(c1s.get(i)); - if (null != comment) { - list.add(comment); - } - } - - Element chd = cdiv.getElementById("chd"); - MutableBoolean hasMore = new MutableBoolean(false); - assert chd != null; - NodeTraversor.traverse(new NodeVisitor() { - @Override - public void head(@NonNull Node node, int depth) { - if (node instanceof Element && ((Element) node).text().equals("click to show all")) { - hasMore.value = true; + fun parseComments(document: Document): GalleryCommentList { + return try { + val cdiv = document.getElementById("cdiv")!! + val c1s = cdiv.getElementsByClass("c1") + val list = c1s.mapNotNull { parseComment(it) } + val chd = cdiv.getElementById("chd") + var hasMore = false + NodeTraversor.traverse(object : NodeVisitor { + override fun head(node: Node, depth: Int) { + if (node is Element && node.text() == "click to show all") { + hasMore = true } } - @Override - public void tail(@NonNull Node node, int depth) { - } - }, chd); - - return new GalleryCommentList(list.toArray(new GalleryComment[0]), hasMore.value); - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - e.printStackTrace(); - return EMPTY_GALLERY_COMMENT_ARRAY; + override fun tail(node: Node, depth: Int) {} + }, chd!!) + GalleryCommentList(list.toTypedArray(), hasMore) + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + e.printStackTrace() + EMPTY_GALLERY_COMMENT_ARRAY } } /** * Parse preview pages with html parser */ - public static int parsePreviewPages(Document document, String body) throws ParseException { - try { - Element ptt = document.getElementsByClass("ptt").first(); - assert ptt != null; - Elements elements = ptt.child(0).child(0).children(); - return Integer.parseInt(elements.get(elements.size() - 2).text()); - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - e.printStackTrace(); - throw new ParseException("Can't parse preview pages", body); + @Throws(ParseException::class) + fun parsePreviewPages(document: Document, body: String?): Int { + return try { + val ptt = document.getElementsByClass("ptt").first()!! + val elements = ptt.child(0).child(0).children() + elements[elements.size - 2].text().toInt() + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + e.printStackTrace() + throw ParseException("Can't parse preview pages", body!!) } } /** * Parse preview pages with regular expressions */ - public static int parsePreviewPages(String body) throws ParseException { - Matcher m = PATTERN_PREVIEW_PAGES.matcher(body); - int previewPages = -1; + @JvmStatic + @Throws(ParseException::class) + fun parsePreviewPages(body: String): Int { + val m = PATTERN_PREVIEW_PAGES.matcher(body) + var previewPages = -1 if (m.find()) { - previewPages = ParserUtils.parseInt(m.group(1), -1); + previewPages = ParserUtils.parseInt(m.group(1), -1) } - if (previewPages <= 0) { - throw new ParseException("Parse preview page count error", body); + throw ParseException("Parse preview page count error", body) } - - return previewPages; + return previewPages } /** * Parse pages with regular expressions */ - public static int parsePages(String body) throws ParseException { - int pages = -1; - - Matcher m = PATTERN_PAGES.matcher(body); + @JvmStatic + @Throws(ParseException::class) + fun parsePages(body: String): Int { + var pages = -1 + val m = PATTERN_PAGES.matcher(body) if (m.find()) { - pages = ParserUtils.parseInt(m.group(1), -1); + pages = ParserUtils.parseInt(m.group(1), -1) } - if (pages < 0) { - throw new ParseException("Parse pages error", body); + throw ParseException("Parse pages error", body) } - - return pages; + return pages } - public static PreviewSet parsePreviewSet(Document d, String body) throws ParseException { - try { - return parseLargePreviewSet(d, body); - } catch (ParseException e) { - return parseNormalPreviewSet(body); + @Throws(ParseException::class) + fun parsePreviewSet(d: Document, body: String): PreviewSet { + return try { + parseLargePreviewSet(d, body) + } catch (e: ParseException) { + parseNormalPreviewSet(body) } } - public static PreviewSet parsePreviewSet(String body) throws ParseException { - try { - return parseLargePreviewSet(body); - } catch (ParseException e) { - return parseNormalPreviewSet(body); + @JvmStatic + @Throws(ParseException::class) + fun parsePreviewSet(body: String): PreviewSet { + return try { + parseLargePreviewSet(body) + } catch (e: ParseException) { + parseNormalPreviewSet(body) } } /** * Parse large previews with regular expressions */ - private static LargePreviewSet parseLargePreviewSet(Document d, String body) throws ParseException { - try { - LargePreviewSet largePreviewSet = new LargePreviewSet(); - Element gdt = d.getElementById("gdt"); - assert gdt != null; - Elements gdtls = gdt.getElementsByClass("gdtl"); - int n = gdtls.size(); + @Throws(ParseException::class) + private fun parseLargePreviewSet(d: Document, body: String): LargePreviewSet { + return try { + val largePreviewSet = LargePreviewSet() + val gdt = d.getElementById("gdt")!! + val gdtls = gdt.getElementsByClass("gdtl") + val n = gdtls.size if (n == 0) { - throw new ParseException("Can't parse large preview", body); + throw ParseException("Can't parse large preview", body) } - for (int i = 0; i < n; i++) { - Element element = gdtls.get(i).child(0); - String pageUrl = element.attr("href"); - element = element.child(0); - String imageUrl = element.attr("src"); - int index = Integer.parseInt(element.attr("alt")) - 1; - largePreviewSet.addItem(index, imageUrl, pageUrl); + for (i in 0 until n) { + var element = gdtls[i].child(0) + val pageUrl = element.attr("href") + element = element.child(0) + val imageUrl = element.attr("src") + val index = element.attr("alt").toInt() - 1 + largePreviewSet.addItem(index, imageUrl, pageUrl) } - return largePreviewSet; - } catch (Throwable e) { - ExceptionUtils.throwIfFatal(e); - throw new ParseException("Can't parse large preview", body); + largePreviewSet + } catch (e: Throwable) { + ExceptionUtils.throwIfFatal(e) + throw ParseException("Can't parse large preview", body) } } /** * Parse large previews with regular expressions */ - private static LargePreviewSet parseLargePreviewSet(String body) throws ParseException { - Matcher m = PATTERN_LARGE_PREVIEW.matcher(body); - LargePreviewSet largePreviewSet = new LargePreviewSet(); - + @Throws(ParseException::class) + private fun parseLargePreviewSet(body: String): LargePreviewSet { + val m = PATTERN_LARGE_PREVIEW.matcher(body) + val largePreviewSet = LargePreviewSet() while (m.find()) { - int index = ParserUtils.parseInt(m.group(2), 0) - 1; + val index = ParserUtils.parseInt(m.group(2), 0) - 1 if (index < 0) { - continue; + continue } - String imageUrl = ParserUtils.trim(m.group(3)); - String pageUrl = ParserUtils.trim(m.group(1)); - largePreviewSet.addItem(index, imageUrl, pageUrl); + val imageUrl = ParserUtils.trim(m.group(3)) + val pageUrl = ParserUtils.trim(m.group(1)) + largePreviewSet.addItem(index, imageUrl, pageUrl) } - if (largePreviewSet.size() == 0) { - throw new ParseException("Can't parse large preview", body); + throw ParseException("Can't parse large preview", body) } - - return largePreviewSet; + return largePreviewSet } /** * Parse normal previews with regular expressions */ - private static NormalPreviewSet parseNormalPreviewSet(String body) throws ParseException { - Matcher m = PATTERN_NORMAL_PREVIEW.matcher(body); - NormalPreviewSet normalPreviewSet = new NormalPreviewSet(); + @Throws(ParseException::class) + private fun parseNormalPreviewSet(body: String): NormalPreviewSet { + val m = PATTERN_NORMAL_PREVIEW.matcher(body) + val normalPreviewSet = NormalPreviewSet() while (m.find()) { - int position = ParserUtils.parseInt(m.group(6), 0) - 1; + val position = ParserUtils.parseInt(m.group(6), 0) - 1 if (position < 0) { - continue; + continue } - String imageUrl = ParserUtils.trim(m.group(3)); - int xOffset = ParserUtils.parseInt(m.group(4), 0); - int yOffset = 0; - int width = ParserUtils.parseInt(m.group(1), 0); + val imageUrl = ParserUtils.trim(m.group(3)) + val xOffset = ParserUtils.parseInt(m.group(4), 0) + val yOffset = 0 + val width = ParserUtils.parseInt(m.group(1), 0) if (width <= 0) { - continue; + continue } - int height = ParserUtils.parseInt(m.group(2), 0); + val height = ParserUtils.parseInt(m.group(2), 0) if (height <= 0) { - continue; + continue } - String pageUrl = ParserUtils.trim(m.group(5)); - normalPreviewSet.addItem(position, imageUrl, xOffset, yOffset, width, height, pageUrl); + val pageUrl = ParserUtils.trim(m.group(5)) + normalPreviewSet.addItem(position, imageUrl, xOffset, yOffset, width, height, pageUrl) } - if (normalPreviewSet.size() == 0) { - throw new ParseException("Can't parse normal preview", body); + throw ParseException("Can't parse normal preview", body) } - - return normalPreviewSet; + return normalPreviewSet } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/hippo/util/MutableBoolean.java b/app/src/main/java/com/hippo/util/MutableBoolean.java deleted file mode 100644 index 1d8d6d812..000000000 --- a/app/src/main/java/com/hippo/util/MutableBoolean.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2019 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.util; - -public class MutableBoolean { - - public boolean value; - - public MutableBoolean(boolean value) { - this.value = value; - } -}