git.fiddlerwoaroof.com
Browse code

chore: maintenance

fiddlerwoaroof authored on 21/06/2020 19:37:15
Showing 4 changed files
... ...
@@ -36,19 +36,19 @@
36 36
                    (items alimenta:items)
37 37
                    (link alimenta:link)
38 38
                    (source-type alimenta:source-type)
39
-                   (title alimenta:title)) feed)
40
-  (yason:with-output (stream :indent t)
41
-    (yason:with-object ()
42
-      (yason:encode-object-element "metadata" feed)
43
-      (yason:with-object-element ("items")
44
-        (yason:with-array ()
45
-          (dolist (item item-storage-info)
46
-            (with-simple-restart (skip-item "Skip item ~s" (car item))
47
-              ;; (format t "~&I Store Info: ~a~%~4t~a~%" (uiop:unix-namestring (cadr item)) root-dir)
48
-              (%encode-item root-dir item)
49
-              #+null
50
-              (yason:encode-array-element (uiop:unix-namestring (uiop:enough-pathname root-dir (cadr item))))
51
-              )))))))
39
+                   (title alimenta:title)) feed
40
+    (yason:with-output (stream :indent t)
41
+      (yason:with-object ()
42
+        (yason:encode-object-element "metadata" feed)
43
+        (yason:with-object-element ("items")
44
+          (yason:with-array ()
45
+            (dolist (item item-storage-info)
46
+              (with-simple-restart (skip-item "Skip item ~s" (car item))
47
+                ;; (format t "~&I Store Info: ~a~%~4t~a~%" (uiop:unix-namestring (cadr item)) root-dir)
48
+                (%encode-item root-dir item)
49
+                #+null
50
+                (yason:encode-array-element (uiop:unix-namestring (uiop:enough-pathname root-dir (cadr item))))
51
+                ))))))))
52 52
 
53 53
 (defmethod store ((items sequence) storage)
54 54
   (when (next-method-p)
... ...
@@ -73,14 +73,15 @@
73 73
                      (title alimenta:title)) feed
74 74
                                         ; We wrap all errors with our own condition
75 75
       (handler-bind ((error (lambda (c) (error 'feed-error :feed feed :condition c))))
76
-        (values (prog1-let ((feed-title title)
77
-                            (feed-store (get-feed-store-name feed directory)))
78
-                  (ensure-directories-exist feed-store)
79
-                  (with-open-file (index (merge-pathnames "index.json" feed-store) :direction :output)
80
-                    (%encode-feed-as-json feed
81
-                                          (store (copy-seq items) feed-store)
82
-                                          feed-store
83
-                                          index)))
76
+        (values (multiple-value-list
77
+                 (prog1-let ((feed-title title)
78
+                             (feed-store (get-feed-store-name feed directory)))
79
+                   (ensure-directories-exist feed-store)
80
+                   (with-open-file (index (merge-pathnames "index.json" feed-store) :direction :output)
81
+                     (%encode-feed-as-json feed
82
+                                           (store (copy-seq items) feed-store)
83
+                                           feed-store
84
+                                           index))))
84 85
                 feed-link)))))
85 86
 
86 87
 (defmethod store ((feed alimenta:feed) (stream stream))
... ...
@@ -104,14 +105,16 @@
104 105
            (let ((id (get-id item)))
105 106
              (merge-pathnames (make-pathname :name id :version nil :type "json") directory))))
106 107
 
107
-    (prog1-let ((item-title (alimenta:title item))
108
-                (fn (get-item-store-name item directory)))
109
-      (with-open-file (item-f fn :direction :output)
110
-        (yason:encode item item-f)))))
108
+    (multiple-value-list
109
+     (prog1-let ((item-title (alimenta:title item))
110
+                 (fn (get-item-store-name item directory)))
111
+       (with-open-file (item-f fn :direction :output)
112
+         (yason:encode item item-f))))))
111 113
 
112 114
 (defmethod store ((item alimenta:item) (stream stream))
113 115
   (yason:with-output (stream :indent t)
114
-    (yason:encode-slots item))
116
+    (yason:with-object ()
117
+      (yason:encode-slots item)))
115 118
   (list (alimenta:title item)
116 119
         stream))
117 120
 
... ...
@@ -133,9 +136,15 @@
133 136
   (let ((id (get-id item)))
134 137
     (make-pathname :name id :version nil :type "json")))
135 138
 
