| 1 | #!/bin/sh |
|---|
| 2 | #@63 |
|---|
| 3 | LANG=C exec /usr/bin/emacs -Q --batch --no-unibyte --kill -l $0 |
|---|
| 4 | ; set LANG for format-time-string |
|---|
| 5 | |
|---|
| 6 | (set-default-coding-systems 'utf-8) |
|---|
| 7 | (set-terminal-coding-system 'utf-8) |
|---|
| 8 | (set-buffer-file-coding-system 'utf-8) |
|---|
| 9 | (prefer-coding-system 'utf-8) |
|---|
| 10 | (set-keyboard-coding-system 'utf-8) |
|---|
| 11 | |
|---|
| 12 | (require 'cl) |
|---|
| 13 | |
|---|
| 14 | ; http://subtech.g.hatena.ne.jp/antipop/20071023/1193150099 |
|---|
| 15 | (defun apply-template (place flavour) |
|---|
| 16 | (setf file (concat place flavour)) |
|---|
| 17 | (save-current-buffer |
|---|
| 18 | (let ((buffer (get-buffer-create "*TemplateProcessing*"))) |
|---|
| 19 | (set-buffer buffer) |
|---|
| 20 | (erase-buffer) |
|---|
| 21 | (insert-file-contents file) |
|---|
| 22 | (while (re-search-forward "\\$\\([0-9a-zA-Z_-]+\\)" nil t) |
|---|
| 23 | (replace-match (symbol-value (intern (match-string 1))) nil nil)) |
|---|
| 24 | (prog1 (buffer-string) |
|---|
| 25 | (kill-buffer nil))))) |
|---|
| 26 | |
|---|
| 27 | (defun replace (str match-str replace-str) |
|---|
| 28 | (save-current-buffer |
|---|
| 29 | (let ((buffer (get-buffer-create "*ReplaceString*"))) |
|---|
| 30 | (set-buffer buffer) |
|---|
| 31 | (erase-buffer) |
|---|
| 32 | (insert str) |
|---|
| 33 | (goto-char (point-min)) |
|---|
| 34 | (while (re-search-forward match-str nil t) |
|---|
| 35 | (replace-match replace-str nil nil)) |
|---|
| 36 | (prog1 (buffer-string) |
|---|
| 37 | (kill-buffer nil))))) |
|---|
| 38 | |
|---|
| 39 | (defun split-entry-body (file) |
|---|
| 40 | (save-current-buffer |
|---|
| 41 | (let ((buffer (get-buffer-create "*TempEntry*"))) |
|---|
| 42 | (set-buffer buffer) |
|---|
| 43 | (erase-buffer) |
|---|
| 44 | (insert-file-contents file) |
|---|
| 45 | (goto-char (point-min)) |
|---|
| 46 | (kill-line) |
|---|
| 47 | (setf title (car kill-ring)) |
|---|
| 48 | (setf body (buffer-string)) |
|---|
| 49 | (prog1 (values title body) |
|---|
| 50 | (setf kill-ring '()) |
|---|
| 51 | (kill-buffer nil))))) |
|---|
| 52 | |
|---|
| 53 | (defun list-entries (dir base) |
|---|
| 54 | (setf base (expand-file-name base)) |
|---|
| 55 | (let ((ret '())) |
|---|
| 56 | (loop for f in (directory-files dir t) do |
|---|
| 57 | (let* ((attr (file-attributes f)) |
|---|
| 58 | (dir? (eq (car attr) t)) |
|---|
| 59 | (file? (null (car attr))) |
|---|
| 60 | (mtime (nth 5 attr))) |
|---|
| 61 | ;(print (list f dir? file?)) |
|---|
| 62 | (if (null (string-match "\\(\\.\\|\\.\\.\\)$" f)) |
|---|
| 63 | (progn |
|---|
| 64 | (if dir? (setf ret (append ret (list-entries f base)))) |
|---|
| 65 | (if file? (setf ret (append ret (list |
|---|
| 66 | `((path . ,f) |
|---|
| 67 | (name . ,(replace f (concat (regexp-quote base) "\\|\\..+$") "")) |
|---|
| 68 | (time . ,mtime)) |
|---|
| 69 | ))))) |
|---|
| 70 | ) |
|---|
| 71 | ) |
|---|
| 72 | ) |
|---|
| 73 | ret) |
|---|
| 74 | ) |
|---|
| 75 | |
|---|
| 76 | (defun matches (regexp str) |
|---|
| 77 | (if (string-match regexp str) |
|---|
| 78 | (progn |
|---|
| 79 | (setf m (match-data)) |
|---|
| 80 | (loop for x below 10 |
|---|
| 81 | if (match-beginning x) |
|---|
| 82 | collect |
|---|
| 83 | (substring str (match-beginning x) (match-end x)) |
|---|
| 84 | )) |
|---|
| 85 | nil |
|---|
| 86 | )) |
|---|
| 87 | |
|---|
| 88 | (setf title "blosxom.el !") |
|---|
| 89 | (setf author "Joe") |
|---|
| 90 | |
|---|
| 91 | (setf servername (concat "http://" (or (getenv "SERVER_NAME") ""))) |
|---|
| 92 | (setf home (or (getenv "SCRIPT_NAME") "")) |
|---|
| 93 | (setf pathinfo (or (getenv "PATH_INFO") "")) |
|---|
| 94 | (setf pathname (replace pathinfo "\\(index\\)?\\..+$" "")) |
|---|
| 95 | (setf version (emacs-version)) |
|---|
| 96 | |
|---|
| 97 | (setf flavour (or (nth 1 (matches "\\(\\..+\\)$" pathinfo)) ".html")) |
|---|
| 98 | (setf splitted-pathinfo (matches "^/\\([0-9]+\\)\\(/[0-9][0-9]\\)?\\(/[0-9][0-9]\\)?" pathinfo)) |
|---|
| 99 | ;(print system-configuration) |
|---|
| 100 | ;(print system-name) |
|---|
| 101 | |
|---|
| 102 | ;(print (getenv "PATH_INFO")) |
|---|
| 103 | ;(print invocation-name) |
|---|
| 104 | ;(print process-environment) |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | (setf entries (list-entries "data" "data")) |
|---|
| 108 | |
|---|
| 109 | ; sort by mtime |
|---|
| 110 | (sort entries '(lambda (a b) |
|---|
| 111 | (setf timea (cdr (assoc 'time a))) |
|---|
| 112 | (setf timeb (cdr (assoc 'time b))) |
|---|
| 113 | |
|---|
| 114 | ; どうすればいいだろう…… |
|---|
| 115 | (< (+ (* 65535 (car timea)) (cadr timea)) |
|---|
| 116 | (+ (* 65535 (car timeb)) (cadr timeb)) |
|---|
| 117 | ) |
|---|
| 118 | )) |
|---|
| 119 | |
|---|
| 120 | ; filter |
|---|
| 121 | (setf entries (loop for e in entries |
|---|
| 122 | if (progn |
|---|
| 123 | (setf name (cdr (assoc 'name e))) |
|---|
| 124 | (setf time (cdr (assoc 'time e))) |
|---|
| 125 | ; (string= "2007" (format-time-string "%Y" time)) |
|---|
| 126 | (cond ((nth 3 splitted-pathinfo) |
|---|
| 127 | (string= (format-time-string "%Y/%m/%d" time) (apply 'concat (cdr splitted-pathinfo))) |
|---|
| 128 | ) |
|---|
| 129 | ((nth 2 splitted-pathinfo) |
|---|
| 130 | (string= (format-time-string "%Y/%m" time) (apply 'concat (cdr splitted-pathinfo))) |
|---|
| 131 | ) |
|---|
| 132 | ((nth 1 splitted-pathinfo) |
|---|
| 133 | (string= (format-time-string "%Y" time) (nth 1 splitted-pathinfo)) |
|---|
| 134 | ) |
|---|
| 135 | (t |
|---|
| 136 | (string-match (concat "^" pathname) name) |
|---|
| 137 | )) |
|---|
| 138 | ) |
|---|
| 139 | collect e)) |
|---|
| 140 | |
|---|
| 141 | (setf entries (last entries 7)) |
|---|
| 142 | (setf entries (nreverse entries)) |
|---|
| 143 | |
|---|
| 144 | (setf lastupdate (format-time-string "%Y-%m-%dT%H:%M:%SZ" (cdr (assoc 'time (car entries))))) |
|---|
| 145 | |
|---|
| 146 | (princ (concat "Content-Type: " (apply-template "content_type" flavour) "\n")) |
|---|
| 147 | (princ (apply-template "head" flavour)) |
|---|
| 148 | |
|---|
| 149 | (loop for e in entries do |
|---|
| 150 | (multiple-value-bind (title body) (split-entry-body (cdr (assoc 'path e)))) |
|---|
| 151 | (setf name (cdr (assoc 'name e))) |
|---|
| 152 | (setf path (cdr (assoc 'name e))) |
|---|
| 153 | (setf time (cdr (assoc 'time e))) |
|---|
| 154 | (setf w3cdtf (format-time-string "%Y-%m-%dT%H:%M:%SZ" time)) |
|---|
| 155 | (setf yr (format-time-string "%Y" time)) |
|---|
| 156 | (setf mo (format-time-string "%b" time)) |
|---|
| 157 | (setf mo_num (format-time-string "%m" time)) |
|---|
| 158 | (setf da (format-time-string "%d" time)) |
|---|
| 159 | (setf dw (format-time-string "%a" time)) |
|---|
| 160 | (setf hr (format-time-string "%H" time)) |
|---|
| 161 | (setf min (format-time-string "%M" time)) |
|---|
| 162 | (setf hr12 (format-time-string "%I" time)) |
|---|
| 163 | (setf ampm (format-time-string "%p" time)) |
|---|
| 164 | (setf ti (format-time-string "%X" time)) |
|---|
| 165 | (princ (apply-template "story" flavour)) |
|---|
| 166 | ) |
|---|
| 167 | ;(print entries) |
|---|
| 168 | |
|---|
| 169 | (princ (apply-template "foot" flavour)) |
|---|
| 170 | |
|---|
| 171 | |
|---|