Advertisement
Guest User

Untitled

a guest
May 20th, 2019
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns match.core  
  2.   (:require [clojure.string :as str]))
  3.  
  4. (defn raw-param-to-typed [line]
  5.   (let [[name value] (str/split line #"=")]
  6.     {:name name :value value}))
  7.  
  8. (defn param-to-keyword [[f & tail]]
  9.   (when (and (= \? f) (seq? tail))
  10.     (keyword (apply str tail))))
  11.  
  12. (defn chain
  13.   ([x f] (f x))
  14.   ([x f & fs]
  15.    (->> (conj fs f)
  16.         (map #(% x))
  17.         (filter some?)
  18.         (first))))
  19.  
  20. (defn host-matcher [[command pattern]]
  21.   (when (= command "host")
  22.     {:command :host :pattern pattern}))
  23.  
  24. (defn path-matcher [[command pattern]]
  25.   (when (= command "path")
  26.     (println "path-matcher" pattern)
  27.     {:command :path :pattern (str/split pattern #"/")}))
  28.  
  29. (defn param-matcher [[command pattern]]
  30.   (when (= command "queryparam")
  31.     (println  "param-matcher" pattern)
  32.     (let [[param-name keyword] (str/split pattern #"=")]
  33.       {:command :param :pattern {:param-name param-name :keyword (param-to-keyword keyword)}})))
  34.  
  35. (defn url-chain [x]
  36.   (chain x
  37.          host-matcher
  38.          path-matcher
  39.          param-matcher))
  40.  
  41. (defn command-pattern [str]
  42.   (rest (re-matches #"(\w+)\(([A-Za-z0-9\/\?=\.]+)\)" str)))
  43.  
  44. (defn get-commands [line]
  45.   (let [components (->> (str/split line #";")                      
  46.                         (map (comp command-pattern str/trim))
  47.                         (map url-chain))]
  48.     (when (every? some? components)
  49.       components)))
  50.  
  51. (defn split-raw-params [line]
  52.   (println "split-raw-params" line)
  53.   (str/split line #"&"))
  54.  
  55. (defn split-raw-path [line]
  56.   (println "split-raw-path" line)
  57.   (str/split line #"/"))
  58.  
  59. (defn pattern-to-command [str-pattern]
  60.   (let [[_ command pattern] (re-matches #"(\w+)\(([A-Za-z0-9\/\?=\.]+)\)" str-pattern)]
  61.     {:command (keyword command) :pattern pattern}))
  62.  
  63. (defn scramble-url [url]
  64.   (let [url-pattern #"(?:http[s]?:\/\/)?(?:www\.)?([A-Za-z0-9\-\.]+\.\w+)(?:\/?)((?:[A-Za-z\-0-9\.]+(?:\/)?)*)\??((?:(?:\w+)=(?:\w+)&?)*)"
  65.         [_ host path params] (re-matches url-pattern url)
  66.         query-map (map raw-param-to-typed (split-raw-params params))]
  67.     {:host host :path path :queryparams query-map}))
  68.  
  69. (defn build-path-component
  70.   [pattern-comp url-comp]
  71.   (if (= (first pattern-comp) \?)
  72.     {:type :path-param :result [(param-to-keyword pattern-comp) url-comp]}
  73.     {:type :path-match :result (= pattern-comp url-comp)}))
  74.  
  75. (defn get-path
  76.   [pattern path]
  77.   (let [paths-compnents (split-raw-path path)
  78.         pattern-compnents (split-raw-path pattern)
  79.         paths (map build-path-component pattern-compnents paths-compnents)]
  80.     (when (and (= (count paths-compnents) (count pattern-compnents))
  81.                (every? true? (map :result (filter #(= (:type %) :path-match) paths))))
  82.       (map :result (filter #(= (:type %) :path-param) paths)))))
  83.  
  84. (defn get-queryparams
  85.   [{:keys [param-name keyword]} url-queryparams]
  86.   (let [{:keys [name value] :as url-param} (->> url-queryparams
  87.                                                 (filter #(= param-name (:name %)))
  88.                                                 (first))]
  89.     (when url-param
  90.       [keyword value])))
  91.  
  92. (defn ok-result [value]
  93.   {:ok value})
  94.  
  95. (defn fail-result [value]
  96.   {:error value})
  97.  
  98. (defn apply-command
  99.   [url-info {ok :ok :as result} {:keys [command pattern]}]
  100.     (if ok
  101.       (cond
  102.         (= command :host)
  103.         (if (= (:host url-info) pattern)
  104.           (ok-result ok)
  105.           (fail-result "host mismatch"))
  106.        
  107.         ; (= command :path)        
  108.         ; (let [get-path-result (get-path pattern (:path url-info))]
  109.         ;   (if get-path-result
  110.         ;     (ok-result (reduce conj ok get-path-result))
  111.         ;     (fail-result "path mismatch")))
  112.        
  113.         ; (= command :queryparam)
  114.         ; (let [query-param (get-queryparams pattern (:queryparams url-info))]
  115.         ;   (if query-param
  116.         ;     (ok-result (conj ok query-param))
  117.         ;     (fail-result (str pattern " missing"))))
  118.        
  119.         :else (fail-result "command not found!"))
  120.      
  121.       result))
  122.  
  123. (defn new-pattern [str-pattern]
  124.   (get-commands str-pattern))
  125.  
  126. (new-pattern "host(twitter.com); path(?user/status/?id); queryparam(offset=?offset);")
  127.  
  128. (defn recognize
  129.   [commands url]
  130.   (let [url-info (scramble-url url)]    
  131.     (reduce (partial apply-command url-info) (ok-result []) commands)))
  132.  
  133. (def twitter (new-pattern "host(twitter.com); path(?user/status/?id);"))
  134.  
  135. (new-pattern "host(twitter.com); path(?user/status/?id);")
  136.  
  137. (scramble-url "http://twitter.com/bradfitz/status/562360748727611392")
  138.  
  139. (recognize twitter "http://twitter.com/bradfitz/status/562360748727611392")
  140. ;; => [[:id 562360748727611392] [:user "bradfitz"]]
  141.  
  142. (def dribbble (new-pattern "host(dribbble.com); path(shots/?id); queryparam(offset=?offset);")
  143. (recognize dribbble "https://dribbble.com/shots/1905065-Travel-Icons-pack?list=users&offset=1")
  144. ;; => [[:id "1905065-Travel-Icons-pack"] [:offset "1"]]
  145. (recognize dribbble "https://twitter.com/shots/1905065-Travel-Icons-pack?list=users&offset=1")
  146. ;; => nil ;; host mismatch
  147. (recognize dribbble "https://dribbble.com/shots/1905065-Travel-Icons-pack?list=users")
  148. ;; => nil ;; offset queryparam missing
  149.  
  150. (def dribbble2 (new-pattern "host(dribbble.com); path(shots/?id); queryparam(offset=?offset); queryparam(list=?type);"))
  151.  
  152. (recognize dribbble2 "https://dribbble.com/shots/1905065-Travel-Icons-pack?list=users&offset=dgdfg")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement