;;; 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))))))