2008/04/30

Muse で書いて Blogger にポストするプログラム

sak さんがコメントをくれたのでドキュメントを書きました。sak さんきっかけありがとうございます。

概要

とにかく Emacs から Blogger に投稿したかった。どうせなら Muse で書きたかった。simple-hatena-mode とかうらやましかった。というわけで作ってみたものです。

できること。

  • 新規投稿
  • 投稿したものの修正

めんどうなところ

  • Slime 経由なので M-x slime とか事前にしておく必要がある。
  • 新規投稿後、元ファイルの末尾に post-id をくっつけるので、Emacs 上で再読み込みする必要がある。
  • カテゴリにはまだ対応してない。
  • Web 上で編集したものとローカルの Muse ファイルの同期はとれない。Muse -> Web の一方通行。
  • slime の repl バッファを見てないと、投稿が完了したかどうか分からない;)

必要なもの

Drakma等は asdf-install を使って次のようにインストールするのが簡単だと思います。他には clbuild を使う方法もあります。

CL-USER> (require :asdf-install)
("ASDF-INSTALL")
CL-USER> (asdf-install:install :drakma)
Install where?
1) System-wide install:
System in /usr/lib/sbcl/site-systems/
Files in /usr/lib/sbcl/site/
2) Personal installation:
System in /home/ancient/.sbcl/systems/
Files in /home/ancient/.sbcl/site/
--> 2

ここで 2 を入力してください。

No key found for key id 0x#1=595FF045057958C6.  Try some command like
gpg --recv-keys 0x#1#
[Condition of type ASDF-INSTALL::KEY-NOT-FOUND]

Restarts:
0: [SKIP-GPG-CHECK] Don't check GPG signature for this package
1: [ABORT] Return to SLIME's top level.
2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" {10034FE621}>)

みたいなのが表示されたら 0 を入力してください。あと同様に cl-ppcre 等をインストールしてください。

(asdf-install:install :cl-ppcre)
(asdf-install:install :s-xml)

インストール

取得

最新バージョンを Subversion で取得します。dot.blogger.lisp を ~/.blogger.lisp にコピーします。

$ mkdir ~/lisp
$ cd ~/lisp
$ svn checkout http://cl-blogger.googlecode.com/svn/trunk/ blogger
$ cd blogger
$ cp dot.blogger.lisp ~/.blogger.lisp

~/.blogger.lisp の編集

~/.blogger.lisp を編集します。

設定内容は次のとおりです。

*author*
投稿ユーザ名
*email*
投稿ユーザ email
*passwd*
Blogger のパスワード
*blog-id*
ブログID

ブログIDは Blogger のソースを表示すると次のような個所があると思いますので、"blogId=" の後のものを指定してください。

<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://www.blogger.com/rsd.g?blogID=1096313046657120208" />

asdf:*central-registry* への追加

~/.sbclrc 等で asdf:*central-registry* に blogger.asdのあるディレクトリを追加してください。

(pushnew (merge-pathnames #p"lisp/blogger/" (user-homedir-pathname))
asdf:*central-registry*
:test #'equal)

~/.emacs の編集

~/.emacs に次の2行を追加してください。

(setq load-path (cons (expand-file-name "~/lisp/blogger") load-path))
(autoload 'blogger-post "blogger" "Blogger Post" t)

使い方

まず M-x slime 等で Slime を起動しておいてください。

Muse の書式で投稿内容を編集してください。

1行目は "#title" で始めてください。投稿の際にタイトルとして使います。

; labels: で始まる行にコンマ区切りでラベルを指定することができます。

#title 題名

投稿内容。。。
; labels: ブログ, Common Lisp
↑ ; labels: は行頭に記述してください。;の前にスペースは入れないでください。(Muse で example タグの中に "; " で始まる行を書くにはどうすればいいんだろう?)

M-x blogger-post で投稿します。

投稿後には Muse ファイルの末尾にポストIDを追加しますので、投稿後に再編集する場合はC-x C-v などで Muse ファイルを再読込してください。

末尾のポストIDを保持するために次のような行が付加されます。

 ; post-id 3534792244000900117

上記のようなポストIDの行があると M-x blogger-post は既存エントリの置き換えになります。

5 件のコメント:

匿名 さんのコメント...

ドキュメントありがとうございます。

検索でいきなりこちらへおじゃましましたので、Common Lispなどの前堤知識がなくてすみません。

依存ライブラリで、drakma以降のものの取得方法がわかりません。URLリンクがあると助かります。

Yoshinori Tahara さんのコメント...

sak さんご意見ありがとうございます♪
「おまえの説明は分かりにくい」とよく言われるので、いろいろつっこんでもらえると嬉しいです。

http://read-eval-print.blogspot.com/2008/05/common-lisp-asdf-install-drakma.html にちょっと書いてみまみした。

あと README にも同じ内容を記述したので git pull で最新版を取得してみてください。

匿名 さんのコメント...

こんにちは.

READMEに従ってインストール後,投稿テスト(blogger-post)を試みましたが,デバッガへ飛び込んでいるようです.

実際blogger.comには投稿されておりません.なにかわかりますでしょうか?

バッファ:*sldb sbcl/1* の内容:

The class SB-PRETTY:PRETTY-STREAM was not changed, and there's no guarantee that
the loaded code (which expected another layout) will work.
[Condition of type SIMPLE-ERROR]

Restarts:
0: [RETRY] Retry performing #%lt;ASDF:LOAD-OP NIL {B9CAA81}> on #%lt;ASDF:CL-SOURCE-FILE "api" {AD1D0B1}>.
1: [ACCEPT] Continue, treating #%lt;ASDF:LOAD-OP NIL {B9CAA81}> on #%lt;ASDF:CL-SOURCE-FILE "api" {AD1D0B1}> as having been successful.
2: [ABORT] Return to SLIME's top level.
3: [TERMINATE-THREAD] Terminate this thread (#%lt;THREAD "worker" {AF6A731}>)

Backtrace:
0: (SB-KERNEL::CHECK-LAYOUT #%lt;SB-KERNEL:LAYOUT for SB-PRETTY:PRETTY-STREAM {950DCC1}> #%lt;SB-KERNEL:STRUCTURE-CLASSOID SB-PRETTY:PRETTY-STREAM> 25 #(#%lt;SB-KERNEL:LAYOUT for T {905F621}> #%lt;SB-KERNEL:LAYOUT for STRUCTURE-OBJECT {905F659}> #%lt;SB-KERNEL:LAYOUT for STREAM {91A51C1}> #%lt;SB-KERNEL:LAYOUT for SB-KERNEL:ANSI-STREAM {905FB69}>) 4 0)
1: (SB-KERNEL::INIT-OR-CHECK-LAYOUT #%lt;SB-KERNEL:LAYOUT for SB-PRETTY:PRETTY-STREAM {950DCC1}> #%lt;SB-KERNEL:STRUCTURE-CLASSOID SB-PRETTY:PRETTY-STREAM> 25 #(#%lt;SB-KERNEL:LAYOUT for T {905F621}> #%lt;SB-KERNEL:LAYOUT for STRUCTURE-OBJECT {905F659}> #%lt;SB-KERNEL:LAYOUT for STREAM {91A51C1}> #%lt;SB-KERNEL:LAYOUT for SB-KERNEL:ANSI-STREAM {905FB69}>) 4 0)
2: (SB-FASL::FOP-LAYOUT)
3: (SB-FASL::LOAD-FASL-GROUP #%lt;SB-SYS:FD-STREAM for "file /var/cache/common-lisp-controller/1000/sbcl/local/home/ryo/.sbcl/site/cl-ppcre-1.3.2/api.fasl" {AAC5B41}>)
4: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK))
5: ((FLET #:WITHOUT-INTERRUPTS-BODY-[CALL-WITH-RECURSIVE-LOCK]520))
6: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #%lt;CLOSURE (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK) {F73AF39D}> #S(SB-THREAD:MUTEX :NAME "big compiler lock" :%OWNER #%lt;SB-THREAD:THREAD "worker" {AF6A731}> :STATE 1))
7: (SB-FASL::LOAD-AS-FASL #%lt;SB-SYS:FD-STREAM for "file /var/cache/common-lisp-controller/1000/sbcl/local/home/ryo/.sbcl/site/cl-ppcre-1.3.2/api.fasl" {AAC5B41}> NIL #%lt;unavailable argument>)
8: (SB-FASL::%LOAD #%lt;SB-SYS:FD-STREAM for "file /var/cache/common-lisp-controller/1000/sbcl/local/home/ryo/.sbcl/site/cl-ppcre-1.3.2/api.fasl" {AAC5B41}>)[:EXTERNAL]
9: (SB-FASL::%LOAD #P"/var/cache/common-lisp-controller/1000/sbcl/local/home/ryo/.sbcl/site/cl-ppcre-1.3.2/api.fasl")[:EXTERNAL]
10: (LOAD #P"/var/cache/common-lisp-controller/1000/sbcl/local/home/ryo/.sbcl/site/cl-ppcre-1.3.2/api.fasl")[:EXTERNAL]
11: ((SB-PCL::FAST-METHOD ASDF:PERFORM (ASDF:LOAD-OP ASDF:CL-SOURCE-FILE)) #%lt;unavailable argument> #%lt;unavailable argument> #%lt;ASDF:LOAD-OP NIL {B9CAA81}> #%lt;ASDF:CL-SOURCE-FILE "api" {AD1D0B1}>)
12: ((LAMBDA (SB-PCL::.PV. SB-PCL::.NEXT-METHOD-CALL. SB-PCL::.ARG0. SB-PCL::.ARG1.)) #%lt;unavailable argument> #%lt;unavailable argument> #%lt;ASDF:LOAD-OP NIL {B9CAA81}> #%lt;ASDF:CL-SOURCE-FILE "api" {AD1D0B1}>)
13: ((LAMBDA NIL))
14: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK))
15: ((FLET #:WITHOUT-INTERRUPTS-BODY-[CALL-WITH-RECURSIVE-LOCK]520))
16: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #%lt;CLOSURE (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK) {F73AF9FD}> #S(SB-THREAD:MUTEX :NAME "big compiler lock" :%OWNER #%lt;SB-THREAD:THREAD "worker" {AF6A731}> :STATE 1))
17: (SB-C::%WITH-COMPILATION-UNIT #%lt;CLOSURE (LAMBDA NIL) {AF40595}>)[:EXTERNAL]
18: (ASDF:OPERATE ASDF:LOAD-OP :BLOGGER)[:EXTERNAL]
19: (ASDF::MODULE-PROVIDE-ASDF :BLOGGER)
--more--

Yoshinori Tahara さんのコメント...

sak さんトライありがとうございます。

なぜか cl-ppcre のロードで失敗しているみたいですね。

このへんの URL を見るとどうやら Slime のバグでそのような現象が発生するそうです。
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=457648
http://common-lisp.net/pipermail/slime-devel/2008-March/007209.html

できれば、Slime の CVS 版を取得して試していただけませんでしょうか。
cvs -d :pserver:anonymous:anonymous@common-lisp.net:/project/slime/cvsroot co slime

匿名 さんのコメント...

そうですか。

残念ながらCVS版による検証まで時間が割けません。リリースされましたらまた試したいと思います。

検索によるとblogger用のemacsパッケージは他にもあるようなので、そちらの線でも調べてみます。

commonLisp環境の勉強になりました。ありがとうございました。