Browse Source

lots of minor refactorings; landing page extended

master
Christian Mueller 14 years ago
parent
commit
1ba9dc5121
  1. 1
      .gitignore
  2. 3
      Makefile
  3. 2
      settings
  4. 31
      src/NoteHub/settings.clj
  5. 3
      src/NoteHub/storage.clj
  6. 21
      src/NoteHub/views/css_generator.clj
  7. 48
      src/NoteHub/views/pages.clj
  8. 7
      test/NoteHub/test/storage.clj

1
.gitignore vendored

@ -1,3 +1,4 @@
PrivateMakefile
dump.rdb dump.rdb
resources/ resources/
pom.xml pom.xml

3
Makefile

@ -1,3 +1,6 @@
# This one is necessary to start the app in :dev mode, because
# I changed the default mode to the production, because AFAIK
# it's not possible to parameterize the app start on Heroku.
run: run:
lein run dev lein run dev

2
settings

@ -1,2 +1,2 @@
page-width = 800px page-width = 800
max-title-length = 80 max-title-length = 80

31
src/NoteHub/settings.clj

@ -1,24 +1,29 @@
(ns NoteHub.settings (ns NoteHub.settings
(:require [clojure.string :as cs])) (:refer-clojure :exclude [replace reverse])
(:use [clojure.string]))
; Load and parse te settings file returning a map
(def settings-map
(let [file-content (slurp "settings")
lines (split file-content #"\n")
pairs (map #(map trim (split % #"=")) lines)]
(apply hash-map
(mapcat #(list (keyword (first %)) (second %)) pairs))))
(defn get-setting (defn get-setting
"Takes a settings key, a default value and a converter function and returns a corresponding "Takes a settings key, a converter function and a default value, and returns a corresponding
settings value. The default value is returned back when no setting value was found. setting 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." The converter function can be provided to convert the setting from string to a needed type."
[key & more] [key & more]
(let [default (first more) (let [converter (first more)
converter (second more) default (second more)
file-content (slurp "settings") value (settings-map key)
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)
; Through this hack we can read security-critical settings from (previously ; Through this hack we can read security-critical settings from (previously
; set) shell variables without commiting their content to CVS ; set) shell variables without commiting their content to CVS
value (if-not value value (if-not value
(System/getenv (System/getenv
(cs/upper-case (upper-case
(cs/replace (name key) #"-" ""))))] (replace (name key) #"-" ""))))]
(if value (if value
(if (fn? converter) (converter value) value) (if (fn? converter) (converter value) value)
default))) default)))

3
src/NoteHub/storage.clj

@ -21,8 +21,7 @@
(defn set-note (defn set-note
"Creates a note with the given title and text in the given date namespace" "Creates a note with the given title and text in the given date namespace"
[date title text] [date title text]
(let [key (build-key date title)] (redis/hset db note (build-key date title) text))
(redis/hset db note key text)))
(defn get-note (defn get-note
"Gets the note from the given date namespaces for the specified title" "Gets the note from the given date namespaces for the specified title"

21
src/NoteHub/views/css_generator.clj

@ -12,7 +12,7 @@
; CSS Mixins ; CSS Mixins
(def page-width (def page-width
(mixin (mixin
:width (get-setting :page-width :800px keyword))) :width (px (get-setting :page-width #(Integer/parseInt %) 800))))
(def helvetica-neue (def helvetica-neue
(mixin (mixin
@ -71,18 +71,32 @@
:color foreground :color foreground
:margin 0 :margin 0
:padding 0) :padding 0)
(rule "table,tr,td"
:margin 0
:border :none)
(rule "td"
:padding :0.5em)
(rule ".one-third-column"
:text-align :justify
:vertical-align :top
; Replace this by arithmetic with css-lengths as soon as they fix the bug
:width (px (quot (get-setting :page-width #(Integer/parseInt %) 800) 3)))
(rule ".helvetica-neue" (rule ".helvetica-neue"
helvetica-neue) helvetica-neue)
(rule "#hero" (rule "#hero"
:padding-top :5em :padding-top :5em
:padding-bottom :5em :padding-bottom :5em
:text-align :center :text-align :center
(rule "h1"
:font-size :2.5em)
(rule "h2" (rule "h2"
helvetica-neue)) helvetica-neue
:margin :2em))
(rule "article" (rule "article"
central-element central-element
:line-height (% 140) :line-height (% 140)
:font-family text-fonts :font-family text-fonts
:text-align :justify
:font-size :1.2em :font-size :1.2em
(rule "& > h1:first-child" (rule "& > h1:first-child"
:text-align :center :text-align :center
@ -97,9 +111,8 @@
(rule "textarea" (rule "textarea"
page-width page-width
:font-family :Courier :font-family :Courier
:font-size :1.2em :font-size :1em
:border :none :border :none
; TODO: make this dynamic
:height :500px :height :500px
:margin-bottom :2em) :margin-bottom :2em)
(rule ".hidden" (rule ".hidden"

48
src/NoteHub/views/pages.clj

@ -1,9 +1,9 @@
(ns NoteHub.views.pages (ns NoteHub.views.pages
(:require [NoteHub.views.common :as common])
(:require [NoteHub.crossover.lib :as lib]) (:require [NoteHub.crossover.lib :as lib])
(:use (:use
[NoteHub.storage] [NoteHub.storage]
[NoteHub.settings] [NoteHub.settings]
[NoteHub.views.common]
[clojure.string :rename {replace sreplace} :only [split replace lower-case]] [clojure.string :rename {replace sreplace} :only [split replace lower-case]]
[clojure.core.incubator :only [-?>]] [clojure.core.incubator :only [-?>]]
[hiccup.form] [hiccup.form]
@ -31,13 +31,13 @@
(defn- wrap [params md-text] (defn- wrap [params md-text]
(if md-text (if md-text
(let [title (-?> md-text (split #"\n") first (sreplace #"[_\*#]" ""))] (let [title (-?> md-text (split #"\n") first (sreplace #"[_\*#]" ""))]
(common/layout params title [:article (md-to-html md-text)])) (layout params title [:article (md-to-html md-text)]))
(status 404 (get-page 404)))) (status 404 (get-page 404))))
; Template for the error sites ; Template for the error sites
(defn page-setter [code message] (defn page-setter [code message]
(set-page! code (set-page! code
(common/layout message (layout message
[:article [:article
[:h1 message]]))) [:h1 message]])))
@ -58,16 +58,46 @@
; Landing Page ; Landing Page
(defpage "/" {} (defpage "/" {}
(common/layout "Free Markdown Hosting" (layout "Free Markdown Hosting"
[:div#hero [:div#hero
[:h1 "NoteHub"] [:h1 "NoteHub"]
[:h2 "Free hosting for markdown pages."] [:h2 "Free and hassle-free hosting for markdown pages."]
[:br] [:br]
[:a.landing-button {:href "/new"} "New Page"]])) [:a.landing-button {:href "/new"} "New Page"]]
[:div#preview-start-line]
[:table.central-element.helvetica-neue
[:tr
[:td.one-third-column
[:h2 "Why?"]
"Not every person, who occasionally wants to express some thoughts, needs a blog.
Blogs are <b>tedious</b> for writers and for readers. Most people are not interested in thoughts
of other random people. Moreover, nowadays everything rotates around social networks and not
individual blogs. It makes much more sense to publish something somewhere and to share
the link with the audience on the community or social network of your choice, than to maintain a blog
trying to keep your readers interested.
<b>NoteHub</b> should be the place, where you can publish your thoughts without hassle."]
[:td.one-third-column
[:h2 "How to Use?"]
"First create a new page using the markdown syntax. Now, besides just sharing the link, you can
view some rudimentary statistics by appending <code>/stats</code> to the note url:
<pre>notehub.org/.../title/stats</pre>
If you want to export a note in the original Markdown format, append <code>/export</code>
<pre>notehub.org/.../title/export</pre>
And if you want, you also can invert the color scheme by appending <code>?theme=dark</code> to the note url.
<pre>notehub.org/.../title?theme=dark</pre>"]
[:td.one-third-column
[:h2 "For Geeks!"]
"NoteHub was an experiment and is implemented entirely in Clojure and ClojureScript. Its source code can
be found on GitHub. Look at the code to find some undocumented NoteHub features (or bugs) and &mdash; feel free to contribute!
(If you are interested in more detailed code overview, read the following note.) NoteHub's design
is intentionally kept extremelly simple and minimalistic, and should stay like this.
NoteHub's persistence layer bases on the key-value store redis.
Currently, NoteHub is hosted for free on Heroku.
Send your feedback and comments directly to @chmllr."]]]))
; New Note Page ; New Note Page
(defpage "/new" {} (defpage "/new" {}
(common/layout {:js true} "New Markdown Note" (layout {:js true} "New Markdown Note"
[:div.central-element [:div.central-element
(form-to [:post "/post-note"] (form-to [:post "/post-note"]
(hidden-field :session-key (get-flash-key)) (hidden-field :session-key (get-flash-key))
@ -97,7 +127,7 @@
(defpage "/:year/:month/:day/:title/stat" {:keys [year month day title]} (defpage "/:year/:month/:day/:title/stat" {:keys [year month day title]}
(let [views (get-views [year month day] title)] (let [views (get-views [year month day] title)]
(if views (if views
(common/layout "Statistics" (layout "Statistics"
[:article.helvetica-neue [:article.helvetica-neue
[:table {:style "width: 100%"} [:table {:style "width: 100%"}
[:tr [:tr
@ -124,7 +154,7 @@
(-> draft (split #"\n") first (sreplace " " "-") lower-case)) (-> draft (split #"\n") first (sreplace " " "-") lower-case))
trim (fn [s] (apply str (drop-while #(= \- %) s))) trim (fn [s] (apply str (drop-while #(= \- %) s)))
title-uncut (-> untrimmed-line trim reverse trim reverse) title-uncut (-> untrimmed-line trim reverse trim reverse)
proposed-title (apply str (take (get-setting :max-title-length 80 #(Integer/parseInt %)) proposed-title (apply str (take (get-setting :max-title-length #(Integer/parseInt %) 80)
title-uncut)) title-uncut))
date [year month day] date [year month day]
title (first (drop-while #(note-exists? date %) title (first (drop-while #(note-exists? date %)

7
test/NoteHub/test/storage.clj

@ -10,7 +10,12 @@
(is (= (do (is (= (do
(set-note date test-title test-note) (set-note date test-title test-note)
(get-note date test-title)) (get-note date test-title))
test-note))) test-note))
(is (= "1" (get-views date test-title)))
(is (= (do
(get-note date test-title)
(get-views date test-title))
"2")))
(testing "of the note access" (testing "of the note access"
(is (not= (get-note date test-title) "any text"))) (is (not= (get-note date test-title) "any text")))
(testing "of note existence" (testing "of note existence"

Loading…
Cancel
Save