MovableTypeに投稿
30分プログラム、その136。MovableTypeに投稿するRubyプログラム。
はてダラのMovableType版を作りたいので、それの基本となる部分。コマンドラインオプションが多すぎて使いずらいので、これを使ったラッパをそのうち書こう。
使い方
次のようなsample.txtを用意する。
タイトル Tag:: a,b,c Category:: 日記 こんにちは、こんにちは。
$ ruby movabletype.rb \ --entry=http://example.com/mt-xmlrpc.cgi \ --username=mzp \ --password=hogehoge \ --blogid 5 \ sample.txt
ソースコード
#! /opt/local/bin/ruby -w # -*- mode:ruby; coding:utf-8 -*- # # movabletype.rb - # # Copyright(C) 2007 by mzp # Author: MIZUNO Hiroki <hiroki1124@gmail.com> # http://mzp.sakura.ne.jp/ # # Timestamp: 2007/09/17 15:13:30 # # This program is free software; you can redistribute it and/or # modify it under the same terms as Ruby itself. # require 'xmlrpc/client' module MovableType Entry = Struct.new 'Entry',:postid class Blog def initialize(entry,blogid,username,password) @xml = XMLRPC::Client.new2 entry @blogid = blogid @username = username @password = password end def post(title,body,option={}) id = @xml.call('metaWeblog.newPost', @blogid,@username,@password, make_content(title,body,option), 0) Entry.new id end def edit(entry,title,body,option={}) id = @xml.call('metaWeblog.editPost', entry.postid, @username,@password, make_content(title,body,option), 1) Entry.new id end def make_content(title,body,option) { 'title'=>title, 'description'=>body, 'mt_tags'=>option[:tag].join(','), 'mt_convert_breaks'=>option[:format] } end private :make_content def delete(entry) @xml.call 'blogger.deletePost',0,entry.postid,@username,@password,1 end def category_list unless defined?(@cat) then @cat = {} @xml.call('mt.getCategoryList',@blogid,@username,@password).each{|s| @cat[s['categoryName']] = s['categoryId'].to_i } end @cat end def set_category(entry,category) @xml.call('mt.setPostCategories', entry.postid, @username, @password, category.map{|id| {'categoryId'=>id } }) end def publish(entry) @xml.call 'mt.publishPost',entry.postid,@username,@password end end end if __FILE__ == $0 then def parse(io) title = io.gets.chomp option = {} until (s = io.gets.chomp).empty? do name,value = s.chomp.split('::',2) # like Perl option[name.downcase.to_sym] = value.strip end body = io.read [title,body,option] end require 'optparse' entry = username = password = blogid = nil type = :post # or :edit/:delete postid = nil # require at :edit/:delete opt = OptionParser.new opt.on('-e ENTRY' ,'--entry ENTRY'){|entry|} opt.on('-u USERNAME','--username USERNAME'){|username|} opt.on('-p PASSWORD','--password PASSWORD'){|password|} opt.on('-b BLOG_ID' ,'--blogid BLOG_ID'){|blogid|} opt.on('-t TYPE','--type TYPE','post/edit/delete'){|t| type = t.to_sym } opt.on('-i ID' ,'--postid ID','post id'){|postid|} opt.parse! ARGV unless entry or username or password or blogid then abort 'require entry/username/password/blogid' end if (type == :edit or type == :delete) and postid == nil then abort 'require postid when edit or delete' end title = body = option = nil if type == :post or type == :edit then io = unless ARGV.empty? then File.open(ARGV.shift) else $stdin end title,body,option = parse io end mt = MovableType::Blog.new entry,blogid,username,password case type when :post e = mt.post(title, body, {:tag=>option[:tag].split(','),:format=>'markdown'}) mt.set_category e,[mt.category_list[option[:category]]] mt.publish e p e when :edit puts mt.edit(MovableType::Entry.new(postid), title, body, {:tag=>option[:tag].split(','),:format=>'markdown'}) mt.set_category entry,[mt.category_list[option[:category]]] mt.publish entry when :delete mt.delete MovableType::Entry.new(postid) end end