Browse code
Add transform feed protocol
fiddlerwoaroof authored on 15/08/2017 01:14:31
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
;;;; alimenta.lisp |
2 |
-(declaim (optimize (speed 0) (safety 3) (debug 3))) |
|
2 |
+;; (declaim (optimize (speed 0) (safety 3) (debug 3))) |
|
3 | 3 |
|
4 | 4 |
(in-package #:alimenta) |
5 | 5 |
|
... | ... |
@@ -102,19 +102,19 @@ |
102 | 102 |
(let ((result (call-next-method feed feed-type))) |
103 | 103 |
(with-accessors ((items items)) feed |
104 | 104 |
(loop for item in items |
105 |
- do (generate-xml item feed-type :partial result))) |
|
105 |
+ do (generate-xml item feed-type :partial result))) |
|
106 | 106 |
result)) |
107 | 107 |
|
108 | 108 |
(defmethod -to-feed ((doc stream) doc-type &key feed-link) |
109 | 109 |
(-to-feed (plump:parse doc) |
110 |
- doc-type |
|
111 |
- :feed-link feed-link)) |
|
110 |
+ doc-type |
|
111 |
+ :feed-link feed-link)) |
|
112 | 112 |
|
113 | 113 |
(defmethod -to-feed ((doc string) doc-type &key feed-link) |
114 | 114 |
(-to-feed (plump:parse doc) |
115 |
- doc-type |
|
116 |
- :feed-link feed-link)) |
|
117 |
- |
|
115 |
+ doc-type |
|
116 |
+ :feed-link feed-link)) |
|
117 |
+ |
|
118 | 118 |
(defmethod -to-feed :around ((xml-dom plump:node) doc-type &key feed-link) |
119 | 119 |
"This wraps the particular methods so that _they_ don't have to implement |
120 | 120 |
item fetching. NIL passed to the type activates auto-detection" |
... | ... |
@@ -123,9 +123,9 @@ |
123 | 123 |
(setf doc xml-dom |
124 | 124 |
source-type doc-type)) |
125 | 125 |
(setf |
126 |
- (items it) |
|
127 |
- (loop for item across (get-items xml-dom doc-type) |
|
128 |
- collect (make-item item doc-type))))) |
|
126 |
+ (items it) |
|
127 |
+ (loop for item across (get-items xml-dom doc-type) |
|
128 |
+ collect (make-item item doc-type))))) |
|
129 | 129 |
|
130 | 130 |
(defgeneric (setf link) (value self)) |
131 | 131 |
(defmethod (setf link) ((value cons) (self item)) |
... | ... |
@@ -133,8 +133,8 @@ |
133 | 133 |
(destructuring-bind (type . href) value |
134 | 134 |
(when (consp href) |
135 | 135 |
(if (null (cdr href)) |
136 |
- (setf href (car href)) |
|
137 |
- (error 'type-error "too many arguments"))) |
|
136 |
+ (setf href (car href)) |
|
137 |
+ (error 'type-error "too many arguments"))) |
|
138 | 138 |
(let ((type-keyword (make-keyword (string-upcase type)))) |
139 | 139 |
(when (slot-boundp self 'links) |
140 | 140 |
(multiple-value-bind (old-link old-link-p) (gethash type-keyword links) |
... | ... |
@@ -160,8 +160,8 @@ |
160 | 160 |
|
161 | 161 |
(defun detect-feed-type (xml-dom) |
162 | 162 |
(let ((root-node-name (make-keyword (string-upcase |
163 |
- ($ (inline xml-dom) (children) |
|
164 |
- (map #'tag-name) (node)))))) |
|
163 |
+ ($ (inline xml-dom) (children) |
|
164 |
+ (map #'tag-name) (node)))))) |
|
165 | 165 |
(case root-node-name |
166 | 166 |
((:feed) :atom) |
167 | 167 |
(t root-node-name)))) |
... | ... |
@@ -180,8 +180,8 @@ |
180 | 180 |
#'local-time:timestamp> |
181 | 181 |
:key #'date))))) |
182 | 182 |
|
183 |
-;(defun generate-xml (feed &key (feed-type :rss)) |
|
184 |
-; (%generate-xml feed feed-type)) |
|
183 |
+ ;(defun generate-xml (feed &key (feed-type :rss)) |
|
184 |
+ ; (%generate-xml feed feed-type)) |
|
185 | 185 |
|
186 | 186 |
(defun to-feed (doc &key type feed-link) |
187 | 187 |
"Makes an instance of feed from the given document. Specialize to-feed with |
... | ... |
@@ -192,11 +192,11 @@ |
192 | 192 |
(-to-feed doc type :feed-link feed-link)) |
193 | 193 |
|
194 | 194 |
|
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)))) |
|
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)))) |
|
200 | 200 |
|
201 | 201 |
(defun make-feed (&key title link items feed-link description) |
202 | 202 |
(make-instance 'feed |
... | ... |
@@ -219,10 +219,35 @@ |
219 | 219 |
|
220 | 220 |
(defun filter-feed (feed function &key key) |
221 | 221 |
(setf (items feed) |
222 |
- (remove-if-not function (items feed) |
|
223 |
- :key key)) |
|
222 |
+ (remove-if-not function (items feed) |
|
223 |
+ :key key)) |
|
224 | 224 |
feed) |
225 | 225 |
|
226 |
+(defgeneric transform (item transform) |
|
227 |
+ (:documentation "transform a feed entity by TRANSFORM: the |
|
228 |
+function will be called with either a feed or a item as an arguments |
|
229 |
+and, if called upon a feed, it'll automatically be mapped across the |
|
230 |
+feed's items after being called on the feed. We do not use the results |
|
231 |
+of this mapping directly, however any modifications to an item mutate |
|
232 |
+the original.") |
|
233 |
+ |
|
234 |
+ (:method :around (item transform) |
|
235 |
+ (call-next-method) |
|
236 |
+ item) |
|
237 |
+ |
|
238 |
+ (:method ((feed feed-entity) transform) |
|
239 |
+ (funcall transform feed)) |
|
240 |
+ |
|
241 |
+ (:method :after ((feed feed) transform) |
|
242 |
+ (map nil (lambda (it) |
|
243 |
+ (transform it transform)) |
|
244 |
+ (items feed)))) |
|
245 |
+ |
|
246 |
+(defun transform-content (item function) |
|
247 |
+ (setf (content item) |
|
248 |
+ (funcall function |
|
249 |
+ (content item)))) |
|
250 |
+ |
|
226 | 251 |
(defun shorten-link (link) |
227 | 252 |
(let ((link (cl-ppcre:regex-replace "^https?:" link ""))) |
228 | 253 |
(subseq link 0 (min 30 (length link))))) |
... | ... |
@@ -232,13 +257,13 @@ |
232 | 257 |
(items feed))) |
233 | 258 |
|
234 | 259 |
(deftest push-item () |
235 |
- (let ((feed (make-instance 'feed)) |
|
236 |
- (item (make-instance 'item))) |
|
237 |
- (with-accessors ((items items)) feed |
|
238 |
- ;(should signal error (push-item feed 2)) |
|
239 |
- (should be eql item |
|
240 |
- (progn |
|
241 |
- (push-item feed item) |
|
242 |
- (car items)))))) |
|
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)))))) |
|
243 | 268 |
|
244 | 269 |
;; vim: set foldmethod=marker: |
... | ... |
@@ -17,7 +17,8 @@ |
17 | 17 |
#:doc #:source-type #:id #:date #:content #:item #:description |
18 | 18 |
#:%generate-xml #:%to-feed #:get-items #:make-item #:complex-value |
19 | 19 |
#:primary-value #:render #:author #:content-el #:feed-type-unsupported |
20 |
- #:pop-token #:filter-feed #:feed-entity)) |
|
20 |
+ #:pop-token #:filter-feed #:feed-entity |
|
21 |
+ #:transform)) |
|
21 | 22 |
|
22 | 23 |
(defpackage #:alimenta.html |
23 | 24 |
(:use #:cl #:should-test #:lquery #:alexandria #:anaphora #:alimenta #:data-class |