- シリーズ パッケージマネジメント 【第 2 回】 RubyGems (2) RubyistMagazine の記事
- gemspecファイルのリファレンス
- rake の GemPackageTask
カテゴリー: Ruby
publish::hatena_diary_writer が受け取るデータ
時間がないのでアイデアのメモだけ。
要するに,日記として必要なデータは日付と本文なわけで,これを Hash に入れてやればいいんじゃないかな。こんな感じに。
[{"date" => "2007-02-26", "content" => "日記の本文"}, ...]
キー”date” の値は Time のインスタンスか parsedate 可能な文字列。nil なら日付を指定しない(つまり今日の日記)。キー”content”の方はもちろん文字列。
これなら,後々キーを追加(タイトルとか添付画像とか)するにも都合がいい。
PRagger
と publish::hatena_diary_writer プラグインで書き込みテスト。
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 がどんなデータを想定してるのかわからないんですが。
クラスはよくてもモジュールは?
いままで気にしたことなんて無かったけど……
cf. Matzにっき – jijixi’s diary – Ruby の文法的欠陥
cf. じじぃの日記、ツッコミ可 – Ruby の文法的欠陥
jijixiさんのいう”欠陥”(というと言いすぎのような気もする,といっているけど)というのは
『新しいクラスを作ってるつもりで、知らないうちに既存のクラスを上書きする可能性がある』
で,これに対するまつもとさんの対策が
* ちゃんと名前空間を分離する
* クラスを定義する時にはスーパークラスを明示する
2つ目の方は,クラスを定義するときに指定したスーパークラスが合わないとエラーになるってことだな。
D:\>irb irb(main):001:0> class Foo; end => nil irb(main):002:0> class Bar; end => nil irb(main):003:0> class Baz < Foo; end => nil irb(main):004:0> class Baz < Bar; end TypeError: superclass mismatch for class Baz from (irb):4 from :0
そうは言っても class Foo < Object って書いてるのは見たこと無いけど。
さて,クラスはいいとしてもモジュールはどうだろう。
スーパークラスの明示みたいなものはないし,トップレベルで定義されたモジュールでは名前空間の分離もできない。
……ってことは,気をつけるしかないのか。
ちなみに,素の状態で定義されているモジュールは
D:\>type modules.rb ObjectSpace.each_object(Object){|o| puts o.name if o.class == Module} D:\>ruby modules.rb Marshal ObjectSpace GC Math Process::Sys Process::GID Process::UID Process Signal File::Constants FileTest Errno Precision Enumerable Comparable Kernel
意外に少ない。
テキストでプログレスバー
cf. Ruby/ProgressBar: プログレスバーをテキストで表示する Ruby用のライブラリ
via 趣味的にっき – プログレスバーをテキストで表示する関数
インストールは progressbar.rb をライブラリパスの通ったところにおけばいいだけ。
ProgressBar のインスタンスをつくっておいて ProgressBar#inc か ProgressBar#set で進捗を表示する。
まずは記事にある使用例で試してみよう。
D:\>irb -rprogressbar irb(main):001:0> pbar = ProgressBar.new("title", 100) => #<ProgressBar:0/100> | ETA: --:--:-- irb(main):002:0> (1..100).each{|i| sleep(0.1); pbar.set(i)}; pbar.finish title: 100% |oooooooooooooooooooooooooooooooooooooooooo| Time: 00:00:35 => Thu Dec 21 21:29:46 +0000 2006
ProgressBar#file_transfer_mode を使うと,ファイルの転送バイト数と転送速度を表示できる。
こんな感じ。
require 'progressbar' fname1 = ARGV.shift fname2 = ARGV.shift f1 = File.open(fname1, "rb") f2 = File.open(fname2, "wb") size = File.size(fname1) pbar = ProgressBarnew("transfer file", size) pbar.file_transfer_mode until f1.eof? f2.write(f1.read(1000)) pbar.inc(1000) end pbar.finish f1.close f2.close
ファイルのコピーを低レベルでやらなきゃいけないけど。
実行例。
D:\>copy_pbar.rb projects.xls copy_projects.xls transfer file: 100% |oooooooooooooooooooooooo| 5.0MB 35.5MB/s Time: 00:00:00