aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-05-31 01:31:02 -0700
committerAllan Wang <me@allanwang.ca>2017-05-31 01:31:02 -0700
commit9a41937a33539dbfaae4d072361caaec79865c29 (patch)
treece647730eef90b02cb5f4612cf0e37a935500c50
parentc53e343f039b65c0aee2ee316b8c844a5b596bb8 (diff)
downloadfrost-9a41937a33539dbfaae4d072361caaec79865c29.tar.gz
frost-9a41937a33539dbfaae4d072361caaec79865c29.tar.bz2
frost-9a41937a33539dbfaae4d072361caaec79865c29.zip
implement cache db and start js injections
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt52
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt27
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/CookieMap.kt45
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt63
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt32
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/DbUtils.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt5
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt14
9 files changed, 137 insertions, 122 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index 1ea3f0e0..0ad5259d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -1,6 +1,7 @@
package com.pitchedapps.frost
import android.app.Application
+import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.retro.FrostApi
import com.pitchedapps.frost.utils.CrashReportingTree
import com.pitchedapps.frost.utils.Prefs
@@ -21,6 +22,7 @@ class FrostApp : Application() {
FlowManager.init(FlowConfig.Builder(this).build())
Prefs(this)
FrostApi(this)
+ FbCookie.init()
super.onCreate()
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
index 38d55a17..d8f349a0 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
@@ -1,12 +1,14 @@
package com.pitchedapps.frost.dbflow
+import com.pitchedapps.frost.facebook.FbCookie
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.raizlabs.android.dbflow.annotation.ConflictAction
import com.raizlabs.android.dbflow.annotation.Database
-import com.raizlabs.android.dbflow.annotation.ForeignKey
import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
+import com.raizlabs.android.dbflow.kotlinextensions.*
import com.raizlabs.android.dbflow.structure.BaseModel
-import okhttp3.Cookie
-import java.io.Serializable
/**
* Created by Allan Wang on 2017-05-30.
@@ -18,43 +20,13 @@ object CookiesDb {
const val VERSION = 1
}
-//@Database(name = CookieDb.NAME, version = CookieDb.VERSION)
-//object CookieDb {
-// const val NAME = "Cookie"
-// const val VERSION = 1
-//}
+@Table(database = CookiesDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
+data class CookieModel(@PrimaryKey var id: Long = Prefs.userIdDefault, var cookie: String? = null) : BaseModel()
-@Table(database = CookiesDb::class, allFields = true)
-data class CookieModel(@PrimaryKey var name: String,
- var value: String,
- var expiresAt: Long,
- var domain: String,
- var path: String,
- var secure: Boolean,
- var httpOnly: Boolean) {
+fun loadFbCookie(): CookieModel? = (select from CookieModel::class where (CookieModel_Table.id eq Prefs.userId)).querySingle()
- constructor(cookie: Cookie) : this(cookie.name(), cookie.value(), cookie.expiresAt(), cookie.domain(), cookie.path(), cookie.secure(), cookie.httpOnly())
- constructor() : this("", "", 0L, "", "", false, false)
-
- fun toCookie(): Cookie {
- val builder = Cookie.Builder().name(name).value(value).expiresAt(expiresAt).domain(domain).path(path)
- if (secure) builder.secure()
- if (httpOnly) builder.httpOnly()
- return builder.build()
+fun saveFbCookie() {
+ CookieModel(FbCookie.userId, FbCookie.webCookie).async save {
+ L.d("Fb cookie saved")
}
-
- fun isSecure() = secure
- fun isHttpOnly() = httpOnly
-}
-
-//class CookieList(val cookies: List<Cookie>)
-//class CookieDbList(val cookies: List<CookieDb>)
-
-//@com.raizlabs.android.dbflow.annotation.TypeConverter
-//class CookieTypeConverter() : TypeConverter<CookieDbList, CookieList>() {
-// override fun getModelValue(data: CookieDbList): CookieList = CookieList(data.cookies.map { it.toCookie() })
-// override fun getDBValue(model: CookieList): CookieDbList = CookieDbList(model.cookies.map { CookieDb(it) })
-//}
-
-@Table(database = CookiesDb::class)
-data class Cookies(@PrimaryKey var url: String = "", @ForeignKey var cookie: CookieModel = CookieModel()) \ No newline at end of file
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
index 662b97e8..067a07bf 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
@@ -16,6 +16,7 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
import com.raizlabs.android.dbflow.kotlinextensions.from
import com.raizlabs.android.dbflow.sql.language.SQLite
+import com.raizlabs.android.dbflow.structure.BaseModel
/**
* Created by Allan Wang on 2017-05-30.
@@ -33,7 +34,7 @@ data class FbTab(val title: String, val icon: IIcon, val url: String)
data class FbTabModel(
var title: String = "",
@ForeignKey(saveForeignKeyModel = true, deleteForeignKeyModel = false) var icon: IIconModel = IIconModel(),
- @PrimaryKey var url: String = "") {
+ @PrimaryKey var url: String = "") : BaseModel() {
constructor(fbTab: FbTab) : this(fbTab.title, IIconModel(fbTab.icon), fbTab.url)
fun toFbTab() = FbTab(title, icon.toIIcon(), url)
@@ -56,15 +57,19 @@ data class IIconModel(var type: Int = -1, @PrimaryKey var name: String = "") {
}
}
-enum class FbUrl(@StringRes val titleId: Int, val icon: IIcon, val url: String) {
- LOGIN(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, "https://www.facebook.com/v2.9/dialog/oauth?client_id=${FB_KEY}&redirect_uri=https://touch.facebook.com/&response_type=token,granted_scopes"),
- FEED(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, "https://touch.facebook.com/"),
- PROFILE(R.string.profile, CommunityMaterial.Icon.cmd_account, "https://touch.facebook.com/me/"),
- EVENTS(R.string.events, GoogleMaterial.Icon.gmd_event, "https://touch.facebook.com/events/upcoming"),
- FRIENDS(R.string.friends, GoogleMaterial.Icon.gmd_people, "https://touch.facebook.com/friends/center/requests/"),
- MESSAGES(R.string.messages, MaterialDesignIconic.Icon.gmi_comments, "https://touch.facebook.com/messages"),
- NOTIFICATIONS(R.string.notifications, MaterialDesignIconic.Icon.gmi_globe, "https://touch.facebook.com/notifications");
+const val FB_URL_BASE = "https://m.facebook.com/"
+//const val FB_URL_BASE = "https://touch.facebook.com/"
+enum class FbUrl(@StringRes val titleId: Int, val icon: IIcon, relativeUrl: String) {
+// LOGIN(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, "https://www.facebook.com/v2.9/dialog/oauth?client_id=${FB_KEY}&redirect_uri=https://touch.facebook.com/&response_type=token,granted_scopes"),
+ FEED(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, ""),
+ PROFILE(R.string.profile, CommunityMaterial.Icon.cmd_account, "me"),
+ EVENTS(R.string.events, GoogleMaterial.Icon.gmd_event, "events/upcoming"),
+ FRIENDS(R.string.friends, GoogleMaterial.Icon.gmd_people, "friends/center/requests"),
+ MESSAGES(R.string.messages, MaterialDesignIconic.Icon.gmi_comments, "messages"),
+ NOTIFICATIONS(R.string.notifications, MaterialDesignIconic.Icon.gmi_globe, "notifications");
+
+ val url = "$FB_URL_BASE$relativeUrl"
fun tabInfo(c: Context) = FbTab(c.getString(titleId), icon, url)
}
@@ -79,7 +84,5 @@ fun loadFbTabs(c: Context): List<FbTab> {
}
fun List<FbTab>.saveAsync(c: Context) {
- map { FbTabModel(it) }.replace(c, FbTabsDb.NAME, {
- L.e("Saved successfully")
- })
+ map { FbTabModel(it) }.replace(c, FbTabsDb.NAME)
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/CookieMap.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/CookieMap.kt
deleted file mode 100644
index 96b1f2de..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/CookieMap.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.pitchedapps.frost.facebook
-
-import android.webkit.CookieManager
-import com.pitchedapps.frost.utils.Prefs
-
-/**
- * Created by Allan Wang on 2017-05-30.
- */
-object CookieMap {
-
- var userId: Int = -1
- private val userMatcher = "c_user=([0-9]*);"
- private val map = HashMap<String, String>()
-
- operator fun get(key: String) = map[key]
-
- operator fun set(key: String, value: String) {
- map[key] = value
- }
-
- fun put(url: String, cookie: String) {
- map.put(url, cookie)
- checkUserId(url, cookie)
- }
-
- fun checkUserId(url: String, cookie: String) {
- if (userId != -1) return
- if (!url.contains("facebook") || !cookie.contains(userMatcher)) return
- val id = Regex(userMatcher).find(cookie)?.value
- if (id != null) {
- userId = id.toInt()
- save()
- }
- }
-
- fun save() {
- Prefs.userId = userId
- CookieManager.getInstance().flush()
-
- }
-
- fun reset() {
-
- }
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
new file mode 100644
index 00000000..80fc3b72
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
@@ -0,0 +1,63 @@
+package com.pitchedapps.frost.facebook
+
+import android.webkit.CookieManager
+import com.pitchedapps.frost.dbflow.FB_URL_BASE
+import com.pitchedapps.frost.dbflow.loadFbCookie
+import com.pitchedapps.frost.dbflow.saveFbCookie
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+object FbCookie {
+
+ var userId: Long = Prefs.userIdDefault
+ var dbCookie: String? = null
+ var webCookie: String?
+ get() = CookieManager.getInstance().getCookie(FB_URL_BASE)
+ set(value) = CookieManager.getInstance().setCookie(FB_URL_BASE, value)
+
+ fun init() {
+ userId = Prefs.userId
+ dbCookie = loadFbCookie()?.cookie
+ if (dbCookie != null && webCookie == null) {
+ L.d("DbCookie found & WebCookie is null; setting webcookie")
+ webCookie = dbCookie
+ }
+ }
+
+ private val userMatcher: Regex by lazy { Regex("c_user=([0-9]*);") }
+
+ fun checkUserId(url: String, cookie: String?) {
+ if (userId != Prefs.userIdDefault || cookie == null) return
+ L.d("Checking cookie for $url\n\t$cookie")
+ if (!url.contains("facebook") || !cookie.contains(userMatcher)) return
+ val id = userMatcher.find(cookie)?.groups?.get(1)?.value
+ if (id != null) {
+ try {
+ userId = id.toLong()
+ save()
+ } catch (e: NumberFormatException) {
+ //todo send report that id has changed
+ }
+ }
+ }
+
+ fun save() {
+ L.d("New cookie found for $userId")
+ Prefs.userId = userId
+ CookieManager.getInstance().flush()
+ saveFbCookie()
+ }
+
+ //TODO reset when new account is added; reset and clear when account is logged out
+ fun reset() {
+ Prefs.userId = Prefs.userIdDefault
+ userId = Prefs.userIdDefault
+ with(CookieManager.getInstance()) {
+ removeAllCookies(null)
+ flush()
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
new file mode 100644
index 00000000..e7a9df5a
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -0,0 +1,32 @@
+package com.pitchedapps.frost.injectors
+
+import android.webkit.WebView
+
+/**
+ * Created by Allan Wang on 2017-05-31.
+ */
+class JsInjector {
+ private val builder = StringBuilder()
+
+ init {
+ builder.append("javascript:(function(){")
+ }
+
+ private fun getElementById(id: String) = "document.getElementById(\"$id\")"
+
+ private fun hideElementById(id: String) {
+ builder.append(getElementById(id)).append(".style.display=\"none\";")
+ }
+
+ fun hideElementById(vararg ids: String) {
+ ids.forEach { hideElementById(it) }
+ }
+
+ fun build() = builder.toString() + "})()"
+
+ fun inject(webView: WebView) {
+ webView.loadUrl(build())
+ }
+
+ override fun toString() = build()
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/DbUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/DbUtils.kt
index 5b10e581..32d232b7 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/DbUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/DbUtils.kt
@@ -2,8 +2,8 @@ package com.pitchedapps.frost.utils
import android.content.Context
import com.raizlabs.android.dbflow.config.FlowManager
-import com.raizlabs.android.dbflow.kotlinextensions.processInTransactionAsync
-import com.raizlabs.android.dbflow.kotlinextensions.save
+import com.raizlabs.android.dbflow.kotlinextensions.*
+import com.raizlabs.android.dbflow.structure.database.transaction.FastStoreModelTransaction
import com.raizlabs.android.dbflow.structure.database.transaction.Transaction
/**
@@ -18,19 +18,8 @@ object DbUtils {
}
-inline fun <reified T : Any> List<T>.replace(context: Context, dbName: String,
- crossinline callback: ((successful: Boolean) -> Unit)) {
+inline fun <reified T : Any> List<T>.replace(context: Context, dbName: String) {
L.d("Replacing $dbName.db")
DbUtils.db(dbName).reset(context)
- this.processInTransactionAsync({
- t, databaseWrapper ->
- t.save(databaseWrapper)
- },
- Transaction.Success {
- callback.invoke(true)
- },
- Transaction.Error { _, error ->
- L.e(error.message ?: "DbReplace error")
- callback.invoke(false)
- })
+ FastStoreModelTransaction.saveBuilder(FlowManager.getModelAdapter(T::class.java)).addAll(this).build()
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
index 2ac58113..52a75929 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -25,8 +25,9 @@ object Prefs {
get() = sp.getLong(LAST_ACTIVE, -1)
set(value) = set(LAST_ACTIVE, System.currentTimeMillis())
- var userId: Int
- get() = sp.getInt(USER_ID, -1)
+ const val userIdDefault = -1L
+ var userId: Long
+ get() = sp.getLong(USER_ID, userIdDefault)
set(value) = set(USER_ID, value)
private fun set(key: String, value: Boolean) = sp.edit().putBoolean(key, value).apply()
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
index c529b224..d537d623 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
@@ -11,6 +11,7 @@ import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.webkit.*
+import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.ObservableContainer
import io.reactivex.subjects.BehaviorSubject
@@ -52,22 +53,19 @@ class FrostWebView @JvmOverloads constructor(
override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
super.onReceivedError(view, request, error)
observable.onNext(WebStatus.ERROR)
- L.e("Error ${request}")
+ L.e("FWV Error ${request}")
}
- override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
+ override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
observable.onNext(WebStatus.LOADING)
- L.d("Loading $url")
+ L.d("FWV Loading $url")
}
- override fun onPageFinished(view: WebView?, url: String?) {
+ override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
observable.onNext(WebStatus.LOADED)
- val cookie = CookieManager.getInstance().getCookie(url)
- L.d("Loaded $url")
- L.d("Cookie $cookie")
- CookieManager.getInstance().flush()
+ FbCookie.checkUserId(url, CookieManager.getInstance().getCookie(url))
}
})
}