;;; filefeed.lisp -- Generate news feed from files in file system subtree ;;; 2010/7/20 David Meyer <papa@freeshell.org> +JMJ ;;; ;;; To-do: ;;; 1. list files in subtree ;;; 2. filter files based on name (extension, ...) ;;; 3. lookup file update times, save in plist ;;; 4. sort files by update time ;;; 5. select files for feed (most recently updated n files) ;;; 6. extract article title and other info. from files ;;; 7. format file info. and output feed data ;;; ;; Configuration variables ... (setf *data-path* (pathname "~/cave/green/")) (setf *feed-items* 40) (setf *item-types* '("txt" "html" "htm" "shtml")) (defvar *db* '()) (defun all-files () (directory (merge-pathnames (make-pathname :directory '(:relative "**") :name "*") *data-path*))) (defun select-by-type (file-paths) (remove-if-not #'(lambda (pathname) (member-if #'(lambda (s) (string= s (string-downcase (pathname-type pathname)))) *item-types*)) file-paths)) (defun path-time-plist (pathnames) (let (plist '()) (dolist (p pathnames plist) (push (list :pathname p :write-time (file-write-date p)) plist)))) (defun feed-items (plists) (subseq (sort plists (lambda (a b) (> (getf a :write-time) (getf b :write-time)))) 0 *feed-items*)) (defun complete-props (plists) (dolist (record plists plists) (let ((pathname (getf record :pathname)) (write-time (getf record :write-time))) (nconc record (list :id (entry-id pathname) :updated (entry-updated write-time) :category (entry-category pathname)) (file-content-props pathname))))) (defun file-content-props (pathname) (let ((title "") (content "")) (with-open-file (in-file pathname) (if (string= (pathname-type pathname) "txt") (progn (if (string= title "") (setf title (read-line in-file nil)) (setf content (nconc content (read-line in-file nil))))))) (list :title title :content content))) (defun entry-id (pathname) "test-id") (defun entry-updated (write-time) "test-updated") (defun entry-category (pathname) "test-category") (defun test-driver () (complete-props (feed-items (path-time-plist (select-by-type (all-files))))))