2007/12/10 に Remember The Milk から howm へインポートするためのコードを書きましたが、換骨奪胎により Trac のチケットの RSS フィードから howm へインポートするプログラムになりました。
基本的なアイディアは前回と同じですが、
という点が異なっていました。
出力例:
= [sample] #15: example <http://example.com/trac/sample/ticket/15> = [sample] #16: メモリリークを直す <http://example.com/trac/sample/ticket/16> = [sample] #20: 設定を変更する <http://example.com/trac/sample/ticket/20> = [sample] #21: test1 <http://example.com/trac/sample/ticket/21> = [sample] #23: test2 <http://example.com/trac/sample/ticket/23> = [sample] #25: test3 <http://example.com/trac/sample/ticket/25> ...
XML を howm の書式に変換するプログラム:
#!/usr/bin/env gosh
(use gauche.charconv)
(use srfi-1)
(use sxml.ssax)
(use sxml.sxpath)
(define *trac-output-encoding* "EUC-JP")
(define *trac-namespace* '())
(define entry->title (compose second fourth))
(define entry->link (compose second second))
(define (entry->memo project entry oport)
(define (f str . params)
(apply format oport (string-append str "\n") params))
(let ((title (entry->title entry))
(link (entry->link entry)))
(f "= [~a] ~a <~a>" project title link)
))
(define (xml->howm iport oport project)
(let* ((proc (sxpath '(// item)))
(tree (ssax:xml->sxml iport *trac-namespace*))
(entries (proc tree)))
(for-each (cut entry->memo project <> oport) entries)
))
(define (main args)
(call-with-input-conversion (current-input-port)
(lambda (iport)
(call-with-output-conversion (current-output-port)
(lambda (oport)
(xml->howm iport oport (cadr args)))
:encoding *trac-output-encoding*))
:encoding "*JP")
0)
Emacs でのコマンドの定義:
(require 'w3m)
(defvar trac-url-prefix "http://example.com/trac/")
(defvar trac-login-url-suffix "/login")
(defvar trac-feed-url-suffix "/query")
(defvar trac-feed-query-parameter '((status . new) (status . assigned) (status . reopened) (format . rss) (order . priority)))
(defun trac-login-url (project)
"URL for trac's login."
(concat trac-url-prefix project trac-login-url-suffix))
(defun trac-feed-url (project)
"URL for trac's RSS feed."
(concat trac-url-prefix
project
trac-feed-url-suffix
"?"
(mapconcat (lambda (pair) (concat (symbol-name (car pair)) "=" (symbol-name (cdr pair)))) trac-feed-query-parameter "&")
))
(defvar trac-feed-content-type "application/rss+xml")
(defvar trac-temporary-file-prefix "/tmp/trac")
(defvar trac-convert-program "/home/tabe/bin/trac2howm.scm")
(defun trac-retrieve (project)
(interactive "sProject: ")
(catch 'failed
(let ((use-cookies w3m-use-cookies)
(temp-file (make-temp-file trac-temporary-file-prefix)))
(unwind-protect
(progn
(setq w3m-use-cookies t)
(with-temp-buffer
(w3m-retrieve (w3m-retrieve (trac-login-url project))))
(set-file-modes temp-file ?\600)
(with-temp-file temp-file
(let ((content-type (w3m-retrieve (trac-feed-url project) nil t)))
(unless (equal trac-feed-content-type content-type)
(throw 'failed (message "failed. (%s)" (or content-type "nil"))))
)
)
(call-process trac-convert-program temp-file t t project))
(delete-file temp-file)
(setq w3m-use-cookies use-cookies)
))))
動かすには: