2008/10/27


以前、「はてなブックマークをPlaggerで同期する際の注意点」という記事で書いたXML::Feed::Atomが複数のsubjectを返せない件で、送ったパッチが取り込まれました。厳密にはちょっと変えられてますが。
はてなブックマークのRSSフィードにはblockquote引用文が含まれており、Atomを使った方が良いという記事でしたが難点としてPlaggerで使用しているXML::Feed::Atomには複数のsubjectつまりタグを返せる仕組みがなかった為、別のソーシャルブックマークへポストした際にタグが削られてしまう事になっていました。
簡単な例で言うと use strict;
use warnings;
use XML::Feed;
my $feed = XML::Feed->parse(URI->new('http://b.hatena.ne.jp/mattn/atomfeed'))
    or die XML::Feed->errstr;
for my $entry ($feed->entries) {
  print $entry->link."\n";
  print "[$_]" for $entry->category;
  print $entry->summary->{body};
  print "\n";
}
というコードに対して、以前までのXML::Feed::Atomだと http://b.hatena.ne.jp/mattn/20081024#bookmark-10541285
[coderepos]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10541123
[coderepos]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10538485
[wsgi]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10534904
[googleappengine]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10531400
[]てかRSS意識しすぎw そんなに気になるか。
http://b.hatena.ne.jp/mattn/20081024#bookmark-7152814
[webfont]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10530774
[vimperator]Include this patch f*ck でok
http://b.hatena.ne.jp/mattn/20081023#bookmark-10527748
[perl]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10529111
[chrome]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10522215
[catalyst]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10520297
[dojo]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10516769
[igoogle]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10513534
[ruby]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512893
[merb]merbでscaffold
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512804
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512802
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-9671938
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512759
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-9696628
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512388
[perl]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10498444
[lighttpd]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10504059
[]prototype.jsかぁ…。
http://b.hatena.ne.jp/mattn/20081022#bookmark-10502783
[]
http://b.hatena.ne.jp/mattn/20081021#bookmark-10489204
[vimperator]rcが先す
http://b.hatena.ne.jp/mattn/20081021#bookmark-10488856
[softbank]
http://b.hatena.ne.jp/mattn/20081021#bookmark-10484808
[blosxom]
http://b.hatena.ne.jp/mattn/20081021#bookmark-10488095
[]
http://b.hatena.ne.jp/mattn/20081020#bookmark-7686515
[テスト]TeSt
http://b.hatena.ne.jp/mattn/20081019#bookmark-10465795
[]
http://b.hatena.ne.jp/mattn/20081019#bookmark-10460236
[perl]
こんな形にタグが1つ以上出力されず、しかも空の配列として得られたりしていましたが、XML::Feed 0.22以降だと http://b.hatena.ne.jp/mattn/20081024#bookmark-10541285
[coderepos][oops]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10541123
[coderepos]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10538485
[wsgi]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10534904
[googleappengine][appengine]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10531400
てかRSS意識しすぎw そんなに気になるか。
http://b.hatena.ne.jp/mattn/20081024#bookmark-7152814
[webfont]
http://b.hatena.ne.jp/mattn/20081024#bookmark-10530774
[vimperator]Include this patch f*ck でok
http://b.hatena.ne.jp/mattn/20081023#bookmark-10527748
[perl]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10529111
[chrome]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10522215
[catalyst]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10520297
[dojo]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10516769
[igoogle][google]
http://b.hatena.ne.jp/mattn/20081023#bookmark-10513534
[ruby][rails]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512893
[merb]merbでscaffold
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512804
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512802
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-9671938
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512759
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-9696628
[merb]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10512388
[perl][twitter][wassr]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10498444
[lighttpd]
http://b.hatena.ne.jp/mattn/20081022#bookmark-10504059
prototype.jsかぁ…。
http://b.hatena.ne.jp/mattn/20081022#bookmark-10502783

http://b.hatena.ne.jp/mattn/20081021#bookmark-10489204
[vimperator]rcが先す
http://b.hatena.ne.jp/mattn/20081021#bookmark-10488856
[softbank]
http://b.hatena.ne.jp/mattn/20081021#bookmark-10484808
[blosxom]
http://b.hatena.ne.jp/mattn/20081021#bookmark-10488095

http://b.hatena.ne.jp/mattn/20081020#bookmark-7686515
[テスト]TeSt
http://b.hatena.ne.jp/mattn/20081019#bookmark-10465795