136
-(defclass feed-stream-provider (stream-provider:file-provider)
139
+(defclass feed-stream-item-provider ()
137 140
   ((%item-providers :accessor item-providers :initform (make-hash-table :test 'equal))))
138 141
 
142
+(defclass feed-stream-provider (stream-provider:file-provider feed-stream-item-provider)
143
+  ())
144
+
145
+(defclass feed-stream-string-provider (stream-provider:string-provider feed-stream-item-provider)
146
+  ())
147
+
139 148
 (defmethod stream-provider:get-nested-provider ((provider stream-provider:stream-provider) (streamable alimenta:feed))
140 149
   (with (items-root (uiop:merge-pathnames* (uiop:pathname-directory-pathname (stream-provider:stream-key provider streamable))
141 150
                                            (stream-provider:root provider)))
... ...
@@ -173,10 +182,11 @@
173 182
       (let* ((item-provider (stream-provider:get-nested-provider stream-provider feed))
174 183
              (item-storage-info (map-coalesce (op (store _ item-provider))
175 184
                                               items)))
176
-        (yason:with-output (s :indent t)
185
+        (let ((yason::*json-output*
186
+                (make-instance 'yason::json-output-stream
187
+                               :output-stream s
188
+                               :indent t)))
177 189
           (with-collection (item "items" item-storage-info "metadata" feed)
178 190
             (destructuring-bind (title path) item
179 191
               (yason:with-object ()
180
-                (yason:encode-object-elements
181
-                 "title" title
182
-                 "path" path)))))))))
192
+                (yason:encode-object-elements "title" title "path" path)))))))))
... ...
@@ -8,12 +8,14 @@
8 8
 
9 9
 (defun get-store-directory-name (timestamp)
10 10
   (flet ((make-dirname (timestamp)
11
-           (-> (local-time:format-timestring nil (local-time:timestamp-minimize-part timestamp :sec)
12
-                                             :format +dirname-format+)
13
-               (merge-pathnames *feed-base*))))
14
-    (-> (prog1-let ((result (make-dirname timestamp)))
15
-          (ensure-directories-exist result))
16
-        (car))))
11
+           (merge-pathnames
12
+            (local-time:format-timestring nil
13
+                                          (local-time:timestamp-minimize-part timestamp
14
+                                                                              :sec)
15
+                                          :format +dirname-format+)
16
+            *feed-base*)))
17
+    (values (prog1-let ((result (make-dirname timestamp)))
18
+              (ensure-directories-exist result)))))
17 19
 
