aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2018-12-24 01:47:03 -0500
committerGitHub <noreply@github.com>2018-12-24 01:47:03 -0500
commit697d01882ba8b1dbb85484ba3bf6e810e32448fc (patch)
treef59d2407ffbd724200e3c79eb366a8da1efe0829 /app/src/main/kotlin/com/pitchedapps/frost/facebook/requests
parentc45b30e28f451699f3be828a1201260ed27e321e (diff)
downloadfrost-697d01882ba8b1dbb85484ba3bf6e810e32448fc.tar.gz
frost-697d01882ba8b1dbb85484ba3bf6e810e32448fc.tar.bz2
frost-697d01882ba8b1dbb85484ba3bf6e810e32448fc.zip
Enhancement/ktlint (#1259)
* Add spotless * Reformat code * Apply license header * Add remaining license headers
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/facebook/requests')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt61
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt49
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt137
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt32
5 files changed, 208 insertions, 97 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt
index 500c4102..584107cc 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt
@@ -1,7 +1,29 @@
+/*
+ * 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.requests
import com.pitchedapps.frost.BuildConfig
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_DTSG_MATCHER
+import com.pitchedapps.frost.facebook.FB_JSON_URL_MATCHER
+import com.pitchedapps.frost.facebook.FB_REV_MATCHER
+import com.pitchedapps.frost.facebook.FB_URL_BASE
+import com.pitchedapps.frost.facebook.FB_USER_MATCHER
+import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.rx.RxFlyweight
import com.pitchedapps.frost.utils.L
import io.reactivex.Single
@@ -21,10 +43,9 @@ private class RxAuth : RxFlyweight<String, Long, RequestAuth>() {
override fun call(input: String) = input.getAuth()
override fun validate(input: String, cond: Long) =
- System.currentTimeMillis() - cond < 3600000 // valid for an hour
+ System.currentTimeMillis() - cond < 3600000 // valid for an hour
override fun cache(input: String) = System.currentTimeMillis()
-
}
private val auth = RxAuth()
@@ -48,10 +69,12 @@ fun String?.fbRequest(fail: () -> Unit = {}, action: RequestAuth.() -> Unit) {
/**
* Underlying container for all fb requests
*/
-data class RequestAuth(val userId: Long = -1,
- val cookie: String = "",
- val fb_dtsg: String = "",
- val rev: String = "") {
+data class RequestAuth(
+ val userId: Long = -1,
+ val cookie: String = "",
+ val fb_dtsg: String = "",
+ val rev: String = ""
+) {
val isComplete
get() = userId > 0 && cookie.isNotEmpty() && fb_dtsg.isNotEmpty() && rev.isNotEmpty()
}
@@ -64,8 +87,8 @@ class FrostRequest<out T : Any?>(val call: Call, private val invoke: (Call) -> T
}
internal inline fun <T : Any?> RequestAuth.frostRequest(
- noinline invoke: (Call) -> T,
- builder: Request.Builder.() -> Request.Builder // to ensure we don't do anything extra at the end
+ noinline invoke: (Call) -> T,
+ builder: Request.Builder.() -> Request.Builder // to ensure we don't do anything extra at the end
): FrostRequest<T> {
val request = cookie.requestBuilder()
request.builder()
@@ -75,8 +98,10 @@ internal inline fun <T : Any?> RequestAuth.frostRequest(
val httpClient: OkHttpClient by lazy {
val builder = OkHttpClient.Builder()
if (BuildConfig.DEBUG)
- builder.addInterceptor(HttpLoggingInterceptor()
- .setLevel(HttpLoggingInterceptor.Level.BASIC))
+ builder.addInterceptor(
+ HttpLoggingInterceptor()
+ .setLevel(HttpLoggingInterceptor.Level.BASIC)
+ )
builder.build()
}
@@ -97,7 +122,7 @@ internal fun List<Pair<String, Any?>>.withEmptyData(vararg key: String): List<Pa
internal fun String?.requestBuilder(): Request.Builder {
val builder = Request.Builder()
- .header("User-Agent", USER_AGENT_BASIC)
+ .header("User-Agent", USER_AGENT_BASIC)
if (this != null)
builder.header("Cookie", this)
// .cacheControl(CacheControl.FORCE_NETWORK)
@@ -112,9 +137,9 @@ fun String.getAuth(): RequestAuth {
val id = FB_USER_MATCHER.find(this)[1]?.toLong() ?: return auth
auth = auth.copy(userId = id)
val call = this.requestBuilder()
- .url(FB_URL_BASE)
- .get()
- .call()
+ .url(FB_URL_BASE)
+ .get()
+ .call()
call.execute().body()?.charStream()?.useLines { lines ->
lines.forEach {
val text = StringEscapeUtils.unescapeEcmaScript(it)
@@ -135,8 +160,10 @@ fun String.getAuth(): RequestAuth {
return auth
}
-inline fun <T, reified R : Any, O> Array<T>.zip(crossinline mapper: (List<R>) -> O,
- crossinline caller: (T) -> R): Single<O> {
+inline fun <T, reified R : Any, O> Array<T>.zip(
+ crossinline mapper: (List<R>) -> O,
+ crossinline caller: (T) -> R
+): Single<O> {
if (isEmpty())
return Single.just(mapper(emptyList()))
val singles = map { Single.fromCallable { caller(it) }.subscribeOn(Schedulers.io()) }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt
index 8eeef08d..e0ccea81 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.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.requests
import com.bumptech.glide.Priority
@@ -11,7 +27,11 @@ import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.signature.ObjectKey
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_IMAGE_ID_MATCHER
+import com.pitchedapps.frost.facebook.FB_REDIRECT_URL_MATCHER
+import com.pitchedapps.frost.facebook.FB_URL_BASE
+import com.pitchedapps.frost.facebook.formattedFbUrl
+import com.pitchedapps.frost.facebook.get
import io.reactivex.Maybe
import okhttp3.Call
import okhttp3.Request
@@ -33,9 +53,9 @@ val test: () -> InputStream? = { null }
*/
fun String.getFullSizedImageUrl(url: String): Maybe<String?> = Maybe.fromCallable {
val redirect = requestBuilder().url(url).get().call()
- .execute().body()?.string() ?: return@fromCallable null
+ .execute().body()?.string() ?: return@fromCallable null
return@fromCallable FB_REDIRECT_URL_MATCHER.find(redirect)[1]?.formattedFbUrl
- ?: return@fromCallable null
+ ?: return@fromCallable null
}.onErrorComplete()
/**
@@ -51,7 +71,6 @@ data class HdImageMaybe(val url: String, val cookie: String) {
val isValid: Boolean by lazy {
id != -1L && cookie.isNotBlank()
}
-
}
/*
@@ -69,18 +88,20 @@ class HdImageLoadingFactory : ModelLoaderFactory<HdImageMaybe, InputStream> {
}
fun <T> RequestBuilder<T>.loadWithPotentialHd(model: HdImageMaybe) =
- thumbnail(clone().load(model.url))
- .load(model)
- .apply(RequestOptions().override(Target.SIZE_ORIGINAL))
+ thumbnail(clone().load(model.url))
+ .load(model)
+ .apply(RequestOptions().override(Target.SIZE_ORIGINAL))
class HdImageLoading : ModelLoader<HdImageMaybe, InputStream> {
- override fun buildLoadData(model: HdImageMaybe,
- width: Int,
- height: Int,
- options: Options): ModelLoader.LoadData<InputStream>? =
- if (!model.isValid) null
- else ModelLoader.LoadData(ObjectKey(model), HdImageFetcher(model))
+ override fun buildLoadData(
+ model: HdImageMaybe,
+ width: Int,
+ height: Int,
+ options: Options
+ ): ModelLoader.LoadData<InputStream>? =
+ if (!model.isValid) null
+ else ModelLoader.LoadData(ObjectKey(model), HdImageFetcher(model))
override fun handles(model: HdImageMaybe) = model.isValid
}
@@ -105,7 +126,7 @@ class HdImageFetcher(private val model: HdImageMaybe) : DataFetcher<InputStream>
model.cookie.fbRequest(fail = { callback.fail("Invalid auth") }) {
if (cancelled) return@fbRequest callback.fail("Cancelled")
val url = getFullSizedImage(model.id).invoke()
- ?: return@fbRequest callback.fail("Null url")
+ ?: return@fbRequest callback.fail("Null url")
if (cancelled) return@fbRequest callback.fail("Cancelled")
if (!url.contains("png") && !url.contains("jpg")) return@fbRequest callback.fail("Invalid format")
urlCall = Request.Builder().url(url).get().call()
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt
index e83e4e43..dcb0ce10 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.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.requests
import com.fasterxml.jackson.annotation.JsonCreator
@@ -19,28 +35,27 @@ import java.io.IOException
fun RequestAuth.getMenuData(): FrostRequest<MenuData?> {
val body = listOf(
- "fb_dtsg" to fb_dtsg,
- "__user" to userId
+ "fb_dtsg" to fb_dtsg,
+ "__user" to userId
).withEmptyData("m_sess", "__dyn", "__req", "__ajax__")
return frostRequest(::parseMenu) {
url("${FB_URL_BASE}bookmarks/flyout/body/?id=u_0_2")
post(body.toForm())
}
-
}
fun parseMenu(call: Call): MenuData? {
val fullString = call.execute().body()?.string() ?: return null
var jsonString = fullString.substringAfter("bookmarkGroups", "")
- .substringAfter("[", "")
+ .substringAfter("[", "")
if (jsonString.isBlank()) return null
jsonString = "{ \"data\" : [${StringEscapeUtils.unescapeEcmaScript(jsonString)}"
val mapper = ObjectMapper()
- .disable(MapperFeature.AUTO_DETECT_SETTERS)
+ .disable(MapperFeature.AUTO_DETECT_SETTERS)
return try {
val data = mapper.readValue(jsonString, MenuData::class.java)
@@ -48,11 +63,14 @@ fun parseMenu(call: Call): MenuData? {
// parse footer content
val footer = fullString.substringAfter("footerMarkup", "")
- .substringAfter("{", "")
- .substringBefore("}", "")
-
- val doc = Jsoup.parseBodyFragment(StringEscapeUtils.unescapeEcmaScript(
- StringEscapeUtils.unescapeEcmaScript(footer)))
+ .substringAfter("{", "")
+ .substringBefore("}", "")
+
+ val doc = Jsoup.parseBodyFragment(
+ StringEscapeUtils.unescapeEcmaScript(
+ StringEscapeUtils.unescapeEcmaScript(footer)
+ )
+ )
val footerData = mutableListOf<MenuFooterItem>()
val footerSmallData = mutableListOf<MenuFooterItem>()
@@ -76,11 +94,14 @@ fun parseMenu(call: Call): MenuData? {
}
@JsonIgnoreProperties(ignoreUnknown = true)
-data class MenuData(val data: List<MenuHeader> = emptyList(),
- val footer: MenuFooter = MenuFooter()) {
-
- @JsonCreator constructor(
- @JsonProperty("data") data: List<MenuHeader>?
+data class MenuData(
+ val data: List<MenuHeader> = emptyList(),
+ val footer: MenuFooter = MenuFooter()
+) {
+
+ @JsonCreator
+ constructor(
+ @JsonProperty("data") data: List<MenuHeader>?
) : this(data ?: emptyList(), MenuFooter())
fun flatMapValid(): List<MenuItemData> {
@@ -95,7 +116,6 @@ data class MenuData(val data: List<MenuHeader> = emptyList(),
return items
}
-
}
interface MenuItemData {
@@ -103,17 +123,20 @@ interface MenuItemData {
}
@JsonIgnoreProperties(ignoreUnknown = true)
-data class MenuHeader(val id: String? = null,
- val header: String? = null,
- val visible: List<MenuItem> = emptyList(),
- val all: List<MenuItem> = emptyList()) : MenuItemData {
-
- @JsonCreator constructor(
- @JsonProperty("id") id: String?,
- @JsonProperty("header") header: String?,
- @JsonProperty("visible") visible: List<MenuItem>?,
- @JsonProperty("all") all: List<MenuItem>?,
- @JsonProperty("fake") fake: Boolean?
+data class MenuHeader(
+ val id: String? = null,
+ val header: String? = null,
+ val visible: List<MenuItem> = emptyList(),
+ val all: List<MenuItem> = emptyList()
+) : MenuItemData {
+
+ @JsonCreator
+ constructor(
+ @JsonProperty("id") id: String?,
+ @JsonProperty("header") header: String?,
+ @JsonProperty("visible") visible: List<MenuItem>?,
+ @JsonProperty("all") all: List<MenuItem>?,
+ @JsonProperty("fake") fake: Boolean?
) : this(id, header, visible ?: emptyList(), all ?: emptyList())
override val isValid: Boolean
@@ -121,41 +144,49 @@ data class MenuHeader(val id: String? = null,
}
@JsonIgnoreProperties(ignoreUnknown = true)
-data class MenuItem(val id: String? = null,
- val name: String? = null,
- val pic: String? = null,
- val url: String? = null,
- val badge: String? = null,
- val countDetails: String? = null) : MenuItemData {
-
- @JsonCreator constructor(
- @JsonProperty("id") id: String?,
- @JsonProperty("name") name: String?,
- @JsonProperty("pic") pic: String?,
- @JsonProperty("url") url: String?,
- @JsonProperty("count") badge: String?,
- @JsonProperty("count_details") countDetails: String?,
- @JsonProperty("fake") fake: Boolean?
- ) : this(id, name, pic?.formattedFbUrl,
- url?.formattedFbUrl,
- if (badge == "0") null else badge,
- countDetails)
+data class MenuItem(
+ val id: String? = null,
+ val name: String? = null,
+ val pic: String? = null,
+ val url: String? = null,
+ val badge: String? = null,
+ val countDetails: String? = null
+) : MenuItemData {
+
+ @JsonCreator
+ constructor(
+ @JsonProperty("id") id: String?,
+ @JsonProperty("name") name: String?,
+ @JsonProperty("pic") pic: String?,
+ @JsonProperty("url") url: String?,
+ @JsonProperty("count") badge: String?,
+ @JsonProperty("count_details") countDetails: String?,
+ @JsonProperty("fake") fake: Boolean?
+ ) : this(
+ id, name, pic?.formattedFbUrl,
+ url?.formattedFbUrl,
+ if (badge == "0") null else badge,
+ countDetails
+ )
override val isValid: Boolean
get() = !name.isNullOrBlank() && !url.isNullOrBlank()
}
-data class MenuFooter(val data: List<MenuFooterItem> = emptyList(),
- val smallData: List<MenuFooterItem> = emptyList()) {
+data class MenuFooter(
+ val data: List<MenuFooterItem> = emptyList(),
+ val smallData: List<MenuFooterItem> = emptyList()
+) {
val hasContent
get() = data.isNotEmpty() || smallData.isNotEmpty()
-
}
-data class MenuFooterItem(val name: String? = null,
- val url: String? = null,
- val isSmall: Boolean = false) : MenuItemData {
+data class MenuFooterItem(
+ val name: String? = null,
+ val url: String? = null,
+ val isSmall: Boolean = false
+) : MenuItemData {
override val isValid: Boolean
get() = name != null && url != null
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt
index 0e37a61e..f350c547 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.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.requests
import com.pitchedapps.frost.facebook.FB_URL_BASE
@@ -10,10 +26,10 @@ fun RequestAuth.sendMessage(group: String, content: String): FrostRequest<Boolea
// todo test more; only tested against tids=cid...
val body = listOf(
- "tids" to group,
- "body" to content,
- "fb_dtsg" to fb_dtsg,
- "__user" to userId
+ "tids" to group,
+ "body" to content,
+ "fb_dtsg" to fb_dtsg,
+ "__user" to userId
).withEmptyData("m_sess", "__dyn", "__req", "__ajax__")
return frostRequest(::validateMessage) {
@@ -29,4 +45,4 @@ private fun validateMessage(call: Call): Boolean {
val body = call.execute().body() ?: return false
// todo
return true
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt
index 0d3926dc..43815b67 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.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.requests
import com.pitchedapps.frost.facebook.FB_URL_BASE
@@ -8,11 +24,11 @@ import com.pitchedapps.frost.facebook.FB_URL_BASE
fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest<Boolean> {
val body = listOf(
- "click_type" to "notification_click",
- "id" to notifId,
- "target_id" to "null",
- "fb_dtsg" to fb_dtsg,
- "__user" to userId
+ "click_type" to "notification_click",
+ "id" to notifId,
+ "target_id" to "null",
+ "fb_dtsg" to fb_dtsg,
+ "__user" to userId
).withEmptyData("m_sess", "__dyn", "__req", "__ajax__")
return frostRequest(::executeForNoError) {
@@ -22,6 +38,6 @@ fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest<Boolean> {
}
fun RequestAuth.markNotificationsRead(vararg notifId: Long) =
- notifId.toTypedArray().zip<Long, Boolean, Boolean>(
- { it.all { self -> self } },
- { markNotificationRead(it).invoke() }) \ No newline at end of file
+ notifId.toTypedArray().zip<Long, Boolean, Boolean>(
+ { it.all { self -> self } },
+ { markNotificationRead(it).invoke() })