git.fiddlerwoaroof.com
Browse code

inital

fiddlerwoaroof authored on 19/11/2015 07:42:41
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,139 @@
1
+(declaim (optimize (debug 3) (speed 0) (safety 3)))
2
+(ql:quickload :alexandria)
3
+(ql:quickload :ironclad)
4
+(ql:quickload :uuid)
5
+(ql:quickload :bordeaux-threads)
6
+(ql:quickload :manardb)
7
+(ql:quickload :ningle)
8
+(ql:quickload :anaphora)
9
+(ql:quickload :ubiquitous)
10
+(ql:quickload :spinneret)
11
+(ql:quickload :clack)
12
+(ql:quickload :clack-errors)
13
+
14
+(defpackage :blogerate
15
+  (:use :cl :alexandria :ningle :anaphora :ningle))
16
+
17
+(in-package :blogerate)
18
+(ubiquitous:restore 'blogerate)
19
+
20
+(manardb:use-mmap-dir "/tmp/manardb-blogerate")
21
+
22
+(manardb:defmmclass blog ()
23
+    ((id :initarg :id :accessor blog-id)
24
+     (posts :initarg :posts :accessor blog-posts :initform nil)
25
+     (tags :initform (make-hash-table :test #'equal) :accessor blog-tags)
26
+     (authors :initform (make-hash-table :test #'equal) :accessor blog-authors)
27
+     (sets :initform (make-hash-table :test #'equal) :accessor blog-sets)))
28
+
29
+(manardb:defmmclass post ()
30
+    ((id :initarg :id :accessor post-id :initform (with-output-to-string (s)
31
+                                                    (uuid:print-bytes s
32
+                                                                      (uuid:make-v5-uuid
33
+                                                                        uuid:+namespace-oid+
34
+                                                                        "blump"))))
35
+     (title :initarg :title :accessor post-title :initform "")
36
+     (text :initarg :text :accessor post-text :initform "")
37
+     (author :initarg :author :accessor post-author :initform "")
38
+     (post-set :initarg :set :accessor post-set :initform "")
39
+     (tags :initarg :tags :initform '() :accessor post-tags)))
40
+
41
+(defun make-post (blog title text author set &key (tags nil tags-p))
42
+  (let ((result (make-instance 'post :title title :text text :author author :set set :tags tags)))
43
+    (push result (blog-posts blog))
44
+    (when tags-p
45
+      (mapcar (lambda (x) (push (cons x result) (blog-tags blog)))
46
+              (post-tags result)))
47
+    (push (cons (post-set result) result) (blog-sets blog))
48
+    (push (cons (post-author result) result) (blog-authors blog))
49
+    result))
50
+
51
+(defun get-blog (id)
52
+  (flet ((new-blog () (make-instance 'blog :id id)))
53
+    (aif (manardb:retrieve-all-instances 'blog)
54
+      (aif (car (remove-if-not (lambda (x) (equal id (blog-id x))) it))
55
+        it
56
+        (new-blog))
57
+      (new-blog))))
58
+
59
+(defparameter *blog* (get-blog "my-blog3"))
60
+(defparameter *app* (make-instance 'ningle:<app>))
61
+
62
+(defmacro with-page ((&key title) &body body)
63
+  `(spinneret:with-html-string
64
+     (:doctype)
65
+     (:html
66
+       (:head
67
+         (:link :rel "stylesheet" :href "/static/main.css")
68
+         (:title ,title))
69
+       (:body ,@body))))
70
+
71
+
72
+(setf (route *app* "/post/new" :method :GET)
73
+      (lambda (params)
74
+        (declare (ignorable params))
75
+        (with-page (:title "new post")
76
+          (:header
77
+            (:h1 "New Post:"))
78
+          (:section :class "post-new"
79
+            (:form :action "/post/new" :method "POST"
80
+             (:input :type "text" :name "title")
81
+             (:input :type "text" :name "author")
82
+             (:textarea :name "post")
83
+             (:input :type "text" :name "set")
84
+             (:input :type "text" :name "tags")
85
+             (:input :type "submit"))))))
86
+
87
+(defun str-assoc-cdr (key alist)
88
+  (cdr (assoc key alist :test #'equal)))
89
+
90
+(defun split-tags (str)
91
+  (mapcar (lambda (x) (string-trim " " x)) (split-sequence:split-sequence #\, str)))
92
+
93
+(setf (route *app* "/post/new" :method :POST)
94
+      (lambda (params)
95
+        (format nil "~s" params)
96
+        (let ((new-post
97
+                (make-post *blog*
98
+                           (str-assoc-cdr "title" params)
99
+                           (str-assoc-cdr "post" params)
100
+                           (str-assoc-cdr "author" params)
101
+                           (str-assoc-cdr "set" params)
102
+                           :tags (split-tags (str-assoc-cdr "tags" params)))))
103
+          (with-page (:title (post-title new-post))
104
+            (:header
105
+              (:h1 (post-title new-post)))
106
+            (:section :class "post-show"
107
+             (:article
108
+               (post-text new-post))
109
+             (:span :class "author"
110
+              (post-author new-post))
111
+             (:span :class "set"
112
+              (post-set new-post)))))))
113
+
114
+(setf (route *app* "/" :method :GET)
115
+      (lambda (params)
116
+        (with-page (:title "Blog")
117
+          (:header
118
+            (:h1 "Blog"))
119
+          (loop for new-post in (blog-posts *blog*)
120
+                collect
121
+                (:section :class "post-show"
122
+                 (:h2
123
+                   (post-title new-post))
124
+                 (:article
125
+                   (post-text new-post))
126
+                 (:span :class "author"
127
+                  (post-author new-post))
128
+                 (:span :class "set"
129
+                  (post-set new-post)))))))
130
+
131
+
132
+(defparameter *handler*
133
+  (clack:clackup
134
+    (lack.builder:builder
135
+      :session
136
+      ;:csrf
137
+      ;clack-errors:*clack-error-middleware*
138
+      (:static :path "/static/" :root #p"./static/")
139
+      *app*) :port 5000))
0 140
new file mode 100644
... ...
@@ -0,0 +1,76 @@
1
+* {
2
+  box-sizing: border-box;
3
+  padding: 0px;
4
+  margin: 0px;
5
+}
6
+
7
+body {
8
+  background:  hsl(44, 87%, 94%);
9
+  color: hsl(194, 14%, 40%);
10
+  text-rendering: geometric-precision;
11
+  font-family: Caudex;
12
+}
13
+
14
+header {
15
+  padding: 2em;
16
+  font-size: 2vmin;
17
+  height: 10vh;
18
+  width: 66vw;
19
+  margin-left: 16.5vw;
20
+  border: thin solid black;
21
+}
22
+
23
+section.post-new, section.post-show {
24
+  padding: 2em;
25
+  width: 66vw;
26
+  margin-left: 16.5vw;
27
+  border: thin solid black;
28
+}
29
+section.post-new {
30
+  height: 90vh;
31
+}
32
+
33
+input[type=text], textarea {
34
+  display: inline-block;
35
+}
36
+
37
+input, textarea {
38
+  padding: 0.5em 1em;
39
+  border: thin solid black;
40
+  background:   hsl(44, 87%, 94%);
41
+  color: hsl(194, 14%, 40%);
42
+}
43
+
44
+section.post-new textarea {
45
+  display: block;
46
+  width: 100%;
47
+  height: 60vh;
48
+  margin-bottom: 1em;
49
+}
50
+
51
+input[name=title] {
52
+  width: 100%;
53
+  font-size: 150%;
54
+  font-weight: bolder;
55
+  margin-bottom: 1em;
56
+}
57
+input[name=author] {
58
+  width: 66%;
59
+  margin-left: 34%;
60
+  margin-bottom: 1em;
61
+}
62
+
63
+input[name=set] {
64
+  width: 24%;
65
+  margin-bottom: 1em;
66
+}
67
+
68
+input[name=tags] {
69
+  width: 74%;
70
+  margin-left: 1%;
71
+  margin-bottom: 1em;
72
+  clear: both;
73
+}
74
+
75
+input[type=submit] {
76
+}