From bd7da76b14ab823c5feb808d03c7a4cba14b380a Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 24 Sep 2017 20:50:08 -0400 Subject: Fix/adblock (#338) * Rename none to no notifications * Add pgl adblock and adblock class * Add faq * Line spacing --- .../main/kotlin/com/pitchedapps/frost/FrostApp.kt | 2 + .../pitchedapps/frost/settings/Notifications.kt | 2 +- .../com/pitchedapps/frost/utils/AdBlocker.kt | 43 ++++++++++++++++++++++ .../frost/web/FrostRequestInterceptor.kt | 15 ++------ 4 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt (limited to 'app/src/main/kotlin/com/pitchedapps') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt index 1b714ddb..2de04187 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt @@ -16,6 +16,7 @@ import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader import com.mikepenz.materialdrawer.util.DrawerImageLoader import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.services.scheduleNotifications +import com.pitchedapps.frost.utils.FrostPglAdBlock import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.Showcase @@ -51,6 +52,7 @@ class FrostApp : Application() { Prefs.verboseLogging = false L.i("Begin Frost for Facebook") FbCookie() + FrostPglAdBlock.init(this) if (Prefs.installDate == -1L) Prefs.installDate = System.currentTimeMillis() if (Prefs.identifier == -1) Prefs.identifier = Random().nextInt(Int.MAX_VALUE) Prefs.lastLaunch = System.currentTimeMillis() diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt index 30684826..0f2f8638 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt @@ -24,7 +24,7 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { text(R.string.notification_frequency, { Prefs.notificationFreq }, { Prefs.notificationFreq = it }) { val options = longArrayOf(-1, 15, 30, 60, 120, 180, 300, 1440, 2880) - val texts = options.map { minuteToText(it) } + val texts = options.map { if (it <= 0) string(R.string.no_notifications) else minuteToText(it) } onClick = { _, _, item -> materialDialogThemed { title(R.string.notification_frequency) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt new file mode 100644 index 00000000..298453dd --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt @@ -0,0 +1,43 @@ +package com.pitchedapps.frost.utils + +import android.content.Context +import android.text.TextUtils +import ca.allanwang.kau.utils.use +import okhttp3.HttpUrl +import org.jetbrains.anko.doAsync + +/** + * Created by Allan Wang on 2017-09-24. + */ +object FrostAdBlock : AdBlocker("adblock.txt") +object FrostPglAdBlock : AdBlocker("pgl.yoyo.org.txt") + +/** + * Base implementation of an AdBlocker + * Wrap this in a singleton and initialize it to use it + */ +open class AdBlocker(val assetPath: String) { + + val data: MutableSet = mutableSetOf() + + fun init(context: Context) { + doAsync { + data.addAll(context.assets.open(assetPath).bufferedReader().use { it.readLines().filter { !it.startsWith("#") } }) + L.i("Initialized adblock for $assetPath with ${data.size} hosts") + } + } + + fun isAd(url: String?): Boolean { + val httpUrl = HttpUrl.parse(url) ?: return false + return isAdHost(httpUrl.host()) + } + + tailrec fun isAdHost(host: String): Boolean { + if (TextUtils.isEmpty(host)) + return false + val index = host.indexOf(".") + if (index < 0 || index + 1 < host.length) return false + if (host.contains(host)) return true + return isAdHost(host.substring(index + 1)) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt index d3d58a5c..fdec3238 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt @@ -3,11 +3,8 @@ package com.pitchedapps.frost.web import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView -import ca.allanwang.kau.kotlin.LazyContext -import ca.allanwang.kau.kotlin.lazyContext -import ca.allanwang.kau.utils.use +import com.pitchedapps.frost.utils.FrostPglAdBlock import com.pitchedapps.frost.utils.L -import com.pitchedapps.frost.utils.Prefs import okhttp3.HttpUrl import java.io.ByteArrayInputStream @@ -23,7 +20,7 @@ private val blankResource: WebResourceResponse by lazy { WebResourceResponse("te //these hosts will redirect to a blank resource private val blacklistHost: Set = setOf( -// "edge-chat.facebook.com" //todo make more specific? This is required for message responses + // "edge-chat.facebook.com" //todo make more specific? This is required for message responses ) //these hosts will return null and skip logging @@ -41,17 +38,13 @@ private val adWhitelistHost: Set = "scontent-sea1-1.xx.fbcdn.net" ) -private val adblock: LazyContext> = lazyContext { - it.assets.open("adblock.txt").bufferedReader().use { it.readLines().toSet() } -} - fun WebView.shouldFrostInterceptRequest(request: WebResourceRequest): WebResourceResponse? { val httpUrl = HttpUrl.parse(request.url?.toString() ?: return null) ?: return null val host = httpUrl.host() val url = httpUrl.toString() - if (blacklistHost.contains(host)) return blankResource +// if (blacklistHost.contains(host)) return blankResource if (whitelistHost.contains(host)) return null - if (!adWhitelistHost.contains(host) && adblock(context).any { url.contains(it) }) return blankResource + if (!adWhitelistHost.contains(host) && FrostPglAdBlock.isAdHost(host)) return blankResource // if (!shouldLoadImages && !Prefs.loadMediaOnMeteredNetwork && request.isMedia) return blankResource L.v("Intercept Request", "$host $url") return null -- cgit v1.2.3