documentation added + more sophisticated settings file reader
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
(ns NoteHub.crossover.lib
|
||||
(:refer-clojure :exclude [hash]))
|
||||
|
||||
; very simple hash function %)
|
||||
; (doesn't work for UTF-16!)
|
||||
(defn hash [f s]
|
||||
(defn hash
|
||||
"A simple hash-function, which computes a hash from the text field
|
||||
content and given session number. It is intended to be used as a spam
|
||||
protection / captcha alternative. (Probably doesn't work for URF-16)"
|
||||
[f s]
|
||||
(let [short-mod #(mod % 32767)
|
||||
char-codes (map f
|
||||
(filter #(not (contains? #{"\n" "\r"} %)) (map str s)))]
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
(ns NoteHub.settings
|
||||
(:require [clojure.string :as cs]))
|
||||
|
||||
(defn get-setting
|
||||
"Takes a settings key, a default value and a converter function and returns a corresponding
|
||||
settings value. The default value is returned back when no setting value was found.
|
||||
The converter function can be provided to convert the setting from string to a needed format."
|
||||
[key & more]
|
||||
(let [default (first more)
|
||||
converter (second more)
|
||||
file-content (slurp "settings")
|
||||
lines (cs/split file-content #"\n")
|
||||
pairs (map #(map cs/trim %) (map #(cs/split % #"=") lines))
|
||||
config-map (apply hash-map (mapcat #(list (keyword (first %)) (second %)) pairs))
|
||||
value (config-map key)]
|
||||
(if value
|
||||
(if (fn? converter) (converter value) value)
|
||||
default)))
|
||||
+23
-9
@@ -1,24 +1,32 @@
|
||||
(ns NoteHub.storage
|
||||
(:use [NoteHub.config])
|
||||
(:use [NoteHub.settings]
|
||||
[noir.options :only [dev-mode?]])
|
||||
(:require [clj-redis.client :as redis]))
|
||||
|
||||
; Initialize the data base
|
||||
(def db
|
||||
(redis/init
|
||||
(when noir.options/dev-mode?
|
||||
{:url (config-map :db-url)})))
|
||||
(when dev-mode?
|
||||
{:url (get-setting :db-url)})))
|
||||
|
||||
; DB hierarchy levels
|
||||
(def note "note")
|
||||
|
||||
(def views "views")
|
||||
|
||||
|
||||
; Concatenates all fields to a string
|
||||
(defn- build-key [[year month day] title]
|
||||
(print-str year month day title))
|
||||
|
||||
(defn set-note [date title text]
|
||||
(defn set-note
|
||||
"Creates a note with the given title and text in the given date namespace"
|
||||
[date title text]
|
||||
(let [key (build-key date title)]
|
||||
(redis/hset db note key text)))
|
||||
|
||||
(defn get-note [date title]
|
||||
(defn get-note
|
||||
"Gets the note from the given date namespaces for the specified title"
|
||||
[date title]
|
||||
(let [key (build-key date title)
|
||||
text (redis/hget db note key)]
|
||||
(when text
|
||||
@@ -26,13 +34,19 @@
|
||||
(redis/hincrby db views key 1)
|
||||
text))))
|
||||
|
||||
(defn get-views [date title]
|
||||
(defn get-views
|
||||
"Returns the number of views for the specified date and note title"
|
||||
[date title]
|
||||
(redis/hget db views (build-key date title)))
|
||||
|
||||
(defn note-exists? [date title]
|
||||
(defn note-exists?
|
||||
"Returns true if the note with the specified title and date exists"
|
||||
[date title]
|
||||
(redis/hexists db note (build-key date title)))
|
||||
|
||||
(defn delete-note [date title]
|
||||
(defn delete-note
|
||||
"Deletes the note with the specified coordinates"
|
||||
[date title]
|
||||
(let [key (build-key date title)]
|
||||
(do
|
||||
(redis/hdel db views key)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[hiccup.page :only [include-js html5]]
|
||||
[hiccup.element :only [javascript-tag]]))
|
||||
|
||||
; Creates the main html layout
|
||||
(defpartial generate-layout
|
||||
[params title & content]
|
||||
(html5
|
||||
@@ -28,8 +29,9 @@
|
||||
(include-js "/cljs/main.js")]
|
||||
[:body content])))
|
||||
|
||||
(defn layout [& args]
|
||||
(defn layout
|
||||
"Generates the main html layout"
|
||||
[& args]
|
||||
(if (map? (first args))
|
||||
(apply generate-layout args)
|
||||
(apply generate-layout {} args)))
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
(ns NoteHub.views.css-generator
|
||||
(:use [cssgen]
|
||||
[NoteHub.settings]
|
||||
[cssgen.types]))
|
||||
|
||||
(defn gen-fontlist [& fonts]
|
||||
(defn- gen-fontlist [& fonts]
|
||||
(apply str
|
||||
(interpose ","
|
||||
(map #(str "'" % "'")
|
||||
(filter identity fonts)))))
|
||||
|
||||
; CSS Mixins
|
||||
(def page-width
|
||||
(mixin
|
||||
:width :800px))
|
||||
:width (get-setting :page-width :800px keyword)))
|
||||
|
||||
(def helvetica-neue
|
||||
(mixin
|
||||
@@ -20,6 +22,7 @@
|
||||
"Arial"
|
||||
"Lucida Grande"
|
||||
"sans-serif")))
|
||||
|
||||
(def central-element
|
||||
(mixin
|
||||
page-width
|
||||
@@ -28,7 +31,8 @@
|
||||
:margin-left "auto"
|
||||
:margin-right "auto"))
|
||||
|
||||
(defn color [theme tone]
|
||||
; Resolves the theme name & tone parameter to a concrete color
|
||||
(defn- color [theme tone]
|
||||
(get-in {:dark {:background :#333
|
||||
:foreground :#ccc
|
||||
:background-halftone :#444
|
||||
@@ -38,7 +42,9 @@
|
||||
:background-halftone :#efefef
|
||||
:foreground-halftone :#888 }} [theme tone]))
|
||||
|
||||
(defn global-css [params]
|
||||
(defn global-css
|
||||
"Generates the entire CSS rules of the app"
|
||||
[params]
|
||||
(let [theme (params :theme)
|
||||
theme (if theme (keyword theme) :default)
|
||||
header-fonts (gen-fontlist (params :header-font) "Noticia Text" "PT Serif" "Georgia")
|
||||
|
||||
+22
-16
@@ -3,6 +3,7 @@
|
||||
(:require [NoteHub.crossover.lib :as lib])
|
||||
(:use
|
||||
[NoteHub.storage]
|
||||
[NoteHub.settings]
|
||||
[clojure.string :rename {replace sreplace} :only [split replace lower-case]]
|
||||
[clojure.core.incubator :only [-?>]]
|
||||
[hiccup.form]
|
||||
@@ -16,23 +17,22 @@
|
||||
[java.util Calendar]
|
||||
[org.pegdown PegDownProcessor]))
|
||||
|
||||
; Fix a maximal title length used in the link
|
||||
(def max-title-length 80)
|
||||
|
||||
; Markdown -> HTML mapper
|
||||
(defn md-to-html [md-text]
|
||||
(.markdownToHtml (PegDownProcessor.) md-text))
|
||||
|
||||
(defn get-flash-key []
|
||||
; Creates a random session number
|
||||
(defn- get-flash-key []
|
||||
(let [k (encrypt (str (rand-int Integer/MAX_VALUE)))]
|
||||
(do (flash-put! k true)
|
||||
(print-str k))))
|
||||
|
||||
; This function answers to a corresponding AJAX request
|
||||
(defremote get-preview-md [session-key md]
|
||||
(when (flash-get session-key)
|
||||
{:session-key (get-flash-key)
|
||||
:preview (md-to-html md)}))
|
||||
; Converts given markdwon to html and wraps with layout
|
||||
(defn- wrap [params md-text]
|
||||
(if md-text
|
||||
(let [title (-?> md-text (split #"\n") first (sreplace #"[_\*#]" ""))]
|
||||
(common/layout params title [:article (md-to-html md-text)]))
|
||||
(status 404 (get-page 404))))
|
||||
|
||||
; Template for the error sites
|
||||
(defn page-setter [code message]
|
||||
@@ -41,6 +41,7 @@
|
||||
[:article
|
||||
[:h1 message]])))
|
||||
|
||||
; Sets a message for each corresponding HTTP status
|
||||
(page-setter 404 "Nothing Found.")
|
||||
(page-setter 400 "Bad request.")
|
||||
(page-setter 500 "OMG, Server Exploded.")
|
||||
@@ -48,6 +49,13 @@
|
||||
; Routes
|
||||
; ======
|
||||
|
||||
; This function answers to a AJAX request: it gets a sesion key and markdown text.
|
||||
; IT return html version of the provided markdown and a new session key
|
||||
(defremote get-preview-md [session-key md]
|
||||
(when (flash-get session-key)
|
||||
{:session-key (get-flash-key)
|
||||
:preview (md-to-html md)}))
|
||||
|
||||
; Landing Page
|
||||
(defpage "/" {}
|
||||
(common/layout "Free Markdown Hosting"
|
||||
@@ -74,21 +82,18 @@
|
||||
[:div#preview-start-line.hidden]
|
||||
[:article#preview]))
|
||||
|
||||
(defn wrap [params md-text]
|
||||
(if md-text
|
||||
(let [title (-?> md-text (split #"\n") first (sreplace #"[_\*#]" ""))]
|
||||
(common/layout params title [:article (md-to-html md-text)]))
|
||||
(status 404 (get-page 404))))
|
||||
|
||||
; Display the note
|
||||
(defpage "/:year/:month/:day/:title" {:keys [year month day title theme header-font text-font] :as params}
|
||||
(wrap
|
||||
(select-keys params [:theme :header-font :text-font])
|
||||
(get-note [year month day] title)))
|
||||
|
||||
; Provides Markdown of the specified note
|
||||
(defpage "/:year/:month/:day/:title/export" {:keys [year month day title]}
|
||||
(let [md-text (get-note [year month day] title)]
|
||||
(if md-text md-text (status 404 (get-page 404)))))
|
||||
|
||||
; Provides the number of views of the specified note
|
||||
(defpage "/:year/:month/:day/:title/stat" {:keys [year month day title]}
|
||||
(let [views (get-views [year month day] title)]
|
||||
(if views
|
||||
@@ -119,7 +124,8 @@
|
||||
(-> draft (split #"\n") first (sreplace " " "-") lower-case))
|
||||
trim (fn [s] (apply str (drop-while #(= \- %) s)))
|
||||
title-uncut (-> untrimmed-line trim reverse trim reverse)
|
||||
proposed-title (apply str (take max-title-length title-uncut))
|
||||
proposed-title (apply str (take (get-setting :max-title-length 80 #(Integer/parseInt %))
|
||||
title-uncut))
|
||||
date [year month day]
|
||||
title (first (drop-while #(note-exists? date %)
|
||||
(cons proposed-title
|
||||
|
||||
Reference in New Issue
Block a user