td2planetを使ってみた。

ごにょごにょやっている一環で、td2planetを導入してみた。当初はplanetplanetを導入しようかと思ったのだが、pythonによる実装なのですな、これ。複数の実装を導入するのがメンテナンス考えると面倒なので、rubyによる実装のtd2planetを導入してみたわけだ。td2planetのtdはtDiaryのtdなんですな。導入メモは以下。

パッケージの導入

$ sudo apt-get install td2planet
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  tdiary-theme
Suggested packages:
  tdiary
The following NEW packages will be installed:
  td2planet tdiary-theme
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 3693kB of archives.
After this operation, 12.6MB of additional disk space will be used.
Do you want to continue [Y/n]?
Get:1 http://cdn.debian.or.jp lenny/main tdiary-theme 2.2.1-1 [3681kB]
Get:2 http://cdn.debian.or.jp lenny/main td2planet 0.1.0-2 [12.1kB]
Fetched 3693kB in 3s (1129kB/s)
Selecting previously deselected package tdiary-theme.
(Reading database ... 18285 files and directories currently installed.)
Unpacking tdiary-theme (from .../tdiary-theme_2.2.1-1_all.deb) ...
Selecting previously deselected package td2planet.
Unpacking td2planet (from .../td2planet_0.1.0-2_all.deb) ...
Processing triggers for man-db ...
Setting up tdiary-theme (2.2.1-1) ...
Setting up td2planet (0.1.0-2) ...

td2planet用ユーザの作成

td2planet用のユーザを作成する。td2planetとする。

$ sudo adduser --home /var/www/td2planet --ingroup nogroup --disabled-password \
 --no-create-home --shell /bin/false --disabled-login td2planet

導入、設定

ホームディレクトリ/var/www/td2planet以下に公開用のディレクトリを作る。Lightyのsimple-vhostを使うので、その下にvhost1.hoge.comというディレクトリをまず掘る。

$ sudo mkdir /var/www/td2planet/vhost1.hoge.com/

ここに設定ファイルを置く。

$ sudo -u td2planet cp -/usr/share/doc/td2planet/examples/config.yaml /var/www/td2planet/vhost.hoge.com/

config.yamlを設定する。サンプルファイルを変更するとこんな感じ。

## general config
title: hoge planet
base_uri: http://vhost1.hoge.com/

## feed URIs
uri:
  - http://d.hatena.ne.jp/mkouhei/rss
  - http://d.hatena.ne.jp/emkouhei/rss

## feeds cache into cache_dir
cache_dir: cache

## generated files into output_dir
output_dir: output
output_html: planet.html

## themes
#tdiary_theme_path: http://localhost/tdiary/theme
#tdiary_theme_path: /var/www/tdiary/theme
tdiary_theme: light-blue

## parts of templates
#author: Your name
#made: mailto:webmaster@example.jp
#favicon: /favicon.ico
#logo_html: <img src="http://planet.example.jp/images/logo.png" width="168" heig
ht="150" alt="">
date_strftime_format: '%Y-%m-%d'
sanchor_strftime_format: '%H:%M:%S'

## templates search path
#templates_path:
#  - /path/to/override/templates
#  - /path/to/other/override/templates

## formatter
formatter: default_formatter
#formatter: sample_formatter
#formatter: your_formatter

## spam filter (default_formatter feature)
## (filtered if last value is true, output if false)
filter: |
    if (/ツッコミ/ =~ k(item.title) &&
        (
          (k(item.content_encoded).scan(/http:/).size >= 5) ||
          (k(item.description).scan(/http:/).size >= 5) ||
          (/\[\/url\]/ =~ k(item.content_encoded)) ||
          (/\[\/url\]/ =~ k(item.description)) ||
          (/★/ =~ k(item.dc_creator)) ||
          /@google\.com/ =~ k(item.dc_creator)
        ))
      true
    else
      false
    end

実行してみる

$ cd /var/www/td2planet/vhost1.hoge.com/
$ sudo -u td2planet config.yaml

問題なく表示できることを確認できたら、cronで設定する。td2planetユーザでcronを回すので、/etc/cron.allowにtd2planetユーザを予め追記しておく。

$ sudo crontab -u td2planet -e

# m h  dom mon dow   command
24 * * * * cd /var/www/td2planet/vhost1.hoge.com/; td2planet config.yaml

Webサーバ(Lighty)で公開する。

もともとlighttpdを使っているのだが、virual hostは使っていなかった。今回、td2planet用にホスト名ベースでvirtual hostを設定してみた。まずは、モジュールを有効にする。ホスト名ベースでのvirtual hostの設定のやり方はいくつかあるようなのだが、今回はsimple-vhostで行う。

$ sudo /usr/sbin/lighttpd-enable-mod simple-vhost
$ cd /etc/lighttpd/conf-available/

設定ファイルを変更する。

## Simple name-based virtual hosting
##
## Documentation: /usr/share/doc/lighttpd-doc/simple-vhost.txt
##                http://www.lighttpd.net/documentation/simple-vhost.html

server.modules += ( "mod_simple_vhost" )

## The document root of a virtual host isdocument-root =
##   simple-vhost.server-root + $HTTP["host"] + simple-vhost.document-root

$HTTP["host"] == "hoge.com" {
     simple-vhost.server-root         = "/var/www"
     simple-vhost.document-root       = "/"
     simple-vhost.default-host        = "hoge.com"
}

$HTTP["host"] !~ "^(vhost1\.hoge\.com|vhost2\.hoge\.com)$" {
     simple-vhost.server-root         = "/var/www"
     simple-vhost.document-root       = "/"
     simple-vhost.default-host        = "www.hoge.com"
}


