git.fiddlerwoaroof.com
tools.lisp
79f9884d
 (in-package :alimenta.feed-archive.tools)
 
 (defgeneric store (item directory)
   (:documentation "Store an item in a directory"))
 
 (defmacro -> (&rest forms)
   (let ((forms (mapcar (lambda (form)
 			 (typecase form
 			   (list form)
 			   (t (list form))))
 		       forms)))
     (loop with result = (car forms)
        for form in (cdr forms)
        do
 	 (setf result `(,(car form)
 			 ,result
 			 ,@(cdr form)))
        finally
 	 (return result))))
 
 (defun fix-pathname ()
   (let ((restart (find-restart 'fix-pathname)))
     (when restart
       (invoke-restart restart))))
 
 (defun sha256-string (string)
   (let* ((digester (ironclad:make-digesting-stream :sha256))
 	 (digest-stream (flexi-streams:make-flexi-stream digester)))
     (princ string digest-stream)
     (crypto:byte-array-to-hex-string
      (crypto:produce-digest
       digester))))
 
 (defgeneric get-id (feed)
   (:documentation "Get an identifier for a feed"))
 
 (defmethod get-id ((feed alimenta:feed))
   (let* ((link (alimenta:feed-link feed))
 	 (host (puri:uri-host link)))
     (concat host "-" (sha256-string link) "/")))
 
 (defmethod get-id ((item alimenta:item))
   (concatenate 'string
 	       (local-time:format-timestring nil (alimenta:date item))
 	       "-"
e3a39cd6
 	       (sha256-string (alimenta:id item))))
79f9884d
 
36fc9de2
 (defun older-than-a-month (date)
   (let ((month-ago (local-time:timestamp- (local-time:now)
 					  31 :day)))
1d8d7dc5
     (if date
         (local-time:timestamp< date month-ago)
         t)))
36fc9de2
 
79f9884d
 (defun older-than-a-week (date)
   (let ((week-ago (local-time:timestamp- (local-time:now)
                                          7 :day)))
     (local-time:timestamp< date week-ago)))
 
f7e44666
 (defmacro restart-once ((restart-name (&rest restart-args) &body handler) &body body)
   "Defines a restart that, the first time it's executed, runs a chunk of code and then,
 next time, it re-raises the exception."
   (with-gensyms (start restarted)
     `(let ((,restarted nil))
        (tagbody ,start
b4966c2f
 	        (restart-case
 	            (progn ,@body)
 	          (,restart-name ,restart-args
 	            ,@handler
 	            (unless ,restarted
 		            (setf ,restarted t)
 		            (go ,start))))))))
f7e44666
 
0010b953
 
e8084c22
 (defun relative-uri-p (uri)
4efcb0a6
   (let ((uri (fw.lu:may (puri:uri uri))))
     (and uri
          (not
           (and (puri:uri-scheme uri)
                (puri:uri-host uri)
                t)))))
e8084c22
 
0010b953
 (defun coerce-feed-link (link feed)
e8084c22
   (flet ((unrelativize (url)
            (puri:render-uri (puri:merge-uris url
                                              link)
                             nil)))
     (prog1 feed
       (unless (and (alimenta:feed-link feed)
                    (not (relative-uri-p (alimenta:feed-link feed))))
         (setf (alimenta:feed-link feed)
               (if (alimenta:feed-link feed)
                   (unrelativize (alimenta:feed-link feed))
                   link)))
       (when (relative-uri-p (alimenta:link feed))
         (setf (alimenta:link feed)
               (unrelativize (alimenta:link feed)))))))
0010b953
 
 (defmacro with-retry ((&optional (message "retry the operation")) &body body)
   `(loop
b4966c2f
      (restart-case (return (progn ,@body))
 	     (retry ()
 	       :report (lambda (s)
 		               (format s "~@<~a~@:>" ,message))))))