Advertisement
Guest User

Untitled

a guest
May 10th, 2019
118
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 split-raw-params [line]
  9.   (str/split line #"&"))
  10.  
  11. (defn split-raw-path [line]
  12.   (str/split line #"/"))
  13.  
  14. (defn pattern-to-command [str-pattern]
  15.   (let [[_ command pattern] (re-matches #"(\w+)\(([A-Za-z0-9\/\?=\.]+)\)" str-pattern)]
  16.     {:command (keyword command) :pattern pattern}))
  17.  
  18. (defn param-to-keyword [[f & tail]]
  19.   (when (and (= \? f) (seq? tail))
  20.     (keyword (apply str tail))))
  21.  
  22. (defn scramble-url [url]
  23.   (let [url-pattern #"(?:http[s]?:\/\/)?(?:www\.)?([A-Za-z0-9\-\.]+\.\w+)(?:\/?)((?:[A-Za-z\-0-9\.]+(?:\/)?)*)\??((?:(?:\w+)=(?:\w+)&?)*)"
  24.         [_ host path params] (re-matches url-pattern url)
  25.         query-map (map raw-param-to-typed (split-raw-params params))]
  26.     {:host host :path path :queryparams query-map}))
  27.  
  28. (defn build-path-component
  29.   [pattern-comp url-comp]
  30.   (if (= (first pattern-comp) \?)
  31.     {:type :path-param :result [(param-to-keyword pattern-comp) url-comp]}
  32.     {:type :path-match :result (= pattern-comp url-comp)}))
  33.  
  34. (defn get-path
  35.   [pattern path]
  36.   (let [paths-compnents (split-raw-path path)
  37.         pattern-compnents (split-raw-path pattern)
  38.         paths (map build-path-component pattern-compnents paths-compnents)]
  39.     (when (and (= (count paths-compnents) (count pattern-compnents))
  40.                (every? true? (map :result (filter #(= (:type %) :path-match) paths))))
  41.       (map :result (filter #(= (:type %) :path-param) paths)))))
  42.  
  43. (defn get-queryparams
  44.   [pattern url-queryparams]
  45.   (let [[name key] (str/split pattern #"=")
  46.         url-param (->> url-queryparams
  47.                        (filter #(= name (:name %)))
  48.                        (first))]
  49.     (when url-param
  50.       [(param-to-keyword key) (:value url-param)])))
  51.  
  52. (defn ok-result [value]
  53.   {:ok value})
  54.  
  55. (defn fail-result [value]
  56.   {:error value})
  57.  
  58. (defn apply-command
  59.   [url-info {ok :ok :as result} {:keys [command pattern]}]
  60.     (if ok
  61.       (cond
  62.         (= command :host)
  63.         (if (= (:host url-info) pattern)
  64.           (ok-result ok)
  65.           (fail-result "host mismatch"))
  66.        
  67.         (= command :path)        
  68.         (let [get-path-result (get-path pattern (:path url-info))]
  69.           (if get-path-result
  70.             (ok-result (reduce conj ok get-path-result))
  71.             (fail-result "path mismatch")))
  72.        
  73.         (= command :queryparam)
  74.         (let [query-param (get-queryparams pattern (:queryparams url-info))]
  75.           (if query-param
  76.             (ok-result (conj ok query-param))
  77.             (fail-result (str pattern " missing"))))
  78.        
  79.         :else (fail-result "command not found!"))
  80.      
  81.       result))
  82.  
  83. (defn new-pattern [str-pattern]
  84.   (map (comp pattern-to-command str/trim) (str/split str-pattern #";")))
  85.  
  86. (defn recognize
  87.   [commands url]
  88.   (let [url-info (scramble-url url)]    
  89.     (reduce (partial apply-command url-info) (ok-result []) commands)))
  90.  
  91. (def twitter (new-pattern "host(twitter.com); path(?user/status/?id);"))
  92. (recognize twitter "http://twitter.com/bradfitz/status/562360748727611392")
  93. ;; => [[:id 562360748727611392] [:user "bradfitz"]]
  94.  
  95. (def dribbble (new-pattern "host(dribbble.com); path(shots/?id); queryparam(offset=?offset);")
  96. (recognize dribbble "https://dribbble.com/shots/1905065-Travel-Icons-pack?list=users&offset=1")
  97. ;; => [[:id "1905065-Travel-Icons-pack"] [:offset "1"]]
  98. (recognize dribbble "https://twitter.com/shots/1905065-Travel-Icons-pack?list=users&offset=1")
  99. ;; => nil ;; host mismatch
  100. (recognize dribbble "https://dribbble.com/shots/1905065-Travel-Icons-pack?list=users")
  101. ;; => nil ;; offset queryparam missing
  102.  
  103. (def dribbble2 (new-pattern "host(dribbble.com); path(shots/?id); queryparam(offset=?offset); queryparam(list=?type);"))
  104.  
  105. (recognize dribbble2 "https://dribbble.com/shots/1905065-Travel-Icons-pack?list=users&offset=dgdfg")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement