git.fiddlerwoaroof.com
Browse code

Define sequence protocol, add atom item categories

Ed Langley authored on 12/03/2019 01:53:41
Showing 7 changed files
... ...
@@ -28,18 +28,18 @@
28 28
   (:panes
29 29
    (feeds :application
30 30
           :height 400
31
-          ;; :width 100
31
+          :width 300
32 32
           :display-function 'display-app
33 33
           :default-view (clim:with-application-frame (frame)
34 34
                           (feed-list frame)))
35 35
    (items :application
36 36
           :height 400
37
-          ;; :width  200
37
+          :width  600
38 38
           :display-function #'display-app
39 39
           :default-view *feed-view*)
40 40
    (articles :application
41 41
              :height 400
42
-             ;; :width 300
42
+             :width  600
43 43
              :display-function 'display-app
44 44
              )
45 45
    (int :interactor
... ...
@@ -158,14 +158,13 @@
158 158
             (t 'default)))))
159 159
 
160 160
 
161
+
161 162
 (defun main ()
162 163
   (clim:run-frame-top-level
163 164
    (clim:make-application-frame 'alimenta-clim::alimenta
164 165
                                 :feed-list
165 166
                                 (make-instance 'feed-list
166
-                                               :feeds (list (make-instance 'feed-url
167
-                                                                           :uri
168
-                                                                           "http://thomism.wordpress.com/feed")
169
-                                                            (make-instance 'feed-url
170
-                                                                           :uri
171
-                                                                           "http://planet.lisp.org/rss20.xml"))))))
167
+                                               :feeds (list 
168
+                                                       (make-instance 'feed-url
169
+                                                                      :uri
170
+                                                                      "http://planet.lisp.org/rss20.xml"))))))
... ...
@@ -10,7 +10,7 @@
10 10
                #:chronicity
11 11
                #:drakma
12 12
                #:for
13
-               #:fwoar.lisputils
13
+               #:fwoar-lisputils
14 14
                #:collection-class
15 15
                #:lquery
16 16
                #:plump
... ...
@@ -23,12 +23,13 @@
23 23
                (:file "alimenta")  
24 24
                (:file "data-class")
25 25
                (:file "date-handling")
26
+               (:file "render-protocol")
26 27
                (:file "atom")  
27 28
                (:file "rss")  
28 29
                (:file "fetching")
29 30
                (:file "discovery")))
30 31
 
31
-(defsystem :alimenta+patmatch 
32
+(defsystem :alimenta/patmatch 
32 33
   :description ""
33 34
   :author "Ed L <edward@elangley.org>"
34 35
   :license "MIT"
... ...
@@ -36,7 +37,7 @@
36 37
                #:uiop
37 38
                #:serapeum
38 39
                #:alimenta
39
-               #:fwoar.lisputils)
40
+               #:fwoar-lisputils)
40 41
   :serial t
41 42
   :components ((:file "pattern-matcher")))
42 43
 
... ...
@@ -24,17 +24,6 @@
24 24
   (:documentation "Given a lisp object representing a feed, return it rendered
25 25
                    to the specified format"))
26 26
 
27
-(defgeneric render-feed (feed renderer)
28
-  (:documentation "Render the container for the feed's items. Return an object
29
-                   to which the items can be added via add-rendered-item"))
30
-
31
-(defgeneric render-item (item renderer)
32
-  (:documentation "Render an item to be added to a feed. Return an object that
33
-                   can be added to the container by add-rendered-item"))
34
-
35
-(defgeneric add-rendered-item (item-representation feed-representation renderer)
36
-  (:documentation "Add the rendered item to the rendered feed"))
37
-
38 27
 (defgeneric generate-xml (feed feed-type &key partial)
39 28
   (:documentation "Given a lisp object representing a feed, return an xml
40 29
                    document"))
... ...
@@ -55,9 +44,13 @@
55 44
    (source-type :initarg :source-type :initform nil :accessor source-type)))
56 45
 
57 46
 (defmethod render ((feed feed) renderer)
58
-  (let ((doc (render-feed feed renderer)))
47
+  (let ((doc (alimenta.render:render-feed feed renderer)))
59 48
     (for:for ((item over feed))
60
-      (add-rendered-item (render-item item renderer) doc renderer))))
49
+      (setf doc
50
+            (alimenta.render:add-rendered-item doc
51
+                                               (alimenta.render:render-item item feed renderer)
52
+                                               renderer)))
53
+    doc))
61 54
 
62 55
 (defmethod (setf feed-link) ((value string) (feed feed))
63 56
   (setf (slot-value feed 'feed-link)
... ...
@@ -180,8 +173,8 @@
180 173
                  #'local-time:timestamp>
181 174
                  :key #'date)))))
182 175
 
183
-                                        ;(defun generate-xml (feed &key (feed-type :rss))
184
-                                        ;  (%generate-xml feed feed-type))
176
+;;(defun generate-xml (feed &key (feed-type :rss))
177
+;;  (%generate-xml feed feed-type))
185 178
 
186 179
 (defun to-feed (doc &key type feed-link)
187 180
   "Makes an instance of feed from the given document.  Specialize to-feed with
... ...
@@ -192,11 +185,11 @@
192 185
   (-to-feed doc type :feed-link feed-link))
193 186
 
194 187
 
195
-                                        ;(defun -get-items (feed xml-dom &key type)
196
-                                        ;  (with-accessors ((items items)) feed
197
-                                        ;    (loop for item across (get-items xml-dom type)
198
-                                        ;          do (push (make-item xml-dom type) items)
199
-                                        ;          finally (return items)))) 
188
+;;(defun -get-items (feed xml-dom &key type)
189
+;;  (with-accessors ((items items)) feed
190
+;;    (loop for item across (get-items xml-dom type)
191
+;;          do (push (make-item xml-dom type) items)
192
+;;          finally (return items)))) 
200 193
 
201 194
 (defun make-feed (&key title link items feed-link description)
202 195
   (make-instance 'feed
... ...
@@ -232,16 +225,16 @@ of this mapping directly, however any modifications to an item mutate
232 225
 the original.")
233 226
 
234 227
   (:method :around (item transform)
235
-    (call-next-method)
236
-    item)
228
+           (call-next-method)
229
+           item)
237 230
 
238 231
   (:method ((feed feed-entity) transform)
239 232
     (funcall transform feed))
240 233
 
241 234
   (:method :after ((feed feed) transform)
242
-    (map nil (lambda (it)
243
-                 (transform it transform))
244
-         (items feed))))
235
+           (map nil (lambda (it)
236
+                      (transform it transform))
237
+                (items feed))))
245 238
 
246 239
 (defun transform-content (item function)
247 240
   (setf (content item)
... ...
@@ -257,13 +250,13 @@ the original.")
257 250
         (items feed)))
258 251
 
259 252
 (deftest push-item ()
260
-    (let ((feed (make-instance 'feed))
261
-          (item (make-instance 'item)))
262
-      (with-accessors ((items items)) feed
263
-                                        ;(should signal error (push-item feed 2))
264
-        (should be eql item
265
-                (progn
266
-                  (push-item feed item)
267
-                  (car items))))))
253
+  (let ((feed (make-instance 'feed))
254
+        (item (make-instance 'item)))
255
+    (with-accessors ((items items)) feed
256
+      ;;(should signal error (push-item feed 2))
257
+      (should be eql item
258
+              (progn
259
+                (push-item feed item)
260
+                (car items))))))
268 261
 
269 262
 ;; vim: set foldmethod=marker:
... ...
@@ -5,6 +5,8 @@
5 5
   ((term :initarg :term :initform nil :accessor term)
6 6
    (label :initarg :label :initform nil :accessor label)
7 7
    (scheme :initarg :scheme :initform nil :accessor scheme)))
8
+(defmethod print-object ((o atom-category) s)
9
+  (format s "#.(~s ~s ~s ~s)" 'make-category (term o) (label o) (scheme o)))
8 10
 
9 11
 (defclass atom-person ()
10 12
   ((name  :initarg :name  :type (or null string) :initform nil :accessor name)
... ...
@@ -25,7 +27,8 @@
25 27
    (alimenta::target   :initarg :target)))
26 28
 
27 29
 (defclass atom-item (alimenta:item)
28
-  ((author-uri :initarg :author-uri :initform nil :accessor author-uri)))
30
+  ((author-uri :initarg :author-uri :initform nil :accessor author-uri)
31
+   (categories :initarg :categories :type (or null list) :initform nil :accessor categories)))
29 32
 
30 33
 (defun make-category (term &optional label scheme)
31 34
   (make-instance 'atom-category :term term :label label :scheme scheme))
... ...
@@ -60,17 +63,21 @@
60 63
          (item-content ($ "> content" (text) (node)))
61 64
          (item-author ($ "> author > name" (text) (node)))
62 65
          (item-author-uri ($ "> author > uri" (text) (node)))
66
+         (item-categories ($ (inline xml-dom) "> category"
67
+                            (combine (attr "term") (attr "label") (attr "scheme"))
68
+                            (map-apply #'make-category)))
63 69
          (*tag-dispatchers* *html-tags*)
64 70
          (content (with-output-to-string (s)
65 71
                     (awhen (or item-content item-description) (serialize  (parse it) s)))))
66 72
     (make-instance 'atom-item
67
-         :doc xml-dom
73
+                   :doc xml-dom
68 74
                    :content content
69 75
                    :date (local-time:parse-timestring item-date)
70 76
                    :id item-guid
71 77
                    :author item-author
72 78
                    :author-uri item-author-uri
73 79
                    :link item-link
80
+                   :categories (coerce item-categories 'list)
74 81
                    :title item-title)))
75 82
 
76 83
 (defun get-authors (xml-dom)
... ...
@@ -1,14 +1,40 @@
1 1
 (in-package :collection-class)
2 2
 
3
+#+nil
4
+(defmethod sequence:length ((sequence collection))
5
+  (length (items sequence)))
6
+
7
+#+sbcl
3 8
 (defmethod sb-sequence:length ((sequence collection))
4 9
   (length (items sequence)))
5 10
 
11
+#+nil
12
+(defmethod sequence:elt ((sequence collection) index)
13
+  (elt (items sequence) index))
14
+
15
+#+sbcl
6 16
 (defmethod sb-sequence:elt ((sequence collection) index)
7 17
   (elt (items sequence) index))
8 18
 
19
+#+nil
20
+(defmethod (setf sequence:elt) (new-value (sequence collection) index)
21
+  (setf (elt (items sequence) index) new-value))
22
+
23
+#+sbcl
9 24
 (defmethod (setf sb-sequence:elt) (new-value (sequence collection) index)
10 25
   (setf (elt (items sequence) index) new-value))
11 26
 
27
+#+nil
28
+(defmethod sequence:adjust-sequence ((sequence collection) length &key initial-element initial-contents)
29
+  (let ((result (duplicate-collection sequence)))
30
+    (when (or initial-element initial-contents)
31
+      (setf (items result)
32
+            (sequence:adjust-sequence (items result) length
33
+                                      :initial-element initial-element
34
+                                      :initial-contents initial-contents)))
35
+    result))
36
+
37
+#+sbcl
12 38
 (defmethod sb-sequence:adjust-sequence ((sequence collection) length &key initial-element initial-contents)
13 39
   (let ((result (duplicate-collection sequence)))
14 40
     (when (or initial-element initial-contents)
... ...
@@ -18,6 +44,16 @@
18 44
                                          :initial-contents initial-contents)))
19 45
     result))
20 46
 
47
+#+nil
48
+(defmethod sequence:make-sequence-like ((sequence collection) length &key initial-element initial-contents)
49
+  (let ((result (duplicate-collection sequence)))
50
+    (setf (items result)
51
+          (sequence:make-sequence-like (items result) length
52
+                                       :initial-element initial-element
53
+                                       :initial-contents initial-contents))
54
+    result))
55
+
56
+#+sbcl
21 57
 (defmethod sb-sequence:make-sequence-like ((sequence collection) length &key initial-element initial-contents)
22 58
   (let ((result (duplicate-collection sequence)))
23 59
     (setf (items result)
... ...
@@ -4,6 +4,10 @@
4 4
   (:use #:cl #:alexandria #:serapeum)
5 5
   (:export collection value-error push-item define-collection random-item nth-item items))
6 6
 
7
+(defpackage :alimenta.render
8
+  (:use :cl )
9
+  (:export #:render-feed #:render-item #:add-rendered-item))
10
+
7 11
 (defpackage #:data-class
8 12
   (:use #:cl #:should-test #:lquery #:plump #:alexandria #:anaphora)
9 13
   (:export #:define-data-class))
10 14
new file mode 100644
... ...
@@ -0,0 +1,12 @@
1
+(in-package :alimenta.render)
2
+
3
+(defgeneric render-feed (feed renderer)
4
+  (:documentation "Render the container for the feed's items. Return an object
5
+                   to which the items can be added via add-rendered-item"))
6
+
7
+(defgeneric render-item (item feed renderer)
8
+  (:documentation "Render an item to be added to a feed. Return an object that
9
+                   can be added to the container by add-rendered-item"))
10
+
11
+(defgeneric add-rendered-item (feed-representation item-representation renderer)
12
+  (:documentation "Add the rendered item to the rendered feed"))