This repository has been archived by the owner on Feb 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
forums.lisp
141 lines (122 loc) · 4.04 KB
/
forums.lisp
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
(in-package #:hacksthenet)
(defclass post ()
((parent-thread :type thread
:initarg :parent
:reader parent-thread)
(author-name :type string
:initarg :author
:reader author-name)
(content :type string
:initarg :content
:accessor dirty-content)
(time :type integer
:initform (get-universal-time)
:reader post-time)
(id :type integer
:initarg :id
:reader id)))
(defclass thread ()
((parent-forum :type forum
:initarg :parent
:reader parent-forum)
(posts :type (vector post)
:initform (make-array 0 :fill-pointer 0 :adjustable t)
:accessor posts)
(author-name :type string
:initarg :author
:reader author-name)
(content :type string
:initarg :content
:accessor dirty-content)
(time :type integer
:initform (get-universal-time)
:reader post-time)
(name :type string
:initarg :name
:accessor dirty-name)
(id :type integer
:initarg :id
:reader id)))
(defclass forum ()
((name :type string
:initarg :name
:accessor dirty-name)
(description :type string
:initarg :description
:accessor dirty-description)
(threads :type (or cons null)
:initform ()
:accessor threads)
(post-counter :type integer
:initform 0
:accessor post-counter)
(thread-counter :type integer
:initform 0
:accessor thread-counter)))
(defvar *forums* (make-array 0 :fill-pointer 0 :adjustable t))
(defun author (obj)
(find-account (author-name obj)))
(defun content (obj)
(sanitize (dirty-content obj)))
(defun name (obj)
(sanitize (dirty-name obj)))
(defun description (obj)
(sanitize (dirty-description obj)))
(defun find-forum (name)
(find-if (lambda (forum)
(string= name
(name forum)))
*forums*))
(defun make-forum (name description)
(unless (find-forum name)
(vector-push-extend (make-instance 'forum
:name name
:description description)
*forums*)
name))
(defun delete-forum (name)
(setf *forums* (delete-if
(lambda (forum)
(string= name
(name forum)))
*forums*)))
(defun make-thread (forum author-name name content)
(let ((thread (make-instance 'thread
:parent forum
:author author-name
:content content
:name name
:id (incf (thread-counter forum)))))
(push thread (threads forum))
(id thread)))
(defun make-thread* (forum name content)
(make-thread forum
(username (session-account))
name content))
(defun find-thread (forum-name id)
"On success returns two values: the thread, and its forum. On
failure returns NIL."
(let ((forum (find-forum forum-name)))
(when forum
(values (find-if (lambda (thread)
(= id (id thread)))
(threads forum))
forum))))
(defun make-post (thread author content)
(let ((post (make-instance 'post
:parent thread
:author (username author)
:content content
:id (incf (post-counter (parent-forum thread))))))
(vector-push-extend post (posts thread))
(id post)))
(defun make-post* (thread content)
"On success returns the post's ID. On failure returns NIL."
(make-post thread (session-account) content))
(defmethod posts ((forum forum))
(loop for thread in (threads forum)
append (posts thread)))
(defun find-post (forum id)
(find-if (lambda (post)
(= id (id post)))
(posts forum)))