aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
blob: 7cd93d14cfa4ac563a58a4523622f8291f3faf39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.pitchedapps.frost.facebook

import com.pitchedapps.frost.utils.L

/**
 * Created by Allan Wang on 2017-07-07.
 *
 * Custom url builder so we can easily test it without the Android framework
 */
val String.formattedFbUrl: String
    get() = FbUrlFormatter(this).toString()

class FbUrlFormatter(url: String) {
    val queries = mutableMapOf<String, String>()
    val cleaned: String

    init {
        if (url.isNullOrBlank()) cleaned = ""
        else {
            var cleanedUrl = url
            discardable.forEach { cleanedUrl = cleanedUrl.replace(it, "", true) }
            val changed = cleanedUrl != url //note that discardables strip away the first ?
            decoder.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v, true) }
            val qm = cleanedUrl.indexOf(if (changed) "&" else "?")
            if (qm > -1) {
                cleanedUrl.substring(qm + 1).split("&").forEach {
                    val p = it.split("=")
                    queries.put(p[0], p.elementAtOrNull(1) ?: "")
                }
                cleanedUrl = cleanedUrl.substring(0, qm)
            }
            discardableQueries.forEach { queries.remove(it) }
            if (cleanedUrl.startsWith("#!/")) cleanedUrl = cleanedUrl.substring(2)
            if (cleanedUrl.startsWith("/")) cleanedUrl = FB_URL_BASE + cleanedUrl.substring(1)
            cleanedUrl = cleanedUrl.replaceFirst(".facebook.com//", ".facebook.com/") //sometimes we are given a bad url
            L.v("Formatted url from $url to $cleanedUrl")
            cleaned = cleanedUrl
        }
    }

    override fun toString(): String {
        val builder = StringBuilder()
        builder.append(cleaned)
        if (queries.isNotEmpty()) {
            builder.append("?")
            queries.forEach { (k, v) -> builder.append("$k=$v&") }
        }
        return builder.removeSuffix("&").toString()
    }

    fun toLogList(): List<String> {
        val list = mutableListOf(cleaned)
        queries.forEach { (k, v) -> list.add("- $k\t=\t$v") }
        return list
    }

    companion object {
        /**
         * Items here are explicitly removed from the url
         * Taken from FaceSlim
         * https://github.com/indywidualny/FaceSlim/blob/master/app/src/main/java/org/indywidualni/fblite/util/Miscellany.java
         */
        @JvmStatic val discardable = arrayOf(
                "http://lm.facebook.com/l.php?u=",
                "https://lm.facebook.com/l.php?u=",
                "http://m.facebook.com/l.php?u=",
                "https://m.facebook.com/l.php?u=",
                "http://touch.facebook.com/l.php?u=",
                "https://touch.facebook.com/l.php?u=",
                "/video_redirect/?src="
        )

        @JvmStatic val discardableQueries = arrayOf("ref", "refid")

        @JvmStatic val decoder = mapOf(
                "%3C" to "<", "%3E" to ">", "%23" to "#", "%25" to "%",
                "%7B" to "{", "%7D" to "}", "%7C" to "|", "%5C" to "\\",
                "%5E" to "^", "%7E" to "~", "%5B" to "[", "%5D" to "]",
                "%60" to "`", "%3B" to ";", "%2F" to "/", "%3F" to "?",
                "%3A" to ":", "%40" to "@", "%3D" to "=", "%26" to "&",
                "%24" to "$", "%2B" to "+", "%22" to "\"", "%2C" to ",",
                "%20" to " ",
                //css
                "\\3C " to "<", "\\3E " to ">", "\\23 " to "#", "\\25 " to "%",
                "\\7B " to "{", "\\7D " to "}", "\\7C " to "|", "\\5C " to "\\",
                "\\5E " to "^", "\\7E " to "~", "\\5B " to "[", "\\5D " to "]",
                "\\60 " to "`", "\\3B " to ";", "\\2F " to "/", "\\3F " to "?",
                "\\3A " to ":", "\\40 " to "@", "\\3D " to "=", "\\26 " to "&",
                "\\24 " to "$", "\\2B " to "+", "\\22 " to "\"", "\\2C " to ",",
                "\\20 " to " "
        )
    }
}