;;; -*- Mode: Lisp -*- (defpackage :blitzblog.import (:use "CL" "BLITZBLOG.CONFIG" "BLITZBLOG.DB" "ITERATE" "CL-PPCRE") (:export "IMPORT-FILE")) (in-package :blitzblog.import) (defparameter *header-scanner* (create-scanner "^(\\w+): (.*)$" )) (defun parse-header (stream) (iter (for line = (read-line stream)) (until (string= "--" (string-right-trim " " line))) (multiple-value-bind (success? matches) (scan-to-strings *header-scanner* line) (if success? (collect (cons (aref matches 0) (aref matches 1))) (error 'parse-error))))) (defun read-to-eof (stream) (with-output-to-string (out) (iter (with buf = (make-string 1024)) (for chars = (read-sequence buf stream)) (write-sequence buf out :end chars) (while (= chars 1024))))) (defun import-file (file) (with-open-file (in file) (let ((header-alist (parse-header in))) (flet ((str-assoc (key) (cdr (assoc key header-alist :test #'string=)))) (values (str-assoc "Title") (split-sequence:split-sequence #\Space (str-assoc "Categories")) (read-to-eof in) (or (not (str-assoc "Status")) (string-equal (str-assoc "Status") "Ready")) (and (str-assoc "Id") (parse-integer (str-assoc "Id")))))))) ;;; EOF