LIRS を取得する PRagger プラグイン

を作ってみたけど,「LIRSってどんなんだっけ?」ってとこから始めたからどうもよくわからない。

こんなんでいいのかな。

LIRS と RSS の対応は表のようにしてみたけど,どうか。

LIRS RSS
更新時刻 (Last-Modified GMT) dc:date
更新時刻を取得した時刻(GMT)
サイトのGMTとの時差(秒)
サイトのURL link
サイトの容量
サイトのタイトル title
サイトの管理者
情報取得元サイトのURL
独自情報

require 'open-uri'
require 'rss/maker'
require 'zlib'
require 'kconv'
$KCODE = 'utf8'
def parse_lirs(record)
fields = record.chomp.split(",")
item = RSS::RDF::Item.new
item.title = fields[6]                                 # Title
item.link  = fields[5]                                 # URL
item.date  = Time.at(fields[1].to_i + fields[3].to_i)  # Last-Modified (local time)
return item
end
def load_lirs(config, data)
f = open(config["url"])
lirs = Zlib::GzipReader.wrap(f) {|gz| gz.read }.toutf8
items = lirs.map {|record| parse_lirs(record) }
return items
rescue
puts "LoadError File = #{config["url"]}"
return []
end

publish::hatena_diary_writer が受け取るデータ

時間がないのでアイデアのメモだけ。

要するに,日記として必要なデータは日付と本文なわけで,これを Hash に入れてやればいいんじゃないかな。こんな感じに。

[{"date" => "2007-02-26", "content" => "日記の本文"}, ...]

キー”date” の値は Time のインスタンスか parsedate 可能な文字列。nil なら日付を指定しない(つまり今日の日記)。キー”content”の方はもちろん文字列。

これなら,後々キーを追加(タイトルとか添付画像とか)するにも都合がいい。

PRagger その2

下のエントリをポストするのに使った publish::hatena_diary_writer.rb プラグインがちょっと使いにくい。

今日の日記にしかポストできないのはとりあえずおいとくとしても,ポストするたびに下に追加ってのは1日1ファイルにしてる俺のやり方とは違う。

ここはやっぱり全面的に置き換えるのがいい。

というわけでちょっと手を入れてみた。

config[“mode”] が replace なら上書き,add なら下に追記,insert なら上に挿入だ(文字化けしてるのはsvnのせいみたい)。

ついでに proxy にも対応。環境変数 http_proxy が設定されていればそれを使う。

追記:おっと。http_proxy の文字列にはスキーマも含むのか。というわけで以下のコードは差し替えた。

Index: hatena_diary_writer.rb
===================================================================
--- hatena_diary_writer.rb	(リビジョン 57)
+++ hatena_diary_writer.rb	(作業コピー)
@@ -1,12 +1,19 @@
#!/usr/bin/env ruby
# hatena_diary_writer.rb
#
+require 'uri'
class HatenaDiaryWriter
def initialize(id,password)
@id = id
@password = password
@agent = WWW::Mechanize.new
+    if proxy = ENV['http_proxy']
+      proxy = URI.parse(proxy)
+      proxy_addr = proxy.host
+      proxy_port = proxy.port
+      @agent.set_proxy(proxy_addr, proxy_port)
+    end
@diary = @agent.get("http://d.hatena.ne.jp/#{id}/")
end
@@ -21,11 +28,18 @@
@diary_page = @agent.get(@diary_link.href)
end
-  def edit(content)
+  def edit(content, mode)
edit_link = @diary_page.links.text("譌・險倥r譖ク縺・.toeuc)
      edit_page = @agent.get(edit_link.href)
      edit_form = edit_page.forms.name("edit").first
 -    edit_form["body"] += content
 +    case mode
 +    when 'add'
 +      edit_form["body"] += content
 +    when 'insert'
 +      edit_form["body"] = content + edit_form["body"]
 +    when 'replace'
 +      edit_form["body"] = content
 +    end
      ok_button = edit_form.buttons.name("edit")
      @agent.submit(edit_form, ok_button)
    end
 @@ -42,5 +56,5 @@
      content << ("* "+line.title+"\n"+line.link+"\n"+line.description rescue line.to_s)
    end
    diary.login
 -  diary.edit(content.toeuc)
 +  diary.edit(content.toeuc, config['mode'])
  end

設定ファイルはこんな感じ。

- module: stdin
config:
input: nothing
- module: publish::hatena_diary_writer
config:
user_id: takatoh
password: xxxxxxxx
mode: replace

日記のファイルはコマンドラインで指定する。

^o^>pragger -c hatena.yaml 2007-02-24.txt
exec plugin stdin
exec plugin publish::hatena_diary_writer

ところで

data.each do |line|
content << ("* "+line.title+"\n"+line.link+"\n"+line.description rescue line.to_s)
end

の line がどんなデータを想定してるのかわからないんですが。

変数のスコープ

変数を定義するときには,とにかく var をつけておくのが良さそうだ。

  • 関数の外で定義した変数はグローバル
  • 関数の中で var を使って定義した変数はその関数内のローカル
  • 関数の中で var を使わずに定義した変数はグローバル

関数の中で var を使った場合:

var v1 = "global v1";

function foo() {
    var v1 = "local v1";
    document.write("in function: ", v1, "<br>");      // => "local v1"
    return "function called.";
}

document.write("before function call: ", v1, "<br>");      // => "global v1"
foo();
document.write("avter function call: ", v1, "<br>");      // => "global v1"
before function call: global v1
in function: local v1
avter function call: global v1

関数の中で var を使わなかった場合:

var v2 = "global v2";

function bar() {
    v2 = "local v2";
    document.write("in function: ", v2, "<br>");
    return "function called.";
}

document.write("before function call: ", v2, "<br>");
bar();
document.write("avter function call: ", v2, "<br>");
before function call: global v2
in function: local v2
avter function call: local v2

arguments

関数定義に仮引数を書かなくても,arguments という配列に格納される。引数の数が不定の場合に便利。

function hello() {
    for (var i=0; i<arguments.length; i++) {
        document.write("hello,=", arguments[i], "<br>");
    }
    return i;
}

hello("Andy", "Bill", "Charlie");

無名関数

名前を指定しないで関数を定義すると無名関数になる。

変数に代入する場合:

var f1 = function(arg1, arg2) {
    return arg1 * arg2;
}
f1(3,2); // => 6

直接使う場合:

var a = new Array(3, 2, -6, 8, -4);
a.sort(function (a,b) {return a - b;});
document.write(a.toString()); // => -6,-4,2,3,8