rlm@1
|
1 #+title: Serving a blog using Clojure
|
rlm@1
|
2 #+author: Robert McIntyre
|
rlm@1
|
3 #+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
|
rlm@1
|
4 #+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
|
rlm@1
|
5 #+BEGIN_HTML
|
rlm@1
|
6 <h1>{{{title}}}</h1>
|
rlm@1
|
7 #+END_HTML
|
rlm@1
|
8
|
rlm@1
|
9
|
rlm@1
|
10 * Aurellem Export Program
|
rlm@1
|
11 #+srcname: publish
|
rlm@1
|
12 #+begin_src clojure :results silent
|
rlm@1
|
13 (ns aurellem.publish
|
rlm@1
|
14 (:use rlm.ns-rlm))
|
rlm@1
|
15 (rlm.ns-rlm/ns-clone rlm.light-base)
|
rlm@1
|
16 (import org.htmlcleaner.HtmlCleaner)
|
rlm@1
|
17 (import org.htmlcleaner.TagNode)
|
rlm@1
|
18 (import java.io.File)
|
rlm@1
|
19 (import java.net.URL)
|
rlm@1
|
20 (import org.apache.commons.io.FileUtils)
|
rlm@1
|
21 (use 'clojure.java.io)
|
rlm@1
|
22 (use 'rlm.sanitize-file)
|
rlm@1
|
23 (use 'net.cgrand.enlive-html)
|
rlm@1
|
24 (use 'rlm.pikasemechu)
|
rlm@1
|
25 (require 'rlm.push)
|
rlm@1
|
26 (use 'clojure.contrib.shell-out)
|
rlm@1
|
27
|
rlm@1
|
28 (declare publish)
|
rlm@1
|
29
|
rlm@1
|
30
|
rlm@1
|
31 (defvar *exports*
|
rlm@1
|
32 [(file-str "~/aurellem/src/pokemon/types.html")
|
rlm@1
|
33 (file-str "~/aurellem/src/pokemon/lpsolve.html")
|
rlm@1
|
34 (file-str "~/aurellem/src/abomination/no_parens.html")
|
rlm@1
|
35 (file-str "/home/r/aurellem/src/qm/quandary.html")
|
rlm@1
|
36 (file-str "/home/r/cortex/cortex.html")
|
rlm@1
|
37 (file-str "/home/r/cortex/capture-video.html")]
|
rlm@1
|
38 "The html files which will be exported to the auerllem
|
rlm@1
|
39 website. Listed in the order they will appear on the site
|
rlm@1
|
40 to add more entries to the site, add them here.")
|
rlm@1
|
41
|
rlm@1
|
42 (defvar *other-files*
|
rlm@1
|
43 [(file-str "/home/r/aurellem/src/MathJax/")
|
rlm@1
|
44 (file-str "/home/r/aurellem/src/css/aurellem.css")
|
rlm@1
|
45 (file-str "/home/r/aurellem/src/js/jquery.min.js")
|
rlm@1
|
46 (file-str "/home/r/aurellem/src/aurellem/err.html")
|
rlm@1
|
47 (file-str "/home/r/cortex/sources/turing.pdf")
|
rlm@1
|
48 (file-str "/home/r/cortex/images/brick-wall-standing.jpg")
|
rlm@1
|
49 (file-str "/home/r/cortex/images/brick-wall-knocked-down.jpg")
|
rlm@1
|
50 (file-str "/home/r/cortex/images/dominos.jpg")
|
rlm@1
|
51 (file-str "/home/r/cortex/images/simple-app.jpg")]
|
rlm@1
|
52
|
rlm@1
|
53 "other files needed by the website, but which are not posts.")
|
rlm@1
|
54
|
rlm@1
|
55 (defvar *index*
|
rlm@1
|
56 (file-str "~/aurellem/src/aurellem/index.html")
|
rlm@1
|
57 "this is the main index.html file for the site. It will be updated
|
rlm@1
|
58 with new posts")
|
rlm@1
|
59
|
rlm@1
|
60 (defvar *site*
|
rlm@1
|
61 (file-str "~/aurellem/site-output")
|
rlm@1
|
62 "the target output directoty for the site's content")
|
rlm@1
|
63
|
rlm@1
|
64 (defvar *export-base* (file-str "~/"))
|
rlm@1
|
65
|
rlm@1
|
66 (defn target-file [#^File file]
|
rlm@1
|
67 (file-str
|
rlm@1
|
68 (.replace (.getCanonicalPath file)
|
rlm@1
|
69 (.getCanonicalPath *export-base*)
|
rlm@1
|
70 (.getCanonicalPath *site*))))
|
rlm@1
|
71
|
rlm@1
|
72 (defn title [page]
|
rlm@1
|
73 (str (.getText (first (tags-by-name (parse page) "title")))))
|
rlm@1
|
74
|
rlm@1
|
75 (defn link [#^File file]
|
rlm@1
|
76 (.replace (.getCanonicalPath (target-file file))
|
rlm@1
|
77 (.getCanonicalPath *site*)
|
rlm@1
|
78 "."))
|
rlm@1
|
79
|
rlm@1
|
80 (defn rsync-string [#^java.io.File file]
|
rlm@1
|
81 (if (.isFile file)
|
rlm@1
|
82 (.getPath file)
|
rlm@1
|
83 (str (.getPath file) "/")))
|
rlm@1
|
84
|
rlm@1
|
85 (defn rsync-local [#^File src #^File dst]
|
rlm@1
|
86 (let [parent (.getParentFile dst)]
|
rlm@1
|
87 (if (not (.exists parent))
|
rlm@1
|
88 ;; rsync won't make parent directories
|
rlm@1
|
89 (sh "mkdir" "-p" (.getCanonicalPath parent))))
|
rlm@1
|
90 (sw "rsync" "-avz" "--human-readable" (rsync-string src) (.getCanonicalPath dst)))
|
rlm@1
|
91
|
rlm@1
|
92 (defn cp [#^File src #^File dst]
|
rlm@1
|
93 (if (.isDirectory src)
|
rlm@1
|
94 (FileUtils/copyDirectory src dst)
|
rlm@1
|
95 (FileUtils/copyFile src dst)))
|
rlm@1
|
96
|
rlm@1
|
97 (defn copy-site-files
|
rlm@1
|
98 "copy all the files in *exports* and *other-files* to the site directory
|
rlm@1
|
99 preserving the folder structure."
|
rlm@1
|
100 []
|
rlm@1
|
101 (dorun
|
rlm@1
|
102 (for [file (concat *other-files* *exports*)]
|
rlm@1
|
103 (let [source file destination (target-file file)]
|
rlm@1
|
104 (rsync-local source destination)))))
|
rlm@1
|
105
|
rlm@1
|
106 (deftemplate fill-list *index* [posts]
|
rlm@1
|
107 [:div#posts :ul.post_list :li]
|
rlm@1
|
108 (clone-for [post posts]
|
rlm@1
|
109 (content {:tag :a
|
rlm@1
|
110 :attrs {:href (link post)}
|
rlm@1
|
111 :content [(title post)]})))
|
rlm@1
|
112
|
rlm@1
|
113 (defn update-index
|
rlm@1
|
114 "update the index.html post list and write it to the site directory"
|
rlm@1
|
115 []
|
rlm@1
|
116 (println "Rebuilding index.html")
|
rlm@1
|
117 (FileUtils/writeStringToFile
|
rlm@1
|
118 (file-str "~/aurellem/site-output/index.html")
|
rlm@1
|
119 ;; reverse the list to get reverse chronological order for the site.
|
rlm@1
|
120 (apply str (fill-list *exports*))))
|
rlm@1
|
121
|
rlm@1
|
122 (defn publish-local []
|
rlm@1
|
123 (rlm.rlm-commands/re)
|
rlm@1
|
124 (copy-site-files)
|
rlm@1
|
125 (update-index))
|
rlm@1
|
126
|
rlm@1
|
127 (defn publish-web []
|
rlm@1
|
128 (publish-local)
|
rlm@1
|
129 (rlm.push/push "-u" "-t" "slice"))
|
rlm@1
|
130
|
rlm@1
|
131
|
rlm@1
|
132
|
rlm@1
|
133 #+end_src
|
rlm@1
|
134
|
rlm@1
|
135
|
rlm@1
|
136
|
rlm@1
|
137 #+begin_src clojure :results silent :tangle publish.clj :noweb yes :exports none
|
rlm@1
|
138 <<publish>>
|
rlm@1
|
139 #+end_src
|
rlm@1
|
140
|