Skip to content

Instantly share code, notes, and snippets.

@steeleforge
Created October 13, 2012 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steeleforge/3883247 to your computer and use it in GitHub Desktop.
Save steeleforge/3883247 to your computer and use it in GitHub Desktop.
redir
(ns redir.core
(:gen-class)
(:use
[clojure.string :only [split join]]
[clojure.java.io :only [reader writer]]
[clojure.tools.cli :only [cli]]
[fs.core :only [mkdir]]
:reload))
(defn fmt-match [in]
(str (clojure.string/replace-first in "/" "") "$"))
(def csv-header (join "," ["Domain", "Inbound URI", "Redirect Name", "Outbound URI", "Parameterized"]))
(defn docview-root [type props children]
(format "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<jcr:root xmlns:sling=\"http://sling.apache.org/jcr/sling/1.0\" xmlns:cq=\"http://www.day.com/jcr/cq/1.0\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:rep=\"internal\"\n\tjcr:primaryType=\"%s\"%s>%s</jcr:root>" type props children))
(defn docview-map [match outbound]
(docview-root "sling:Mapping"
(format "\n\tsling:match=\"%s\"\n\tsling:redirect=\"%s\"\n\tsling:status=\"{Long}301\"" (fmt-match match) outbound) ""))
(defn docview-internal-map [match outbound]
(docview-root "sling:Mapping"
(format "\n\tsling:match=\"%s\"\n\tsling:internalRedirect=\"%s\"\n\tsling:status=\"{Long}301\"" (fmt-match match) outbound) ""))
(defn docview-rule [rule idx]
(let [inbound (:inbound rule)
outbound (:outbound rule)
domain (:domain rule)
inboundParameters (let [p (:inboundParameters rule)] (if-not (nil? p) (str "\n\t\t\tinboundParameters=\"[" (join "," p) "]\"") ""))
node (str "rule_" (swap! idx inc))]
(format "\n\t\t<%s\n\t\t\tjcr:primaryType=\"nt:unstructured\"\n\t\t\tsling:resourceType=\"OMIT/components/content/global/redirectRule\"\n\t\t\tinboundUri=\"%s\"\n\t\t\toutboundUri=\"%s\"%s/>"
node inbound outbound inboundParameters)))
(defn docview-redirect [title defaultRedirect rules]
(let [i (atom 0)]
(docview-root "cq:Page" "" (format "\n\t<jcr:content\n\tjcr:title=\"%s\" \n\tjcr:primaryType=\"cq:PageContent\" \n\tcq:template=\"/apps/OMIT/templates/global/redirectPage\" \n\tsling:resourceType=\"OMIT/components/pages/global/redirectPage\" \n\thideInNav=\"true\" \n\tredirectTarget=\"%s\"> \n\t<rules \n\t\tjcr:primaryType=\"nt:unstructured\" \n\t\tsling:resourceType=\"foundation/components/parsys\"> %s \n\t</rules>\n</jcr:content>"
title defaultRedirect (reduce #(str %1 %2) (map #(docview-rule %1 i) rules)) ))))
(defn get-domain [line]
(let [parts (split line #",")]
(re-find #"[\w\.]+(?=/)" (nth parts 2 ""))))
(defn get-inbound [line]
(let [parts (split line #",") inbound (str (re-find #"/.*(?=\?)|/.*$" (nth parts 2 "")))]
(clojure.string/replace inbound #"^$" "/")))
(defn get-full-inbound [line] (str (get-domain line) (get-inbound line)))
(defn get-inbound-params [line]
(let [parts (split line #",")]
(let [token (re-find #"(?<=\?).*" (nth parts 2 ""))]
(if-not (nil? token) (split token #"&")))
))
(defn get-outbound-uri [line]
(let [parts (split line #",")]
(nth parts 3 "")))
(defn get-redirect-name [line]
(clojure.string/replace
(clojure.string/replace (get-full-inbound line) #"[\.]" "-")
#"[\/]" "_"))
(defn fmt-info [line]
{ :inbound (get-inbound line)
:inboundFull (get-full-inbound line)
:inboundParameters (get-inbound-params line)
:domain (get-domain line)
:redirectName (get-redirect-name line)
:outbound (get-outbound-uri line)
:source line })
(defn fmt-csv [info]
(str
(join ","
[(:domain info) (:inbound info) (:redirectName info) (:outbound info) (join " \t " (:inboundParameters info))] ) "\n"))
(defn generate-redirects-seq [in]
(for [item in :let [info (fmt-info item)]]
(hash-map (:redirectName info)
(list {
:inboundFull (:inboundFull info)
:inbound (:inbound info)
:inboundParameters (:inboundParameters info)
:redirectName (:redirectName info)
:outbound (:outbound info)
:source (:source info)
:domain (:domain info)
})
))
)
(defn generate-redirects [in]
(reduce #(merge-with (comp flatten list) %1 %2) (generate-redirects-seq in)))
(defn read-csv [in]
(with-open [r (reader in)]
(doall (line-seq r))
))
(defn write-csv [csv coll]
(with-open [c (writer csv)]
(.write c (str csv-header "\n"))
(doseq [line coll]
(let [info (fmt-info line)]
(.write c (fmt-csv info))
)))
)
(defn report [coll f]
(with-open [w (writer f)] (doseq [k (keys coll)] (.write w (str k " | " (count (coll k)) "\n"))))
)
(defn write-mappings [path redirs]
(doseq [redirectName (keys redirs)]
(let [info (redirs redirectName)]
(fs.core/mkdir (str "../map"))
(fs.core/mkdir (str "../map/" (:domain (first info) ".80")))
(fs.core/mkdir (str "../map/" (:domain (first info) ".80") "/" redirectName))
(with-open [w (writer (str "../map/" (:domain (first info) ".80") "/" redirectName "/.content.xml"))]
(.write w
(if (= 1 (count info))
(docview-map
(:inbound (first info))
(:outbound (first info)))
(docview-internal-map
(:inbound (first info))
(str path "/" redirectName ".html")))
))
))
)
(defn write-redirects [redirs]
(doseq [redirectName (keys redirs)]
(if-not (= 1 (count (redirs redirectName)))
(let [info (redirs redirectName)]
(fs.core/mkdir (str "../redirects"))
(fs.core/mkdir (str "../redirects/" redirectName))
(with-open [w (writer (str "../redirects/" redirectName "/.content.xml"))]
(.write w
(docview-redirect
redirectName
"/"
(doall (flatten info)))
)
)
)
)
)
)
(defn -main [& args]
(let [[opts args banner] (cli args
["-h" "--help" "Show help" :flag true :default false]
["-i" "--input" "Input CSV File"]
["-c" "--csv" "Output CSV File"]
["-p" "--path" "JCR Redirect root"])]
(when (:help opts)
(println banner)
(System/exit 0))
(do
(println "Processing...")
(let [in (:input opts) csv (:csv opts) p (:path opts) recs (read-csv in) redirs (generate-redirects recs)]
(do
(write-csv csv recs)
(write-mappings p redirs)
(write-redirects redirs)))
(println "...Complete"))
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment