refactor: improve memory footprint of zipline-parser code
I miss the ART GC already...
This commit is contained in:
+7
-5
@@ -31,11 +31,13 @@ private fun MutableList<Comment>.addSubtree(
|
||||
val comment = commentElement.toComment(parentComment)
|
||||
add(comment)
|
||||
val childContainer = if (subtree.`is`("div.comment")) subtree.parent() ?: subtree else subtree
|
||||
childContainer
|
||||
.children()
|
||||
.filter { it.`is`("ol.comments") }
|
||||
.flatMap { comments -> comments.children().filter { it.`is`("li.comments_subtree") } }
|
||||
.forEach { child -> addSubtree(child, parentComment = comment.shortId, seen) }
|
||||
for (childList in childContainer.children()) {
|
||||
if (!childList.`is`("ol.comments")) continue
|
||||
for (child in childList.children()) {
|
||||
if (!child.`is`("li.comments_subtree")) continue
|
||||
addSubtree(child, parentComment = comment.shortId, seen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Element.toComment(parentComment: String?): Comment {
|
||||
|
||||
+19
-29
@@ -10,40 +10,30 @@ import com.fleeksoft.ksoup.Ksoup
|
||||
import dev.msfjarvis.claw.model.LobstersPostDetails
|
||||
|
||||
private const val BASE_URL = "https://lobste.rs"
|
||||
private val commentCountRegex = "\\d+".toRegex()
|
||||
private const val STORY_SELECTOR = "ol.stories > li.story"
|
||||
private const val SUBMITTER_SELECTOR =
|
||||
"ol.stories > li.story div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])"
|
||||
|
||||
internal fun parsePostDetails(html: String): LobstersPostDetails {
|
||||
val document = Ksoup.parse(html, baseUri = BASE_URL)
|
||||
val storyElement = document.select(STORY_SELECTOR)
|
||||
val timestampElement = document.select("$STORY_SELECTOR div.byline > time")
|
||||
val titleElement = document.select("$STORY_SELECTOR span.link.h-cite > a")
|
||||
val commentsElement = document.select("$STORY_SELECTOR span.comments_label a")
|
||||
val submitterElement = document.select(SUBMITTER_SELECTOR)
|
||||
val tags = document.select("$STORY_SELECTOR span.tags > a").map { it.text() }
|
||||
return LobstersPostDetails(
|
||||
shortId = document.select("ol.stories > li.story").attr("data-shortid"),
|
||||
createdAt =
|
||||
normalizeCreatedAt(
|
||||
document.select("ol.stories > li.story div.byline > time").attr("data-at-unix")
|
||||
),
|
||||
title = document.select("ol.stories > li.story span.link.h-cite > a").text(),
|
||||
url = document.select("ol.stories > li.story span.link.h-cite > a").attr("abs:href"),
|
||||
shortId = storyElement.attr("data-shortid"),
|
||||
createdAt = normalizeCreatedAt(timestampElement.attr("data-at-unix")),
|
||||
title = titleElement.text(),
|
||||
url = titleElement.attr("abs:href"),
|
||||
description = document.select("div.story_content div.story_text").html(),
|
||||
commentCount =
|
||||
"\\d+"
|
||||
.toRegex()
|
||||
.find(document.select("ol.stories > li.story span.comments_label a").text())
|
||||
?.value
|
||||
?.toInt() ?: 0,
|
||||
commentsUrl = document.select("ol.stories > li.story span.comments_label a").attr("abs:href"),
|
||||
submitter =
|
||||
document
|
||||
.select(
|
||||
"ol.stories > li.story div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])"
|
||||
)
|
||||
.text(),
|
||||
tags = document.select("ol.stories > li.story span.tags > a").map { it.text() },
|
||||
commentCount = commentCountRegex.find(commentsElement.text())?.value?.toInt() ?: 0,
|
||||
commentsUrl = commentsElement.attr("abs:href"),
|
||||
submitter = submitterElement.text(),
|
||||
tags = tags,
|
||||
comments = parseComments(document),
|
||||
userIsAuthor =
|
||||
document
|
||||
.select(
|
||||
"ol.stories > li.story div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])"
|
||||
)
|
||||
.attr("class")
|
||||
.split(' ')
|
||||
.contains("user_is_author"),
|
||||
userIsAuthor = submitterElement.attr("class").split(' ').contains("user_is_author"),
|
||||
)
|
||||
}
|
||||
|
||||
+9
-7
@@ -11,6 +11,7 @@ import com.fleeksoft.ksoup.nodes.Element
|
||||
import dev.msfjarvis.claw.model.LobstersPost
|
||||
|
||||
private const val BASE_URL = "https://lobste.rs"
|
||||
private val commentCountRegex = "\\d+".toRegex()
|
||||
|
||||
internal fun parsePostsPage(html: String): List<LobstersPost> {
|
||||
return Ksoup.parse(html, baseUri = BASE_URL).select("li.story").map(::parsePost)
|
||||
@@ -24,19 +25,20 @@ private fun parsePost(element: Element): LobstersPost {
|
||||
"> div.story_liner div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])"
|
||||
)
|
||||
|
||||
val timestampElement = element.select("> div.story_liner div.byline > time")
|
||||
val descriptionElement = element.select("> div.story_liner a.description_present")
|
||||
val tags = element.select("> div.story_liner span.tags > a").map(Element::text)
|
||||
|
||||
return LobstersPost(
|
||||
shortId = element.attr("data-shortid"),
|
||||
createdAt =
|
||||
normalizeCreatedAt(
|
||||
element.select("> div.story_liner div.byline > time").attr("data-at-unix")
|
||||
),
|
||||
createdAt = normalizeCreatedAt(timestampElement.attr("data-at-unix")),
|
||||
title = titleElement.text(),
|
||||
url = titleElement.attr("abs:href"),
|
||||
description = element.select("> div.story_liner a.description_present").attr("title"),
|
||||
commentCount = "\\d+".toRegex().find(commentElement.text())?.value?.toInt() ?: 0,
|
||||
description = descriptionElement.attr("title"),
|
||||
commentCount = commentCountRegex.find(commentElement.text())?.value?.toInt() ?: 0,
|
||||
commentsUrl = commentElement.attr("abs:href"),
|
||||
submitter = submitterElement.text(),
|
||||
userIsAuthor = submitterElement.attr("class").split(' ').contains("user_is_author"),
|
||||
tags = element.select("> div.story_liner span.tags > a").map(Element::text),
|
||||
tags = tags,
|
||||
)
|
||||
}
|
||||
|
||||
+6
-9
@@ -17,18 +17,15 @@ internal fun parseTagsPage(html: String): List<Tag> {
|
||||
}
|
||||
|
||||
private fun parseTag(element: Element): Tag {
|
||||
val tagElement = element.select("> a.tag")
|
||||
val descriptionElement = element.select("> span:not(.byline)")
|
||||
return Tag(
|
||||
tag = element.select("> a.tag").text(),
|
||||
description = element.select("> span:not(.byline)").text(),
|
||||
tag = tagElement.text(),
|
||||
description = descriptionElement.text(),
|
||||
privileged = element.attr("data-privileged").toBoolean(),
|
||||
active =
|
||||
!element
|
||||
.select("> span:not(.byline)")
|
||||
.attr("class")
|
||||
.split(Regex("\\s+"))
|
||||
.contains("inactive_tag"),
|
||||
active = !descriptionElement.hasClass("inactive_tag"),
|
||||
category = element.attr("data-category"),
|
||||
isMedia = element.select("> a.tag").attr("class").split(Regex("\\s+")).contains("tag_is_media"),
|
||||
isMedia = tagElement.hasClass("tag_is_media"),
|
||||
hotnessMod = element.attr("data-hotness-mod").toDoubleOrNull() ?: 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user