aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/parsers/SearchParser.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/parsers/SearchParser.kt')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/parsers/SearchParser.kt73
1 files changed, 73 insertions, 0 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/parsers/SearchParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/parsers/SearchParser.kt
new file mode 100644
index 00000000..0d542a80
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/parsers/SearchParser.kt
@@ -0,0 +1,73 @@
+package com.pitchedapps.frost.parsers
+
+import ca.allanwang.kau.utils.withMaxLength
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.formattedFbUrlCss
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.frostJsoup
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+
+/**
+ * Created by Allan Wang on 2017-10-09.
+ */
+object SearchParser : FrostParser<List<FrostSearch>> by SearchParserImpl() {
+ fun query(input: String): List<FrostSearch>? {
+ val url = "${FbItem.SEARCH.url}?q=$input"
+ L.i(null, "Search Query $url")
+ return parse(frostJsoup(url))
+ }
+}
+
+enum class SearchKeys(val key: String) {
+ USERS("keywords_users"),
+ EVENTS("keywords_events")
+}
+
+/**
+ * As far as I'm aware, all links are independent, so the queries don't matter
+ * A lot of it is tracking information, which I'll strip away
+ * Other text items are formatted for safety
+ */
+class FrostSearch(href: String, title: String, description: String?) {
+ val href = with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) }
+ val title = title.format()
+ val description = description?.format()
+
+ private fun String.format() = replace("\n", " ").withMaxLength(50)
+
+ override fun toString(): String
+ = "FrostSearch(href=$href, title=$title, description=$description)"
+
+}
+
+private class SearchParserImpl : FrostParserBase<List<FrostSearch>>() {
+ override fun parse(doc: Document): List<FrostSearch>? {
+ val container: Element = doc.getElementById("BrowseResultsContainer")
+ ?: doc.getElementById("root")
+ ?: return null
+ val hrefSet = mutableSetOf<String>()
+ /**
+ * When mapping items, some links are duplicated because they are nested below a main one
+ * We will filter out search items whose links are already in the list
+ *
+ * Removed [data-store*=result_id]
+ */
+ return container.select("a.touchable.primary[href]").filter(Element::hasText).mapNotNull {
+ val item = FrostSearch(it.attr("href").formattedFbUrlCss,
+ it.select("._uok").first()?.text() ?: it.text(),
+ it.select("._1tcc").first()?.text())
+ if (hrefSet.contains(item.href)) return@mapNotNull null
+ hrefSet.add(item.href)
+ item
+ }
+ }
+
+ override fun textToDoc(text: String): Document? = Jsoup.parse(text)
+
+ override fun debugImpl(data: List<FrostSearch>, result: MutableList<String>) {
+ result.addAll(data.map(FrostSearch::toString))
+ }
+
+} \ No newline at end of file