From 9b9d7735920a8f949996751bbca2e39f95a0f852 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 30 Dec 2019 10:41:48 -0800 Subject: Use mbasic for search parser --- .../com/pitchedapps/frost/facebook/FbConst.kt | 1 + .../com/pitchedapps/frost/facebook/FbItem.kt | 12 ++++++-- .../frost/facebook/parsers/SearchParser.kt | 35 ++++++++++++++-------- .../frost/facebook/parsers/FbParseTest.kt | 1 - 4 files changed, 33 insertions(+), 16 deletions(-) (limited to 'app') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt index 8139bebc..f0f6ca7e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt @@ -25,6 +25,7 @@ const val FBCDN_NET = "fbcdn.net" const val WWW_FACEBOOK_COM = "www.$FACEBOOK_COM" const val FACEBOOK_BASE_COM = "m.$FACEBOOK_COM" const val FB_URL_BASE = "https://$FACEBOOK_BASE_COM/" +const val FB_URL_MBASIC_BASE = "https://mbasic.$FACEBOOK_COM/" fun profilePictureUrl(id: Long) = "https://graph.facebook.com/$id/picture?type=large" const val FB_LOGIN_URL = "${FB_URL_BASE}login" const val FB_HOME_URL = "${FB_URL_BASE}home.php" diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt index 265cfbe5..4df99878 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt @@ -32,7 +32,8 @@ enum class FbItem( @StringRes val titleId: Int, val icon: IIcon, relativeUrl: String, - val fragmentCreator: () -> BaseFragment = ::WebFragment + val fragmentCreator: () -> BaseFragment = ::WebFragment, + prefix: String = FB_URL_BASE ) : EnumBundle { ACTIVITY_LOG(R.string.activity_log, GoogleMaterial.Icon.gmd_list, "me/allactivity"), @@ -57,11 +58,16 @@ enum class FbItem( /** * Note that this url only works if a query (?q=) is provided */ - _SEARCH(R.string.kau_search, GoogleMaterial.Icon.gmd_search, "search/top"), + _SEARCH( + R.string.kau_search, + GoogleMaterial.Icon.gmd_search, + "search/top", + prefix = FB_URL_MBASIC_BASE + ), SETTINGS(R.string.settings, GoogleMaterial.Icon.gmd_settings, "settings"), ; - val url = "$FB_URL_BASE$relativeUrl" + val url = "$prefix$relativeUrl" val isFeed: Boolean get() = when (this) { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt index b044ee58..e4339d4f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt @@ -76,22 +76,33 @@ private class SearchParserImpl : FrostParserBase(false) { override var nameRes = FbItem._SEARCH.titleId - override val url = "${FbItem._SEARCH.url}?q=a" + override val url = "${FbItem._SEARCH.url}?q=google" override fun parseImpl(doc: Document): FrostSearches? { val container: Element = doc.getElementById("BrowseResultsContainer") ?: doc.getElementById("root") ?: return null - /** - * - * Removed [data-store*=result_id] - */ - return FrostSearches(container.select("a.touchable[href]").filter(Element::hasText).map { - FrostSearch.create( - it.attr("href").formattedFbUrl, - it.select("._uoi").first()?.text() ?: "", - it.select("._1tcc").first()?.text() - ) - }.filter { it.title.isNotBlank() }) + + return FrostSearches(container.select("table[role=presentation]").mapNotNull { el -> + // Our assumption is that search entries start with an image, followed by general info + // There may be other s, but we will not be parsing them + // Furthermore, the entry wraps a link, containing all the necessary info + val a = el.select("td").getOrNull(1)?.selectFirst("a") ?: return@mapNotNull null + val url = + a.attr("href").takeIf { it.isNotEmpty() }?.formattedFbUrl ?: return@mapNotNull null + // Currently, children should all be
elements, where the first entry is the name/title + // And the other entries are additional info. + // There are also cases of nested tables, eg for the "join" button in groups. + // Those elements have texts, so we will filter by div to ignore those + val texts = a.children().filter { it.tagName() == "div" && it.hasText() } + val title = texts.firstOrNull()?.text() ?: return@mapNotNull null + val info = texts.takeIf { it.size > 1 }?.last()?.text() + L.e { a } + create( + href = url, + title = title, + description = info + ).also { L.e { it } } + }) } } diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt index 0be29c2b..703c2074 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt @@ -71,7 +71,6 @@ class FbParseTest { @Test fun messageUser() = MessageParser.queryUser(COOKIE, "allan").test("allan query") - @Ignore("No longer works as search results don't appear in html") @Test fun search() = SearchParser.test() -- cgit v1.2.3