CUI版mixi station
内定者向けの課題
内定した会社の課題がちょっとおもしろい出題法でよかった。
そのうちのひとつ、おもしろい.bashrcを書けというものがあったので、
ちょっと作ってみた。
CUI版のmixi station
まずは.bashrcから
MIXISTATION=~/mixi_station/mixi.rb MIXIDIR=~/mixi_station/ if [ -f $MIXISTATION ];then echo "mixi station mini"; alias mtracks="$MIXISTATION tracks"; alias mnotify="$MIXISTATION notify"; alias mstop="killall mixi.rb"; alias mstart="$MIXISTATION start&"; alias wtracks="less $MIXIDIR/tracks.log"; alias wnotify="less $MIXIDIR/notify.log"; $MIXISTATION start& fi
#!/usr/bin/ruby require 'net/http' require 'kconv' require 'rexml/document' require 'time' require 'digest/sha1' require 'yaml/store' MIXIID=#mixi id EMAIL =#Eメールアドレス PASSWD=#パスワード class AtomPPClient def initialize(server,email,pass) @server=server; @pass=pass; @email=email; @header=nil; end # # def _wsse_header(email, password) nonce = Array.new(10){ rand(0x100000000) }.pack('I*') nonce_base64 = [nonce].pack("m").chomp # Base64エンコード now = Time.now.utc.iso8601 digest = [Digest::SHA1.digest(nonce + now + password)].pack("m").chomp credentials = sprintf(%Q<UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s">, email, digest, nonce_base64, now) { 'X-WSSE' => credentials } end def get(rest) if @header==nil @header=_wsse_header(@email,@pass) end # p @header Net::HTTP.start(@server,80)do |http| response=http.get(rest,@header); if(response.body.match(/^<xml/)==nil) #response.body.toutf8; REXML::Document.new(response.body); else nil; end end end end class MixiChecker API={ "tracks"=>"/atom/tracks/r=2/member_id=#{MIXIID}", "notify"=>"/atom/notify/r=2/member_id=#{MIXIID}"}; LOG={ "tracks"=>"#{ENV['HOME']}/mixi_station/tracks.log", "notify"=>"#{ENV['HOME']}/mixi_station/notify.log"}; LOG_UPDATE="#{ENV['HOME']}/mixi_station/update.yaml"; def initialize() @atom=AtomPPClient.new("mixi.jp",EMAIL,PASSWD); @db=YAML::Store.new(LOG_UPDATE); end def check(val) last_update={}; @db.transaction{ if @db[val]==nil last_update[val]=Time.parse("1/1"); else last_update[val]=@db[val]; end } data=[] @atom.get(API[val]).root.each_element("entry"){|ent| if val=="tracks" update =Time.parse(ent.elements["updated"].text); name =ent.elements["author/name"].text; if update - last_update[val] >0 data.push({:update=>update,:content=>name.toutf8}) end elsif val=="notify" update =Time.parse(ent.elements["updated"].text); content =ent.elements["content"].text; if (ent.elements["category"].attributes["term"]!="notice")&&(update - last_update[val] >200) data.push({:update=>update,:content=>content}) end else puts "undefined api"; end } data.sort!{|a,b| (a[:update]<=>b[:update])}; open(LOG[val],"a"){|f| if data.length>0 puts ""; end data.each{|d| f.puts "#{d[:content]}\t#{d[:update]}"; puts "#{d[:content]}\t#{d[:update]}"; } } @db.transaction{ @db[val]=data.last[:update] if data.length >0 } end def start ["INT","TERM"].each{|sig|trap(sig){puts "shutdown mixi station";exit;}} self.check("notify") self.check("tracks") i=0; loop do if(i%5==0) #puts "check_notify" self.check("notify") else #puts "check_tracks" self.check("tracks") end sleep(10); i=i+1; end end end case ARGV.shift when "start" MixiChecker.new.start; when "notify" puts "mixi station mini check notification...." MixiChecker.new.check("notify"); when "tracks" puts "mixi station mini check tracking...." MixiChecker.new.check("tracks"); end