http://b.hatena.ne.jp/mattn/20081019#bookmark-10460236
[perl]
こんな感じの出力になります。 今回の修正により手放しで、はてなブックマークAtomフィードをdelicios等にポスト出来る様になります。

めでたしめでたし
Posted at by



2008/10/15


基本部はこちらを参照。
ニコニコ動画のサムネイル画像を取得する Perl スクリプト - Yet Another Hackadelic
http://d.hatena.ne.jp/ZIGOROu/20081014/1223991205
思いっきり個人用ぽいスクリプトになってしまいました...。
Plaggerでアレを適当なフォルダにガサーーーと落として、そのフォルダ上で走らせる。 ガサーーーのレシピはこんな感じ。
plugins:
  - module: Subscription::Config
    config:
      feed:
         - http://www.nicovideo.jp/mylist/7688389

  - module: Filter::FetchNicoVideo
    config:
      mail: xxxxx@example.com
      password: your-password
      dir: /path/to/download/
      download_comment: 1
      id_as_filename: 0
      # for windows
      #filename_encode: shift-jis
スクリプトはガサーーーの中に含まれるXMLをパースしてゴニョゴニョしている。
#!/usr/bin/perl

use strict;
use warnings;

use Encode;
use Template;
use XML::Simple;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new( keep_alive => 4 );
my $xs = XML::Simple->new;

sub save {
    my ($content, $filename) = @_;
    open my $fh, '>', $filename;
    binmode $fh;
    print $fh $content;
    close $fh;
}

sub build {
    my $file = $_;

    # 動画IDと、ソートに用いるサーバ時刻を取得する
    my $ref = $xs->XMLin($file);
    my $video_id = substr($ref->{view_counter}->{id}, 2);
    my $time = $ref->{thread}->{server_time};

    # 動画ファイル名を得る(s/xml/flv/)
    $file =~ s/\.xml$//;
    $file = decode('cp932', $file) if $^O eq 'MSWin32';
    my $movie_file = "$file.flv";

    # ref: http://d.hatena.ne.jp/ZIGOROu/20081014/1223991205
    my $server_id = $video_id % 2 + 1;
    my $thumb_url = "http://tn-skr$server_id.smilevideo.jp/smile?i=$video_id";
    my $thumb_file = "sm$video_id.jpg";
    my $video_url = "http://www.nicovideo.jp/watch/sm$video_id";

    # サムネイルをダウンロード
    unless (-e $thumb_file) {
        my $res = $ua->get($thumb_url);
        &save($res->content, $thumb_file);
    }

    # " - "でファイル名を分割して先頭を題名に、
    my @info = split(/ - /, $file);
    return {
        title   => $info[0] || $file,
        speaker => $info[1] || $file,
        thumb   => $thumb_file,
        file    => $movie_file,
        time    => $time,
        url     => $video_url,
    };
}

# XMLファイル一覧から動画情報を組み立て、サーバ時刻でソートする
my @movies = sort {$a->{time} <=> $b->{time}}
    map(build($_), glob('*.xml'));

# Templateを使用してHTML出力
binmode STDOUT, ':encoding(utf-8)';
my $tt = Template->new({ UNICODE => 1, ENCODING => 'utf-8' });
$tt->process(\*DATA, {movies => \@movies});

