aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt29
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt98
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt94
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt37
4 files changed, 166 insertions, 92 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt
index 3d5c5bce..5709bb9f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.dbflow.CookieModel
@@ -54,7 +70,6 @@ interface FrostParser<out T : Any> {
* Call parsing with given data
*/
fun parseFromData(cookie: String?, text: String): ParseResponse<T>?
-
}
const val FALLBACK_TIME_MOD = 1000000
@@ -92,7 +107,7 @@ internal abstract class FrostParserBase<out T : Any>(private val redirectToText:
}
final override fun parseFromUrl(cookie: String?, url: String): ParseResponse<T>? =
- parse(cookie, frostJsoup(cookie, url))
+ parse(cookie, frostJsoup(cookie, url))
override fun parse(cookie: String?, document: Document): ParseResponse<T>? {
cookie ?: return null
@@ -109,17 +124,17 @@ internal abstract class FrostParserBase<out T : Any>(private val redirectToText:
* Returns the formatted url, or an empty string if nothing was found
*/
protected fun Element.getInnerImgStyle(): String? =
- select("i.img[style*=url]").getStyleUrl()
+ select("i.img[style*=url]").getStyleUrl()
protected fun Elements.getStyleUrl(): String? =
- FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl
+ FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl
protected open fun textToDoc(text: String): Document? =
- if (!redirectToText) Jsoup.parse(text)
- else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc")
+ if (!redirectToText) Jsoup.parse(text)
+ else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc")
protected fun parseLink(element: Element?): FrostLink? {
val a = element?.getElementsByTag("a")?.first() ?: return null
return FrostLink(a.text(), a.attr("href"))
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt
index 27b731bc..f05c42e9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt
@@ -1,7 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.dbflow.CookieModel
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER
+import com.pitchedapps.frost.facebook.FB_MESSAGE_NOTIF_ID_MATCHER
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.formattedFbUrl
+import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.services.NotificationContent
import com.pitchedapps.frost.utils.L
import org.apache.commons.text.StringEscapeUtils
@@ -19,12 +39,12 @@ import org.jsoup.nodes.Element
object MessageParser : FrostParser<FrostMessages> by MessageParserImpl() {
fun queryUser(cookie: String?, name: String) = parseFromUrl(cookie, "${FbItem.MESSAGES.url}/?q=$name")
-
}
-data class FrostMessages(val threads: List<FrostThread>,
- val seeMore: FrostLink?,
- val extraLinks: List<FrostLink>
+data class FrostMessages(
+ val threads: List<FrostThread>,
+ val seeMore: FrostLink?,
+ val extraLinks: List<FrostLink>
) : ParseNotification {
override fun toString() = StringBuilder().apply {
append("FrostMessages {\n")
@@ -35,19 +55,19 @@ data class FrostMessages(val threads: List<FrostThread>,
}.toString()
override fun getUnreadNotifications(data: CookieModel) =
- threads.asSequence().filter(FrostThread::unread).map {
- with(it) {
- NotificationContent(
- data = data,
- id = id,
- href = url,
- title = title,
- text = content ?: "",
- timestamp = time,
- profileUrl = img
- )
- }
- }.toList()
+ threads.asSequence().filter(FrostThread::unread).map {
+ with(it) {
+ NotificationContent(
+ data = data,
+ id = id,
+ href = url,
+ title = title,
+ text = content ?: "",
+ timestamp = time,
+ profileUrl = img
+ )
+ }
+ }.toList()
}
/**
@@ -58,14 +78,16 @@ data class FrostMessages(val threads: List<FrostThread>,
* [unread] true if image is unread, false otherwise
* [content] optional string for thread
*/
-data class FrostThread(val id: Long,
- val img: String?,
- val title: String,
- val time: Long,
- val url: String,
- val unread: Boolean,
- val content: String?,
- val contentImgUrl: String?)
+data class FrostThread(
+ val id: Long,
+ val img: String?,
+ val title: String,
+ val time: Long,
+ val url: String,
+ val unread: Boolean,
+ val content: String?,
+ val contentImgUrl: String?
+)
private class MessageParserImpl : FrostParserBase<FrostMessages>(true) {
@@ -92,11 +114,12 @@ private class MessageParserImpl : FrostParserBase<FrostMessages>(true) {
override fun parseImpl(doc: Document): FrostMessages? {
val threadList = doc.getElementById("threadlist_rows") ?: return null
- val threads: List<FrostThread> = threadList.getElementsByAttributeValueMatching("id", ".*${FB_MESSAGE_NOTIF_ID_MATCHER.pattern}.*")
+ val threads: List<FrostThread> =
+ threadList.getElementsByAttributeValueMatching("id", ".*${FB_MESSAGE_NOTIF_ID_MATCHER.pattern}.*")
.mapNotNull(this::parseMessage)
val seeMore = parseLink(doc.getElementById("see_older_threads"))
val extraLinks = threadList.nextElementSibling().select("a")
- .mapNotNull(this::parseLink)
+ .mapNotNull(this::parseLink)
return FrostMessages(threads, seeMore, extraLinks)
}
@@ -106,21 +129,20 @@ private class MessageParserImpl : FrostParserBase<FrostMessages>(true) {
val epoch = FB_EPOCH_MATCHER.find(abbr.attr("data-store"))[1]?.toLongOrNull() ?: -1L
//fetch id
val id = FB_MESSAGE_NOTIF_ID_MATCHER.find(element.id())[1]?.toLongOrNull()
- ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
+ ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
val snippet = element.select("span.snippet").firstOrNull()
val content = snippet?.text()?.trim()
val contentImg = snippet?.select("i[style*=url]")?.getStyleUrl()
val img = element.getInnerImgStyle()
return FrostThread(
- id = id,
- img = img,
- title = a.text(),
- time = epoch,
- url = a.attr("href").formattedFbUrl,
- unread = !element.hasClass("acw"),
- content = content,
- contentImgUrl = contentImg
+ id = id,
+ img = img,
+ title = a.text(),
+ time = epoch,
+ url = a.attr("href").formattedFbUrl,
+ unread = !element.hasClass("acw"),
+ content = content,
+ contentImgUrl = contentImg
)
}
-
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt
index 8aa8e706..b8aa899b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt
@@ -1,7 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.dbflow.CookieModel
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER
+import com.pitchedapps.frost.facebook.FB_NOTIF_ID_MATCHER
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.formattedFbUrl
+import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.services.NotificationContent
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
@@ -13,8 +33,8 @@ import org.jsoup.nodes.Element
object NotifParser : FrostParser<FrostNotifs> by NotifParserImpl()
data class FrostNotifs(
- val notifs: List<FrostNotif>,
- val seeMore: FrostLink?
+ val notifs: List<FrostNotif>,
+ val seeMore: FrostLink?
) : ParseNotification {
override fun toString() = StringBuilder().apply {
append("FrostNotifs {\n")
@@ -24,19 +44,19 @@ data class FrostNotifs(
}.toString()
override fun getUnreadNotifications(data: CookieModel) =
- notifs.asSequence().filter(FrostNotif::unread).map {
- with(it) {
- NotificationContent(
- data = data,
- id = id,
- href = url,
- title = null,
- text = content,
- timestamp = time,
- profileUrl = img
- )
- }
- }.toList()
+ notifs.asSequence().filter(FrostNotif::unread).map {
+ with(it) {
+ NotificationContent(
+ data = data,
+ id = id,
+ href = url,
+ title = null,
+ text = content,
+ timestamp = time,
+ profileUrl = img
+ )
+ }
+ }.toList()
}
/**
@@ -49,14 +69,16 @@ data class FrostNotifs(
* [timeString] text version of time from Facebook
* [thumbnailUrl] optional thumbnail url if existent
*/
-data class FrostNotif(val id: Long,
- val img: String?,
- val time: Long,
- val url: String,
- val unread: Boolean,
- val content: String,
- val timeString: String,
- val thumbnailUrl: String?)
+data class FrostNotif(
+ val id: Long,
+ val img: String?,
+ val time: Long,
+ val url: String,
+ val unread: Boolean,
+ val content: String,
+ val timeString: String,
+ val thumbnailUrl: String?
+)
private class NotifParserImpl : FrostParserBase<FrostNotifs>(false) {
@@ -67,8 +89,8 @@ private class NotifParserImpl : FrostParserBase<FrostNotifs>(false) {
override fun parseImpl(doc: Document): FrostNotifs? {
val notificationList = doc.getElementById("notifications_list") ?: return null
val notifications = notificationList
- .getElementsByAttributeValueMatching("id", ".*${FB_NOTIF_ID_MATCHER.pattern}.*")
- .mapNotNull(this::parseNotif)
+ .getElementsByAttributeValueMatching("id", ".*${FB_NOTIF_ID_MATCHER.pattern}.*")
+ .mapNotNull(this::parseNotif)
val seeMore = parseLink(doc.getElementsByAttributeValue("href", "/notifications.php?more").first())
return FrostNotifs(notifications, seeMore)
}
@@ -79,22 +101,20 @@ private class NotifParserImpl : FrostParserBase<FrostNotifs>(false) {
val epoch = FB_EPOCH_MATCHER.find(abbr.attr("data-store"))[1]?.toLongOrNull() ?: -1L
//fetch id
val id = FB_NOTIF_ID_MATCHER.find(element.id())[1]?.toLongOrNull()
- ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
+ ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
val img = element.getInnerImgStyle()
val timeString = abbr.text()
val content = a.text().replace("\u00a0", " ").removeSuffix(timeString).trim() //remove &nbsp;
val thumbnail = element.selectFirst("img.thumbnail")?.attr("src")
return FrostNotif(
- id = id,
- img = img,
- time = epoch,
- url = a.attr("href").formattedFbUrl,
- unread = !element.hasClass("acw"),
- content = content,
- timeString = timeString,
- thumbnailUrl = if (thumbnail?.isNotEmpty() == true) thumbnail else null
+ id = id,
+ img = img,
+ time = epoch,
+ url = a.attr("href").formattedFbUrl,
+ unread = !element.hasClass("acw"),
+ content = content,
+ timeString = timeString,
+ thumbnailUrl = if (thumbnail?.isNotEmpty() == true) thumbnail else null
)
}
-
-
}
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 d3367514..7869d881 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
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import ca.allanwang.kau.searchview.SearchItem
@@ -46,9 +62,9 @@ data class FrostSearch(val href: String, val title: String, val description: Str
companion object {
fun create(href: String, title: String, description: String?) = FrostSearch(
- with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) },
- title.format(),
- description?.format()
+ with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) },
+ title.format(),
+ description?.format()
)
}
}
@@ -61,17 +77,18 @@ private class SearchParserImpl : FrostParserBase<FrostSearches>(false) {
override fun parseImpl(doc: Document): FrostSearches? {
val container: Element = doc.getElementById("BrowseResultsContainer")
- ?: doc.getElementById("root")
- ?: return null
+ ?: 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())
+ FrostSearch.create(
+ it.attr("href").formattedFbUrl,
+ it.select("._uoi").first()?.text() ?: "",
+ it.select("._1tcc").first()?.text()
+ )
}.filter { it.title.isNotBlank() })
}
-
-} \ No newline at end of file
+}