blob: d848c0471c71822c0c630835b65403c836227fab (
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
(ns mulk.benki.wiki
(:refer-clojure :exclude [distinct conj! case compile drop take sort disj!
resultset-seq])
(:use [clojure repl pprint]
[clojure.contrib error-kit]
[hiccup core page-helpers]
[mulk.benki util db]
[clojure.core.match.core
:only [match]]
[clojureql core predicates]
noir.core)
(:require [noir.session :as session]
[noir.response :as response]
[clojure.java.jdbc :as sql])
(:import [org.jsoup.Jsoup]))
(def page_revisions (table :wiki_page_revisions))
(def pages (table :wiki_pages))
(defn- html-insert-wikilinks [text]
(clojure.string/replace
text
#"\p{javaUpperCase}+\p{javaLowerCase}+\p{javaUpperCase}+\p{javaLowerCase}+\w+"
(fn [x] (fmt nil "<a href=\"~a\" class=\"benkilink\">~a</a>" (link :wiki x) x))))
(defn- wikilinkify [tag-soup]
(let [doc (org.jsoup.Jsoup/parse tag-soup) ]
(doseq [node (into [] (.select doc "*"))
subnode (into [] (.childNodes node))]
(when (instance? org.jsoup.nodes.TextNode subnode)
(let [new-node (org.jsoup.nodes.Element.
(org.jsoup.parser.Tag/valueOf "span")
"")]
(.html new-node (html-insert-wikilinks (.text subnode)))
(.replaceWith subnode new-node)
(.unwrap new-node))))
(-> doc (.select "body") (.html))))
(defn- unwikilinkify [tag-soup]
(let [doc (org.jsoup.Jsoup/parse tag-soup)]
(doseq [node (-> doc (.select ".benkilink") (.unwrap))])
(-> doc (.select "body") (.html))))
(defpage "/wiki" []
;; NB. response/redirect calls options/resolve-uri.
(response/redirect "/wiki/Home"))
(defpage "/wiki/:title" {title :title, revision-id :revision}
(let [revisions-with-title (-> page_revisions
(select (where (=* :title title)))
(sort [:date#desc]))
revision (if revision-id
(with-dbt (first @(select page_revisions
(where (=* :id (Integer/parseInt revision-id))))))
(with-dbt (first @revisions-with-title)))]
(layout (fmt nil "~A — Benki~@[/~A~] " title revision-id)
(if revision
[:div#wiki-page-content (wikilinkify (:content revision))]
[:div#wiki-page-content [:p "This page does not exist yet."]])
[:hr]
[:div#wiki-page-footer {:style "text-align: right"}
[:a {:href (link :wiki title "/revisions")} "Page revisions"
]])))
(defpage "/wiki/:title/revisions" {title :title}
(let [;; page (-> page_revisions
;; (select (where (=* :title "abc")))
;; (project [:page])
;; (join pages (where (=* :id :page)))
;; (sort [:date#desc])
;; (project [:id])
;; (limit 1))
;; revisions (-> page
;; (rename {:id :page_id})
;; (join page_revisions (where (=* :page_id :id))))
revisions (with-dbt
(query "SELECT r.*
FROM wiki_page_revisions r
JOIN (SELECT * FROM wiki_page_revisions
WHERE title = ?
ORDER BY date DESC
LIMIT 1) pr
ON (pr.page = r.page)
ORDER BY date DESC"
"Home"))]
(with-dbt
(layout (fmt nil "Revision list — ~A — Benki" title)
[:table {:style ""}
[:thead
[:th "Date"]
[:th "Title"]]
[:tbody
(for [rev revisions]
[:tr
[:td [:a {:href (link :wiki
(:title rev)
(fmt nil "?revision=~a" (:id rev)))}
(:date rev)]]
[:td (:title rev)]])]]))))
(defn insert-empty-page []
(sql/with-query-results results ["INSERT INTO wiki_pages DEFAULT VALUES RETURNING *"]
(first (into () results))))
(defpage [:post "/wiki/:title"] {title :title, content :content}
(with-dbt
(let [revisions (-> page_revisions
(select (where (=* :title title)))
(sort [:date#desc]))
revision (first @revisions)
page (:page revision)]
(if-let [user (Integer. (session/get :user))]
(let [page-id (if page page (:id (insert-empty-page)))]
(sql/insert-values
:wiki_page_revisions
[:page :title :content :author :format]
[page-id title (unwikilinkify content) user "html5"])
{:stetus 200, :headers {}, :body (wikilinkify (unwikilinkify content))})
{:status 403, :headers {}, :body ""}))))
|