__DATA__
<html>
<head>
<title>第1回 Coderepos Con</title>
<style type="text/css">
body { font-family: meiryo; background-color: black; color: white }
a { color: #333399 }
.file { color: orange; }
.movie { font-size: 20px; font-weight: bold; padding: 0.5em; }
.movie img { margin-right: 0.5em; border: 1px solid blue; }
</style>
</head>
<body>
<h1>第1回 Coderepos Con</h1>
<hr />
<div id="content">
[% FOREACH movie IN movies %]
<div class="movie">
    <img src="[% movie.thumb %]" style="float:left;" />
    Name: <a class="file" href="[% movie.file %]">[% movie.title %]</a><br />
    Speaker: [% movie.speaker %]<br />
    URL: <a href="[% movie.url %]">[% movie.url %]</a><br />
    <br clear="all"/>
</div>
[% END %]
</div>
</body>
</html>
" - "でタイトルとか分けてる部分は、この動画ファイルの名づけ方に依存しているので使う人は好き勝手に変えて下さい。
ちなみに動かすとこんなHTMLが出来上がる。
nico-playlist
いやぁ久々ソースにコメント書いたね!(えっ
Posted at by



2008/10/10


ようやく動いた。
Apache2/mod_rubyでtDiaryを動かそうと思ったけど、エラーが出て動かなかった。どうやらrhtmlをERBでパースする所で出てるみたい。
今日はこの不可解な問題と向き合ったお話。
まずはmod_rubyをインストールするに当たりバイナリを取ってきたけどDLLのエントリポイントが見つからないとエラーが出たのでビルドする。
svn co http://svn.modruby.net/repos/mod_ruby/trunk mod_ruby
で最新を取って来て、以下のパッチを当てる。
Index: bucket.c
===================================================================
--- bucket.c    (revision 141)
+++ bucket.c    (working copy)
@@ -28,6 +28,10 @@
 #include "mod_ruby.h"
 #include "apachelib.h"
 
+#ifdef _WIN32
+# undef read
+#endif
+
 #ifdef APACHE2
 
 VALUE rb_cApacheBucket;
そして以下のMakefile.w32をmod_ruby直下に置く
APACHE_ROOT=C:\Program Files\Apache Software Foundation\Apache2.2
RUBY_ROOT=C:\Ruby
SRCS = \
    apache_cookie.c \
    apache_multipart_buffer.c \
    apache_request.c \
    apachelib.c \
    array_header.c \
    bucket.c \
    connection.c \
    cookie.c \
    error.c \
    mod_ruby.c \
    multival.c \
    paramtable.c \
    request.c \
    ruby_config.c \
    ruby_shared_stub.c \
    server.c \
    table.c \
    upload.c \
    uri.c

OBJS = $(SRCS:.c=.obj)
CFLAGS=/I"$(APACHE_ROOT)\include" /I"$(RUBY_ROOT)\lib\ruby\1.8\i386-mswin32" /DWIN32 /nologo
LDFLAGS=/LIBPATH:"$(APACHE_ROOT)\lib" /LIBPATH:"$(RUBY_ROOT)\lib"
LIBS= libapr-1.lib libaprutil-1.lib libhttpd.lib msvcrt-ruby18.lib

.SUFFIXES: .c .obj

all : mod_ruby.so

.c.obj:
    cl /c $(CFLAGS) /Fo$@ $<

mod_ruby.so : $(OBJS)
    link /nologo /DLL /OUT:$@ /EXPORT:ruby_module $(OBJS) $(LDFLAGS) $(LIBS)

clean :
    -@del /Q *.obj *.so
パス等は環境に合わせて修正して下さい。
コマンドラインからnmakeでビルド(mingw32の場合はもう一工夫いります)。出来上がったmod_ruby.soをApacheのmodulesディレクトリに配置。httpd.confは適当に設定。 次にtDiary。最新版を svn co https://tdiary.svn.sourceforge.net/svnroot/tdiary/trunk/core tdiary
で取得して設定を済ませる。デフォルトの.htaccessはCGI版になっているので Options +ExecCGI

# if you run tDiary with symbolic link, use settings below.
#Options +FollowSymLinks

# if making anchor style as 'YYYYMMDD.html', add some settings below.
# SEE header of html_anchor.rb plugin.

#AddHandler cgi-script .rb
AddHandler ruby-script .rb
DirectoryIndex index.rb
AddType application/xml .rdf

<Files "*.rhtml*">
    deny from all
</Files>

<Files "tdiary.*">
    deny from all
</Files>

<Files update.rb>
    AuthName      tDiary
    AuthType      Basic
    AuthUserFile  /home/foo/.htpasswd
    Require user  foo
    SetHandler ruby-object
    RubyHandler Apache::RubyRun.instance
</Files>

<Files index.rb>
    SetHandler ruby-object
    RubyHandler Apache::RubyRun.instance
</Files>
以上の様に修正する。さて実行...とまでは良かったが冒頭で書いたエラーが発生。色々調べている内にERBのresult(binding)メソッドでエラーが発生している事が分かった。
しかもコマンドラインから実行すると現象は発生しないけど、Apacheから動かすとエラーが発生する。さらに調べた所、rhtmlファイル内にあるタブ文字(0x09)が影響している事が分かり、tDiaryのskelディレクトリ内にある全てのrhtmlファイルに対してタブ文字からスペースに置き換える作用を行うと正しく動作する。
これでようやくApache2/mod_rubyで動くtDiaryが完成した。
tdiary-apache2-modruby-win32
ただ、どうしてもタブ文字でおかしくなる原因が分からない。RubyKanjiCodeを指定しても駄目。お手上げです。

誰か原因知りませんか?
Posted at by