18 20
 (defun test-feed-list ()
19 21
   (values '("http://feeds.feedburner.com/GamasutraFeatureArticles/"
... ...
@@ -37,30 +39,39 @@
37 39
            (ubiquitous:value :feeds)
38 40
            :test #'equalp))
39 41
 
42
+(defmacro lambda* ((&rest args) &body body)
43
+  (let ((rest-arg (gensym "REST")))
44
+    `(lambda (,@args &rest ,rest-arg)
45
+       (declare (ignore ,rest-arg))
46
+       ,@body)))
47
+
40 48
 (defun safe-pull-feed (feed-url &aux (pop-times 0))
41 49
   "Handles date parsing errors in the feed: chronicity won't parse
42 50
    certain date formats, this catches the error and modifies the
43 51
    format to something chronicity can handle."
44
-  (flet ((pop-50-tokens (c)
45
-           (declare (ignore c))
46
-           (when (find-restart 'alimenta:pop-token) 
47
-             (if (< pop-times 50)
48
-                 (progn (incf pop-times)
49
-                        (format t "~&Processing error, trying to pop a token (popped ~d times)~%"
50
-                                pop-times)
51
-                        (alimenta:pop-token))
52
-                 (continue)))))
53
-    (handler-bind ((warning #'muffle-warning)
54
-                   (error #'pop-50-tokens))
55
-      (prog1-bind (feed (alimenta.pull-feed:pull-feed feed-url))
56
-        ;; Why am I decf-ing here?
57
-        (alimenta:transform feed
58
-                            (fw.lu:glambda (entity)
59
-                              (:method (entity))
60
-                              (:method ((entity alimenta:item))
61
-                                (setf (alimenta:content entity)
62
-                                      (html-sanitizer:sanitize (alimenta:content entity))))))
63
-        (decf pop-times)))))
52
+  (handler-bind ((warning #'muffle-warning)
53
+                 (error (lambda* (c)
54
+                          (when (find-restart 'alimenta:pop-token c)
55
+                            (cond
56
+                              ((< pop-times 50)
57
+                               (incf pop-times)
58
+                               (format t
59
+                                       "~&Processing error, trying to pop a token (popped ~d times)~%"
60
+                                       pop-times)
61
+                               (alimenta:pop-token))
62
+                              (t
63
+                               (continue)))))))
64
+    (prog1-bind (feed (alimenta.pull-feed:pull-feed feed-url))
65
+      ;; Why am I decf-ing here?
66
+      (alimenta:transform feed
67
+                          (fw.lu:glambda (entity)
68
+                            (:method (entity))
69
+                            (:method ((entity alimenta:item))
70
+                              (let ((v (alimenta:content entity)))
71
+                                (when v
72
+                                  (setf (alimenta:content entity)
73
+                                        (html-sanitizer:sanitize v)))))))
74
+      (decf pop-times))))
64 75
 
65 76
 (defmacro with-progress-message ((stream before after &optional (error-msg " ERROR~%~4t~a~%")) &body body)
66 77
   (once-only (before after stream)
... ...
@@ -115,10 +126,10 @@
115 126
                               (merge-pathnames path
116 127
                                                (stream-provider:root stream-provider)))))
117 128
     (handler-bind ((cl+ssl:ssl-error-verify
118
-                    (lambda (c)
119
-                      (declare (ignore c))
120
-                      (format *error-output* "~&SSL Error while pulling ~a~%"
121
-                              feed-url))))
129
+                     (lambda (c)
130
+                       (declare (ignore c))
131
+                       (format *error-output* "~&SSL Error while pulling ~a~%"
132
+                               feed-url))))
122 133
       (with-simple-restart (skip-feed "Stop processing for ~a" feed-url)
123 134
         (let* ((feed (with-retry ("Pull feed again.")
124 135
                        (normalize-feed feed-url (log-pull t)))))
... ...
@@ -139,7 +150,7 @@
139 150
 
140 151
 (defun archive-feeds-nondeterm ()
141 152
   (let* ((pull-time (local-time:now))
142
-         (pull-directory (get-store-directory-name pull-time)) 
153
+         (pull-directory (get-store-directory-name pull-time))
143 154
          (index-path (merge-pathnames "index.json" pull-directory))
144 155
          (feed-stream-provider (make-instance 'alimenta.feed-archive.encoders:feed-stream-provider
145 156
                                               :if-exists :error
... ...
@@ -157,34 +168,44 @@
157 168
                      (alimenta:feed-type c)
158 169
                      (alimenta:feed-link c))
159 170
              (funcall restart))
160
-           (fix-pathname-or-skip (c &key (restart 'skip-feed) (wrapped-condition nil wc-p))
171
+           (fix-pathname-or-skip (c &key
172
+                                      (restart 'skip-feed)
173
+                                      (wrapped-condition nil wc-p))
161 174
              (typecase (or wrapped-condition c)
162 175
                (alimenta:feed-type-unsupported (feed-type-unsupported c))
163
-               (otherwise
176
+               (t
164 177
                 (if (find-restart 'fix-pathname)
165 178
                     (fix-pathname)
166
-                    (progn (unless (eq restart 'continue)
167
-                             (format t "~&Skipping a feed... ~s~%"
168
-                                     (if wc-p
169
-                                         (alimenta.feed-archive.encoders:the-feed c)
170
-                                         "Unknown")))
171
-                           (funcall restart)))))))
179
+                    (if (find-restart 'alimenta.pull-feed:skip-feed)
180
+                        (alimenta.pull-feed:skip-feed c)
181
+                        (progn
182
+                          (unless (eq restart 'continue)
183
+                            (format t "~&Skipping a feed... ~s~%"
184
+                                    (if wc-p
185
+                                        (alimenta.feed-archive.encoders:the-feed c)
186
+                                        "Unknown")))
187
+                          (funcall restart))))))))
172 188
 
173 189
     (let ((error-count 0))
174
-      (handler-bind ((alimenta.feed-archive.encoders:feed-error
175
-                      (op (fix-pathname-or-skip _1 :wrapped-condition (alimenta.feed-archive.encoders:the-condition _1))))
176
-                     (alimenta:feed-type-unsupported #'feed-type-unsupported)
177
-                     ((or usocket:timeout-error usocket:ns-error cl+ssl:ssl-error-verify)
178
-                      (op (alimenta.pull-feed:skip-feed _)))
179
-                     
180
-                     (error
181
-                      (op
182
-                        (format t "~&Error signaled, ~a (count ~d)" _1 error-count)
183
-                        (incf error-count)
184
-                        (unless (< error-count 15)
185
-                          (format t " continuing~%")
186
-                          (fix-pathname-or-skip _1 :restart 'continue)))))
187
-        (multiple-value-bind (*feeds* *feed-base*) (funcall feed-list-initializer)
190
+      (handler-bind
191
+          ((alimenta.feed-archive.encoders:feed-error
192
+             (op (fix-pathname-or-skip
193
+                  _1 :wrapped-condition
194
+                  (alimenta.feed-archive.encoders:the-condition _1))))
195
+           (alimenta:feed-type-unsupported #'feed-type-unsupported)
196
+           ((or usocket:timeout-error usocket:ns-error cl+ssl:ssl-error-verify)
197
+             (op (alimenta.pull-feed:skip-feed _)))
198
+
199
+           (error
200
+             (op
201
+               (format t "~&Error signaled, ~a (count ~d)"
202
+                       _1 error-count)
203
+               (incf error-count)
204
+               (unless (< error-count 15)
205
+                 (format t " continuing~%")
206
+                 (fix-pathname-or-skip _1 :restart 'continue)))))
207
+        (multiple-value-bind (*feeds* *feed-base*)
208
+            (funcall feed-list-initializer)
188 209
           (alimenta.pull-feed:with-user-agent ("Feed Archiver v0.1b")
189 210
             (archive-feeds-nondeterm)))))))
190 211
 
... ...
@@ -208,11 +229,11 @@
208 229
                 (alexandria:hash-table-values ht2)))))
209 230
 
210 231
 (deftest feed-index ()
211
-    (should be hash-table=
212
-            (yason:parse
213
-             (with-output-to-string (s)
214
-               (feed-index s (local-time:encode-timestamp 0 0 0 0 1 1 1) '()))
215
-             :object-as :hash-table :json-arrays-as-vectors nil)
216
-            (alexandria:alist-hash-table
217
-             '(("pull-time" . "0001-01-01T00:00:00.000000-08:00")
218
-               ("feeds" . ())))))
232
+  (should be hash-table=
233
+          (yason:parse
234
+           (with-output-to-string (s)
235
+             (feed-index s (local-time:encode-timestamp 0 0 0 0 1 1 1) '()))
236
+           :object-as :hash-table :json-arrays-as-vectors nil)
237
+          (alexandria:alist-hash-table
238
+           '(("pull-time" . "0001-01-01T00:00:00.000000-08:00")
239
+             ("feeds" . ())))))
... ...
@@ -12,17 +12,18 @@
12 12
 
13 13
 (defun make-feed-index (pull-time references)
14 14
   (make-instance 'feed-index
15
-		 :pull-time pull-time
16
-		 :references (copy-seq references)))
15
+                 :pull-time pull-time
16
+                 :references (copy-seq references)))
17 17
 
18 18
 (defun make-feed-reference (url &rest feed-data &key title path)
19 19
   (declare (ignore title path))
20 20
   (apply #'make-instance 'feed-reference
21
-	 :url url feed-data))
21
+         :url url
22
+         feed-data))
22 23
 
23 24
 (defmethod yason:encode-slots progn ((object feed-reference))
24 25
   (let ((title (title object))
25
-	(path (path object)))
26
+        (path (path object)))
26 27
     (yason:encode-object-element "url" (url object))
27 28
     (when title
28 29
       (yason:encode-object-element "title" title))
... ...
@@ -34,4 +35,4 @@
34 35
     (yason:encode-object-element "pull-time" (local-time:format-timestring nil pull-time))
35 36
     (yason:with-object-element ("feeds")
36 37
       (yason:with-array ()
37
-	(mapcar 'yason:encode-object references)))))
38
+        (mapcar 'yason:encode-object references)))))
... ...
@@ -43,8 +43,7 @@
43 43
   (concatenate 'string
44 44
 	       (local-time:format-timestring nil (alimenta:date item))
45 45
 	       "-"
46
-	       (sha256-string (alimenta:id item))
47
-	       #+nil ".json"))
46
+	       (sha256-string (alimenta:id item))))
48 47
 
49 48
 (defun older-than-a-month (date)
50 49
   (let ((month-ago (local-time:timestamp- (local-time:now)