ありダラ
とゆーわけで。
ほんとはHDWriter::Application#postの中身もちょっとメソッドでくくりたかった
んだけど。疲れててしなくて、確かそのまま。
…何が問題って、そりゃ一番の問題は私がほとんどWWW::Mechanizeのことを
しらないことです。
□あからさまな変更点
- HDWriterモジュール
- HDWriter#Config
- HDWriter#Option
- HDWriter#Application
- 設定ファイルの書式
- 例外をファイルにダンプするようになった
- 日記テキストを検索するディレクトリを指定するようになった
- touchはYAMLで書き出す
[Ruby]application.rb
アプリケーションのライブラリ。
- 2007-11-11:Hash#updateの挙動を勘違いしていたので修正。
# WWW::Mechanize版はてダラ(はてなダイアリーライター) # # from: http://d.hatena.ne.jp/spider-man/20070818 # # mofdified by arikui. # distributes under the same term as Ruby. # # Version -- 0.3.1 require 'rubygems' require 'mechanize' require 'optparse' require 'yaml' module HDWriter class LoginError < RuntimeError ; end CONFIG_PATH = './config.rb' TOUCH_SAVE_PATH = './_touch.dat' ERROR_DUMP_PATH = './_error.dump' class Config def self.empty new() end def initialize(h={}) @configs = h end [ :diary_directory, :hatena_id, :password, :proxy_address, :proxy_port ].each do |name| define_method(name){ @configs[name] } end end class Option DEFAULT = { :trivial => false } def self.default new() end def initialize(h={}) @options = DEFAULT.dup.update(h) end DEFAULT.keys.each do |name| define_method(name){ @options[name] } define_method("#{name}="){|v| @options[name] = v } end end class Application VERSION = '0.3.0' DIARY_FILE_PATH_FILTER = /\d\d\d\d-\d\d-\d\d\.txt/ def initialize(configs=Config.empty, options=Option.default) @on_login = false @echo = $stdout @agent = WWW::Mechanize.new @configs = configs @options = options @opp = new_optionparser() end attr_reader :echo attr_reader :agent attr_reader :configs attr_reader :options def new_optionparser opp = OptionParser.new opp.on('-t', '--trivial', 'trivial update'){ options.trivial = true echo.puts 'trivial update on' } opp.on('-h', '--help', 'show this help'){ print_help } opp.on('-v', '--version', 'show version'){ print_version } opp end private :new_optionparser def option_parse!(argv) @opp.parse!(argv) end def print_help $stderr.puts @opp.help exit end private :print_help def print_version $stderr.puts "hdwriter -- version #{VERSION}" exit end private :print_version def setup_agent return unless configs.proxy_address echo.puts "set proxy -> #{configs.proxy_address}:#{configs.proxy_port}" agent.set_proxy(configs.proxy_address , configs.proxy_port) end def login form = agent.get('https://www.hatena.ne.jp/login').forms.first set_login_form(form) res = form.submit if /.*error-message"\>.*\<p\>(.*?)\<\/p\>.*\<\/div\>/m =~ res.body raise LoginError, "login error to #{configs.hatena_id}" else echo.puts "login to #{configs.hatena_id}" @on_login = true end end def set_login_form(form) form["name"] = configs.hatena_id form["password"] = configs.password form["persistent"] = "true" form end private :set_login_form def post touched = touch_time() #optimize by cache value. Dir.foreach(diary_dir) do |path| next unless DIARY_FILE_PATH_FILTER === path path = File.join(diary_dir(), path) next unless File.mtime(path) > touched login unless @on_login echo.print "post #{path} ... " date = File.basename(path, '.txt').split('-') uri = hatena_dirary_edit_uri(date) form = agent.get(uri).forms.first body = File.open(path){|f| f.read.split("\n", 2) } set_write_form(form, date, body) form.submit echo.puts "end" end end def diary_dir configs.diary_directory || '.' end private :diary_dir def hatena_dirary_edit_uri(date) [ "http://d.hatena.ne.jp", configs.hatena_id, "edit?date=#{date.join}" ].join('/') end private :hatena_dirary_edit_uri def set_write_form(form, date, body) form["year"] = date[0] form["month"] = date[1] form["day"] = date[2] form["title"] = body[0] form["body"] = body[1] form["trivial"] = "true" if options.trivial form end private :set_write_form def touch_time if File.exist?(TOUCH_SAVE_PATH) YAML.load_file(TOUCH_SAVE_PATH) else Time.now end end private :touch_time def update_touch_time File.open(TOUCH_SAVE_PATH, 'w') do |f| YAML.dump(Time.now, f) end end end end
[Ruby]hdwriter.rb
エントリポイント。
require 'application.rb' def exceptions_handling begin yield rescue Exception => ex err = HDWriter::ERROR_DUMP_PATH #optimize File.open(err, 'w') do |f| f.puts Time.now, ex.class, ex.message, ex.backtrace end $stderr.puts "Error! -- #{ex.message}" $stderr.puts "(error details was dumped at `#{err}')" exit end end def run_application(application) exceptions_handling do application.option_parse!(ARGV) application.setup_agent application.post application.update_touch_time end end load HDWriter::CONFIG_PATH configs = hdwriter_context() run_application HDWriter::Application.new(configs)
[Ruby]config.rb(例)
def hatena_diary_context { :hatena_id => "arikui1911", :password => "xxxx" } end def hdwriter_context HDWriter::Config.new( hatena_diary_context.dup.update( :diary_directory => './diary' ) ) end