$HTTP["host"] == "vhost1.hoge.com" {
     url.rewrite-once = (
             "^/$" => "/planet.html",
     )
     alias.url       += (
             "/tdiary/theme/" => "/usr/share/tdiary/theme/"
     )

     server.document-root = "/var/www/td2planet/vhost1.hoge.com/output/"
     accesslog.filename = "/var/log/lighttpd/vhost1.access.log"
}

つぎに元の設定を変更する。10-cgi.confの中で、www.hoge.comfやhoge.comにマッチした場合の処理を設定する。そうしないと、せっかくtd2planet用にvirtual hostを設定しても、期待通りに表示されない。

変更前
alias.url       += ( "/blog/" => "/var/www/blog/" )

$HTTP["url"] =~ "/blog/" {
     cgi.assign = ( ".cgi" => "" )


変更後
$HTTP["host"]        =~ "^(www\.hoge\.com|hoge\.com)$" {
     alias.url       += ( "/blog/" => "/var/www/blog/" )
     $HTTP["url"] =~ "/blog/" {
             cgi.assign = ( ".cgi" => "" )
     }
}

これらの設定をしておかないと、www.hoge.com/planet.htmlやhoge.com/planet.htmlでtd2planetのコンテンツが見えてしまう。simple-vhostの設定は、 Lighttpdのマニュアル を読むのがベストだ。

あとは、再起動する。

$ sudo /etc/init.d/lighttpd restart

任意のカテゴリのエントリだけを表示させる

テーマを絞って表示したい。タイトルで判断することにする。これにはformatterを使用する。まず、config.yamlの

## formatter
formatter: default_formatter
#formatter: sample_formatter
#formatter: your_formatter

となっている箇所を、default_formatterをコメントアウトし、your_formatterを有効にする。次にsample_formatter.rbを雛形に、your_formatter.rbを作成する。

$ sudo -u td2planet cp -i /usr/lib/ruby/1.8/td2planet/sample_formatter.rb /var/www/td2planet/vhost1.hoge.com/your_formatter.rb
$ sudo -u td2planet vi your_formatter.rb
$ cd /var/www/td2planet/vhost1.hoge.com/
$ diff -u /usr/lib/ruby/1.8/td2planet/sample_formatter.rb your_formatter.rb

変更箇所は以下のとおり。

--- /usr/lib/ruby/1.8/td2planet/sample_formatter.rb  2007-07-06 12:00:16.000000000 +0900
+++ your_formatter.rb        2009-05-25 22:27:29.000000000 +0900
@@ -8,14 +8,18 @@
 require 'td2planet/formatter'

 module TD2Planet
-  class SampleFormatter < Formatter
+  class YourFormatter < Formatter
     def spam?(item)
-      if /ツッコミ/ =~ k(item.title) &&
-          /casino/ =~ item.dc_creator &&
-          /casino/ =~ item.description
-        true
-      else
+      #if /ツッコミ/ =~ k(item.title) &&
+      if /(Keyword1|Keyword2|Keyword3)/ =~ k(item.title)
+          #/casino/ =~ item.dc_creator &&
+          #/casino/ =~ item.description
+        #true
         false
+      else
+        #false
+    true
       end
     end

実際はこんな感じ。

#--
# -*- mode: ruby; coding: utf-8 -*-
# vim: set filetype=ruby ts=2 sw=2 sts=2 fenc=utf-8:
#
# copyright (c) 2006, 2007 Kazuhiro NISHIYAMA
#++

require 'td2planet/formatter'

module TD2Planet
  class YourFormatter < Formatter
    def spam?(item)
      #if /ツッコミ/ =~ k(item.title) &&
      if /(Keyword1|Keyword2|Keyword3)/ =~ k(item.title)
          #/casino/ =~ item.dc_creator &&
          #/casino/ =~ item.description
        #true
        false
      else
        #false
     true
      end
    end

    def skip?(item)
      spam?(item) or too_old?(item)
    end
  end
end

これで、Keyword1, Keyword2, Keyword3のカテゴリのエントリだけが表示されるようになる。

これで終わり、のはずだった。

はてダのRSSの仕様による、表示上のバグ

終わりだと思ったら、どうも表示がおかしい。カテゴリが重複して表示されるのだ。どうやら、はてダのRSSでのカテゴリはitem要素の子要素dc:subjectにあるのだが、同じ子要素titleにも、”[keyword1][keyword2]title”という形でタイトルの先頭に残ってしまう。まぁ、これがあるおかげで、YourFormatterのitem.titleで該当するキーワードのエントリだけを拾えるのだけど。で、仕方ないので、titleの文字列のうち、”[...]”となっている箇所を破壊的に削除することにした。やることは簡単。item.titleに対し、該当部分だけを削除するように、

item.title.gsub!(/\[.*\]/, "")

の一行を追加してやればよい。変更後は以下のようになる。

#--
# -*- mode: ruby; coding: utf-8 -*-
# vim: set filetype=ruby ts=2 sw=2 sts=2 fenc=utf-8:
#
# copyright (c) 2006, 2007 Kazuhiro NISHIYAMA
#++

require 'td2planet/formatter'

module TD2Planet
  class YourFormatter < Formatter
    def spam?(item)
      #if /ツッコミ/ =~ k(item.title) &&
      if /(Keyword1|Keyword2|Keyword3)/ =~ k(item.title)
          #/casino/ =~ item.dc_creator &&
          #/casino/ =~ item.description
        #true
        item.title.gsub!(/\[.*\]/, "")
        false
      else
        #false
     true
      end
    end

    def skip?(item)
      spam?(item) or too_old?(item)
    end
  end
end

これでやりたいことが全てできた。よかったよかった。