Rubyの魔神 このページをアンテナに追加 RSSフィード

   「Ruby」は宝石の魔神のイメージ(The Jinn of the Ruby)
   [VB] [VB6] [C#] [Android] [電子工作] [個人メモ] [仕事メモ] [アイデア] [TstLink] [CE] [LTSA] [自動化] [Qt] [OCaml] [TOOLS]
   [3Dプリンタ] [RAA] [Forge]   [機能別索引] [逆引きRuby] [マニュアル] [るびま] [標準ライブラリ] [るりまサーチ] [Try! Ruby] [PRaggerまとめ] [ピジョン・ブラッド]
   [Rubyコーディング規約] [プログラミングのオキテ] [Rubyist SNS] [TOOLBIS]
   [RubyネットワークProg] [druby] [コードなにがし] [RDocテンプレ] [Ruby/Tkサンプル]
   [WAVE] [Xperia] [github] [twitterなど] [Java] [EA] [マクロ]

2007-12-20

mailの本文に書かれたプログラムを実行して結果を返すプログラム

| 17:03 | mailの本文に書かれたプログラムを実行して結果を返すプログラム - Rubyの魔神 を含むブックマーク はてなブックマーク - mailの本文に書かれたプログラムを実行して結果を返すプログラム - Rubyの魔神 mailの本文に書かれたプログラムを実行して結果を返すプログラム - Rubyの魔神 のブックマークコメント

mail.rb

#!/usr/local/bin/ruby -Ks
require 'recvMail'
require 'sendMail'
require 'thread'
require 'logger'

class MailRobo

  def initialize(id,pass,popsvr,mailaddress,smtpsvr)
    @recvQueue = Queue.new
    @logger = Logger.new('logfile.log')
    @logger.level = Logger::DEBUG

    @recvmail = RecvMail.new(id, pass,popsvr)
    @sendmail = SendMail.new(@recvmail ,mailaddress,smtpsvr)
  end
  
  def main(sendmailaddress)
    @recvmail.start(@recvQueue)
    st = Thread.new do
      while true do
        if !@recvQueue.empty?
          fname = @recvQueue.pop
          mail=TMail::Mail.load(fname)

          str=""
          str += "mail from #{mail.to}\n"
          str += "mail to #{mail.from}\n"
          str += "subject #{mail.subject}\n"
          str += "date #{mail.date}\n"
          str += "ver #{mail.mime_version}\n"
          str += "body #{mail.body}\n"
          str += "excute:#{eval(mail.body)}"

          @logger.debug "recv #{fname}"
          @sendmail.send(sendmailaddress,'recvmail',str)
          @logger.debug "send mail"
        end
      end
      sleep 3
    end
    st.join
  end
end


mr=MailRobo.new('xxx@xxx.ne.jp', 'xxx','xxx.xxx.ne.jp','xxx@xxx.ne.jp','xxx.ne.jp')

mr.main('xxx@gmail.com')

sendmail.rb


#!/usr/local/bin/ruby -Ks
require 'net/smtp'
require 'net/pop'
require 'time'
require 'Tmail'
require 'kconv'

class SendMail
  def initialize(pop,mailAddress,smtpSvr,smtpPort=25)

    popSvr,popPort,id,password = pop.popSvr,pop.popPort,pop.popId,pop.popPassword

    @systemMailAddress=mailAddress
    @systemId=id
    @systemPassword=password
    @smtpSvr=smtpSvr
    @smtpPort=smtpPort
    @popSvr=popSvr
    @popPort=popPort
  end

  def send(mailaddress,subject,mes)
    Net::POP3.auth_only( @popSvr, @popPort,@systemId,@systemPassword )
    Net::SMTP.start( @smtpSvr, @smtpPort ) {|smtp|
      mail = TMail::Mail.new
      mail.to = mailaddress
      mail.from = @systemMailAddress
      mail.subject = subject.tojis
      mail.date = Time.now
      mail.mime_version = '1.0'
      mail.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'}
      mail.body = mes.tojis
      str = mail.encoded
      smtp.send_mail str,@systemMailAddress, mailaddress
      smtp.finish
    }
  end
end

recvmail.rb


#!/usr/local/bin/ruby -Ks
require 'net/pop'
require 'thread'
require 'pstore'
require 'tmail'
require 'logger'

class RecvMail

  attr_accessor :popSvr,:popPort,:popId,:popPassword

  MailDir = './inbox/'
  
  def initialize(popId,popPassword,popSvr,popPort=110)
    @logger = Logger.new('logfile.log')
    @logger.level = Logger::DEBUG
    @popId,@popPassword,@popSvr,@popPort=popId,popPassword,popSvr,popPort

    Dir::mkdir(MailDir) if not FileTest::directory?(MailDir)

    @counter = PStore.new(MailDir+'counter')
    @counter.transaction do
      if @counter['counter'].nil? then
        @counter['counter'] = 1
      end
    end
  end

  def start(recvQueue)
    begin
      recvMail = Thread.new do
        i = 0
        while true
          @counter.transaction do
            i = @counter['counter']
          end

          Net::POP3.delete_all(@popSvr,@popPort,@popId,@popPassword) do |m|
            Dir::mkdir(MailDir + i.to_s ) if not FileTest::directory?(MailDir + i.to_s)

            File.open( MailDir + i.to_s + '/'+ i.to_s, 'w' ) {|f|
                @logger.debug "recvQueue.size=#{recvQueue.size}"
                f.write m.pop
                @logger.debug "recvmail #{MailDir + i.to_s + '/'+ i.to_s}"
                @logger.debug "recvQueue.size=#{recvQueue.size}"
            }
            recvQueue.push(MailDir + i.to_s + '/'+ i.to_s)
            extractAttachments(MailDir + i.to_s + '/'+ i.to_s)
            @counter.transaction do
              i += 1
              @counter['counter'] = i
              puts i
            end
          end
          sleep 10
          print 'r'
        end
      end
    rescue
      p $!
      puts "err" 
    end
  end

  CTYPE_TO_EXT = {
    'image/jpeg' => 'jpeg',
    'image/gif'  => 'gif',
    'image/png'  => 'png',
    'image/tiff' => 'tiff',
    'application/vnd.ms-excel' => 'xls',
    'application/msword' => 'doc'
  }

  def extractAttachments(fname)
    ret =[]
    idx = 1
    email=TMail::Mail.load(fname)
    email.parts.each do |m|
      m.base64_decode
      file =  m.disposition_param('filename')
      file = "#{idx}.#{ext(m)}" if file.nil?
      puts "[RECV]#{file}"
      
      File.open(File.dirname(fname) + "/" + file, 'wb') {|f|
        ret << f
        f.write m.body
      }
      idx += 1
    end
    ret
  end

  def ext( mail )
    CTYPE_TO_EXT[mail.content_type] || 'txt'
  end
end

トラックバック - http://ruby.g.hatena.ne.jp/garyo/20071220

2007-12-12

RubyToXML:RubyソースのコメントからTestLinkのテストケース用XMLを作成するツール

| 15:22 | RubyToXML:RubyソースのコメントからTestLinkのテストケース用XMLを作成するツール - Rubyの魔神 を含むブックマーク はてなブックマーク - RubyToXML:RubyソースのコメントからTestLinkのテストケース用XMLを作成するツール - Rubyの魔神 RubyToXML:RubyソースのコメントからTestLinkのテストケース用XMLを作成するツール - Rubyの魔神 のブックマークコメント

Rubyソースのコメントからテスト管理ツールTestLink用のテストケースを作成するツール

ダウンロード

rubytoxml.rb

#=RubyToXML
#
#Rubyソースからテストケースを作成するツール
#==ツールの概要
#RubyソースにコメントからTestLinkのテストケース用XMLを作成するツールです。
#Rubyソースに以下の形式でコメントを記述すると
#
## tltestcase:: テストケース名
## tlsummary:: テストの概要
## tlsteps:: テスト手順
## tlexpectedresults:: 期待される結果
## tlkeyword:: キーワード
## tlnotes:: キーワードの説明
#下記のXMLファイルを生成します。
#
#<?xml version="1.0" encoding="UTF-8"?>
#<testsuite name="sample1"><details><![CDATA[
#
#]]></details>
#<testcase name="テストケース名"><summary><![CDATA[
#テストの概要
#]]></summary><steps><![CDATA[
#テスト手順
#]]></steps><expectedresults><![CDATA[
#期待される結果
#]]></expectedresults>
#<keywords>
#<keyword name="キーワード">
#<notes><![CDATA[
#キーワードの説明
#]]></notes>
#</keyword>
#</keywords>
#</testcase>
#</testsuite>
#
#このXMLファイルをテストケースの編集->テストスイートのツリーを選択->テストスイートをインポート からインポートすることによりテストケースがTestLinkに追加されます。
#
#改訂履歴
#2007/12/12 0.1 garyo 新規作成
#2007/12/12 0.2 garyo コメント訂正
#2007/12/12 0.3 garyo RDoc用に@xxx yyy を xxx::yyyに変更

require 'csv2testcace'

class RtxTestcase

  TLtestcase=0
  TLsummary=1
  TLsteps=2
  TLexpectedresults=3
  TLkeyword=4
  TLnotes=5

  attr_accessor :data,:keyword

  def initialize
    @keyword=["tltestcase","tlsummary","tlsteps","tlexpectedresults","tlkeyword","tlnotes"]
    @data={}
    @keyword.each{|k|
      @data[k]=""
    }
  end

  def getdata(i)
    @data[@keyword[i]]
  end

  def self.tltestcase?(s)
    if /tltestcase::/ =~ s then
      true
    else
      false
    end
  end

  def readLine(s)
    if /::/ =~ s then
      @keyword.each{|k|
        if /#{k}::(.*)$/ =~ s then
          @data[k] = $1.strip
        end
      }
    end
  end

end


class RubyToXML
  
  attr_accessor :filename,:file,:testcase

  def initialize
  end

  def load_file(filename)
    @filename=filename
    open(filename,"r"){|f|
      @file=f.read
    }
  end

  def convert(str)
    ret=[]
    tc = nil
    lines=str.split("\n")
    lines.each{|line|
      if RtxTestcase::tltestcase?(line) then
        tc = RtxTestcase.new
        ret << tc
      end
      tc.readLine(line) if tc
    }
    ret
  end

  def main(filename)
    load_file(filename)
    ret = convert(@file)

    cx=Csv2testcase.new
    cx.useTitleLine = false
    wrfile = File.dirname(filename) + "/" + File.basename(filename, ".*") + ".xml"
    testSuiteName = File.basename(filename, ".*")
    
    cx.initTestSuite(testSuiteName,"")

    ret.each{|r|
      ky=[]
      ky[0]=r.getdata(RtxTestcase::TLkeyword)
      ky[1]=r.getdata(RtxTestcase::TLnotes)
      cx.addTestcase(r.getdata(RtxTestcase::TLtestcase),r.getdata(RtxTestcase::TLsummary),r.getdata(RtxTestcase::TLsteps),r.getdata(RtxTestcase::TLexpectedresults),ky)
    }
    cx.writeFile(wrfile)
  end
end

if ARGV.size == 1 then
  rtx = RubyToXML.new
  rtx.main(ARGV[0])
end
#=RubyToXML
#
#Rubyソースからテストケースを作成するツール
#==ツールの概要
#RubyソースにコメントからTestLinkのテストケース用XMLを作成するツールです。
#Rubyソースに以下の形式でコメントを記述すると
#
## tltestcase:: テストケース名
## tlsummary:: テストの概要
## tlsteps:: テスト手順
## tlexpectedresults:: 期待される結果
## tlkeyword:: キーワード
## tlnotes:: キーワードの説明
#下記のXMLファイルを生成します。
#
#<?xml version="1.0" encoding="UTF-8"?>
#<testsuite name="sample1"><details><![CDATA[
#
#]]></details>
#<testcase name="テストケース名"><summary><![CDATA[
#テストの概要
#]]></summary><steps><![CDATA[
#テスト手順
#]]></steps><expectedresults><![CDATA[
#期待される結果
#]]></expectedresults>
#<keywords>
#<keyword name="キーワード">
#<notes><![CDATA[
#キーワードの説明
#]]></notes>
#</keyword>
#</keywords>
#</testcase>
#</testsuite>
#
#このXMLファイルをテストケースの編集->テストスイートのツリーを選択->テストスイートをインポート からインポートすることによりテストケースがTestLinkに追加されます。
#
#改訂履歴
#2007/12/12 0.1 garyo 新規作成
#2007/12/12 0.2 garyo コメント訂正
#2007/12/12 0.3 garyo RDoc用に@xxx yyy を xxx::yyyに変更

require 'csv2testcace'

class RtxTestcase

  TLtestcase=0
  TLsummary=1
  TLsteps=2
  TLexpectedresults=3
  TLkeyword=4
  TLnotes=5

  attr_accessor :data,:keyword

  def initialize
    @keyword=["tltestcase","tlsummary","tlsteps","tlexpectedresults","tlkeyword","tlnotes"]
    @data={}
    @keyword.each{|k|
      @data[k]=""
    }
  end

  def getdata(i)
    @data[@keyword[i]]
  end

  def self.tltestcase?(s)
    if /tltestcase::/ =~ s then
      true
    else
      false
    end
  end

  def readLine(s)
    if /::/ =~ s then
      @keyword.each{|k|
        if /#{k}::(.*)$/ =~ s then
          @data[k] = $1.strip
        end
      }
    end
  end

end


class RubyToXML
  
  attr_accessor :filename,:file,:testcase

  def initialize
  end

  def load_file(filename)
    @filename=filename
    open(filename,"r"){|f|
      @file=f.read
    }
  end

  def convert(str)
    ret=[]
    tc = nil
    lines=str.split("\n")
    lines.each{|line|
      if RtxTestcase::tltestcase?(line) then
        tc = RtxTestcase.new
        ret << tc
      end
      tc.readLine(line) if tc
    }
    ret
  end

  def main(filename)
    load_file(filename)
    ret = convert(@file)

    cx=Csv2testcase.new
    cx.useTitleLine = false
    wrfile = File.dirname(filename) + "/" + File.basename(filename, ".*") + ".xml"
    testSuiteName = File.basename(filename, ".*")
    
    cx.initTestSuite(testSuiteName,"")

    ret.each{|r|
      ky=[]
      ky[0]=r.getdata(RtxTestcase::TLkeyword)
      ky[1]=r.getdata(RtxTestcase::TLnotes)
      cx.addTestcase(r.getdata(RtxTestcase::TLtestcase),r.getdata(RtxTestcase::TLsummary),r.getdata(RtxTestcase::TLsteps),r.getdata(RtxTestcase::TLexpectedresults),ky)
    }
    cx.writeFile(wrfile)
  end
end

if ARGV.size == 1 then
  rtx = RubyToXML.new
  rtx.main(ARGV[0])
end

csv2testcace.rb

#! /usr/local/bin/ruby -Ks
# csv2testcase
# csv -> testcase converter
# 
# 2007/09/28 0.00 garyo release 
# 2007/09/29 0.01 garyo allpairs2testcaseから使えるように変更
# 2007/10/29 0.02 garyo GUIを追加
# 2007/10/29 0.03 終了時のメッセージ変更。メニューを追加
# 2007/11/26 0.04 garyo keyword対応

require 'csv'
require 'kconv'
class TestCase
  attr_accessor :name,:summary,:steps,:expectedresults,:keyword
  def initialize(name,summary,steps,expectedresults,keyword)
    @name=Kconv.toutf8(name)
    @summary=Kconv.toutf8(summary)
    @steps=Kconv.toutf8(steps)
    @expectedresults=Kconv.toutf8(expectedresults)
    @keyword = keyword.map!{|x|Kconv.toutf8(x)}
  end
  def getXML
    @xml =  "<testcase name=\"#{name}\">"
    @xml += "<summary><![CDATA[\n#{summary}\n]]></summary>"
    @xml += "<steps><![CDATA[\n#{steps}\n]]></steps>"
    @xml += "<expectedresults><![CDATA[\n#{expectedresults}\n]]></expectedresults>\n"
    @xml += convKeyword(@keyword) if @keyword.size > 0
    @xml += "</testcase>\n"
    @xml
  end
  def convKeyword(k)
    ret ="<keywords>\n"
    n = k.size/2
    n.times{|i|
      if k[i * 2] != nil then
        k[i * 2 + 1] ="" if k[i * 2 + 1] == nil
        ret += "<keyword name=\"#{k[i * 2]}\">\n"
        ret += "<notes><![CDATA[\n#{k[i * 2 + 1]}\n]]></notes>\n"
        ret += "</keyword>\n"
      end
    }
    ret += "</keywords>\n"
  end
end

class TestSuite
  attr_accessor :name,:details,:testcase,:testsuite
  @name
  @details
  @testcase
  @testsuite
  @xml
  def initialize(name,details)
    @name=Kconv.toutf8(name)
    @details=Kconv.toutf8(details)
    @testcase=[]
    @testsuite=[]
  end
  def addTestCase(t)
    @testcase << t
  end
  def addTestSuite(t)
    @testsuite << t
  end
  def getXML
    @xml="<testsuite name=\"#{name}\"><details><![CDATA[\n#{details}\n]]></details>\n"
    @testcase.each{|s| @xml = @xml + s.getXML}
    @testsuite.each{|s| @xml = @xml + s.getXML}
    @xml=@xml + "</testsuite>\n"
    @xml
  end
end

class AllTestSuite
  attr_accessor :testsuite
  @testsuite
  def initialize(ts)
    @testsuite=ts
  end
  def getXML
    @xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    @xml=@xml + @testsuite.getXML
    @xml
  end
end


class Csv2testcase
  Name = 0
  Summary = 1
  Steps = 2
  Expectedresults = 3
  Keyword = 4
  attr_accessor :useTitleLine

  @testsuite
  def initialize
  end

  def initTestSuite(name,details)
    @testsuite=TestSuite.new(name,details)
  end

  def addTestcase(name,summary,steps,expectedresults,keyword)
      s=TestCase.new(name,summary,steps,expectedresults,keyword)
      @testsuite.addTestCase(s)
  end

  def readFile(infile)
    csv = CSV.open(infile, 'r')
    csv.each_with_index {|line, i|
      line.each{|d|d = "" if d == nil}
      if i == 0 and @useTitleLine == true then
        #skip title line
      else
        addTestcase(line[Name],line[Summary],line[Steps],line[Expectedresults],line[Keyword..-1])
      end
    }
  end

  def writeFile(outfile)
    f = File.open(outfile,"w")
    ats=AllTestSuite.new(@testsuite)
    f.puts ats.getXML
    f.close
  end

  def convCvs2Testcase(infile,outfile,testSuiteName)
    initTestSuite(testSuiteName,"")
    readFile(infile)
    writeFile(outfile)
  end
end

test/test_rubytoxml.rb

#
#=RubyToXML UnitTest
#
# Author::    garyo  (mailto:garyohosu@gmail.com)
# Copyright:: Copyright (c) 2007 garyo
# License::   GPL
$LOAD_PATH << File.dirname(__FILE__) + '/..'
require 'test/unit'
require '../rubytoxml'
require 'FileUtils'

#RubyToXMLのテスト
class Test_RubyToXML < Test::Unit::TestCase

  def setup
    @obj = RubyToXML.new
  end

  # tltestcase:: 読み込みファイル名確認
  # tlsummary:: ファイルを読み込む
  # tlsteps:: ファイル名を指定しファイルを読み込む
  # tlexpectedresults:: ファイル名が設定されること
  # tlkeyword:: FILE
  # tlnotes:: ファイル関連
  def test_load_file_title()
    tf="testfile.txt"
    open(tf,"w"){|f|
      f.puts "test"
    }
    @obj.load_file(tf)
    assert_equal(tf,@obj.filename)
    FileUtils.rm([tf]) 
  end

  # tltestcase:: 読み込みファイル確認
  # tlsummary:: ファイルを読み込む
  # tlsteps:: ファイル名を指定しファイルを読み込む
  # tlexpectedresults:: 読み込んだファイルの値が正しいこと
  # tlkeyword:: FILE
  # tlnotes:: ファイル関連
  def test_load_file()
    tf="testfile.txt"
    tt="test\ntest2"
    open(tf,"w"){|f|
      f.puts tt
    }
    @obj.load_file(tf)
    assert_equal(tt,@obj.file.chop)
    FileUtils.rm([tf]) 
  end

  # tltestcase:: テストケース変換確認1件
  # tlsummary:: テストケースを読みだすこと
  # tlsteps:: 変換元テキストを与える
  # tlexpectedresults:: 正しくテストケースが返ること
  # tlkeyword:: CONVERT
  # tlnotes:: 変換関連
  def test_convert_1()
    a=[]

    a[0]="tltestcase1"
    a[1]="tlsummary1"
    a[2]="tlsteps1"
    a[3]="tlexpectedresults1"
    a[4]="tlkeyword1"
    a[5]="tlnotes1"

    pf="::"

    testString="# tltestcase#{pf} #{a[0]}\n# tlsummary#{pf} #{a[1]}\n# tlsteps#{pf}  #{a[2]}\n# tlexpectedresults#{pf} #{a[3]}\n# tlkeyword#{pf} #{a[4]}\n# tlnotes#{pf} #{a[5]}\n"
    bb=@obj.convert(testString)

    if bb then
      bb.each{|b|
        a.each_with_index{|c,i|
          assert_equal(c,b.getdata(i))
        }
      }
    end
  end

  # tltestcase:: テストケース変換確認10件
  # tlsummary:: テストケースを読みだすこと
  # tlsteps:: 変換元テキストを与える
  # tlexpectedresults:: 正しくテストケースが返ること
  # tlkeyword:: CONVERT
  # tlnotes:: 変換関連
  def test_convert_n()

    n=10

    testString=""
    aa=[]
    n.times{|i|
      a=[]

      a[0]="tltestcase#{i}"
      a[1]="tlsummary#{i}"
      a[2]="tlsteps#{i}"
      a[3]="tlexpectedresults#{i}"
      a[4]="tlkeyword#{i}"
      a[5]="tlnotes#{i}"

      pf="::"

      testString += "# tltestcase#{pf} #{a[0]}\n# tlsummary#{pf} #{a[1]}\n# tlsteps#{pf}  #{a[2]}\n# tlexpectedresults#{pf} #{a[3]}\n# tlkeyword#{pf} #{a[4]}\n# tlnotes#{pf} #{a[5]}\n"
      aa << a
    }
   
    bb=@obj.convert(testString)
    
    aabb=aa.zip(bb)

    aabb.each{|a,b|
      a.each_with_index{|c,i|
        assert_equal(c,b.getdata(i))
      }
    }
  end
  
  # tltestcase:: ファイル名変換確認
  # tlsummary:: 正しくファイル名を変換すること
  # tlsteps:: 変換元ファイル名を設定
  # tlexpectedresults:: 正しくファイル名が変換・保存されること
  # tlkeyword:: FILE
  # tlnotes:: ファイル関連
  def test_conv_name_file()
    @obj.main("test_rubytoxml.rb")
    r = FileTest.exist? "test_rubytoxml.xml"
    assert(r)
    FileUtils.rm(["test_rubytoxml.xml"]) 
  end  

  # tltestcase:: ファイル変換確認
  # tlsummary:: 正しくファイルを変換すること
  # tlsteps:: 変換元ファイルを設定
  # tlexpectedresults:: 正しくファイルが変換・保存されること
  # tlkeyword:: FILE
  # tlnotes:: ファイル関連
  def test_conv_file()
    @obj.main("sample.rb")
    r = FileTest.exist? "sample.xml"
    assert(r)

    open("sample.xml"){|f1|
      open("sample_comp.xml"){|f2|
        assert_equal(f1.gets,f2.gets)
      }
    }
    FileUtils.rm(["sample.xml"]) 
  end  

end

gan2gan22007/12/12 15:15浅いコピーと深いコピーの違いは気付きにくいところですよね。
僕もそのうちうっかりしてハマってそうです(;゚Д゚)

garyogaryo2007/12/12 15:26gan2さん、こんにちは。思いっきりはまりました(^^;)
全然わからなかったのですが、gan2さんのページ読んでわかりました。

トラックバック - http://ruby.g.hatena.ne.jp/garyo/20071212

2007-01-19

PStoreを使った1行掲示版

| 11:39 | PStoreを使った1行掲示版 - Rubyの魔神 を含むブックマーク はてなブックマーク - PStoreを使った1行掲示版 - Rubyの魔神 PStoreを使った1行掲示版 - Rubyの魔神 のブックマークコメント

#!/usr/bin/ruby
require "cgi"
require "pstore"

class Message
  @time
  @msg
  attr_accessor :time, :msg
  def initialize(t,s)
    @time = t
    @msg = s
  end
end

print "Content-Type: text/html\n"
print "\n"

day = Time.new

cgi = CGI.new

mb=[]

db = PStore.new("messagelog")
m = Message.new(day.to_s,cgi['test'])

db.transaction{
  if db["msg"] == nil then
    db["msg"]=mb
  else
    mb = db["msg"]
  end
  mb.push(m)
  db["msg"] = mb
}

print <<EOF
<html>
<head></head>
<body>
<form method=POST action="./comment.cgi">
<input type="text" name="test" value="">
</form>
EOF
mb.reverse.each do |s|
  print "#{s.time}  #{s.msg}<BR>"
end

print <<EOF
</body>
</html>
EOF
トラックバック - http://ruby.g.hatena.ne.jp/garyo/20070119

2007-01-18

PStore例

| 17:53 | PStore例 - Rubyの魔神 を含むブックマーク はてなブックマーク - PStore例 - Rubyの魔神 PStore例 - Rubyの魔神 のブックマークコメント

簡易DBとして使えるのかな

require 'pstore'

db=PStore.new("pstest")
db.transaction{
  db["key"]=[[1,2,3],{1=>2},0,[[1,2],4],"test"]
}

db.transaction{
  p db["key"]
}
トラックバック - http://ruby.g.hatena.ne.jp/garyo/20070118

2006-12-26

MantisのCSV出力のデータを変換

| 19:23 | MantisのCSV出力のデータを変換 - Rubyの魔神 を含むブックマーク はてなブックマーク - MantisのCSV出力のデータを変換 - Rubyの魔神 MantisのCSV出力のデータを変換 - Rubyの魔神 のブックマークコメント

変換内容

文字コード UTF→SJIS

日付 月-日-年 → 年/月/日

Mantis側のPHPをいじれとか言わないように

require "kconv"

class BugList
  Id=0			#Id
  Project=1		#プロジェクト
  Toroku_sya=2		#登録者
  Tanto_sya=3		#担当者
  Yusendo=4		#優先度
  Juyodo=5		#重要度
  Saigensei=6		#再現性
  Version=7		#製品バージョン
  Syusei=8		#修正方法
  Category=9		#カテゴリ
  Toroku=10		#登録日
  Yotei_kosu=11		#予定工数
  OS=12			#OS
  Version2=13		#バージョン
  Plathome=14		#プラットフォーム
  Sansyo=15		#外部からの参照
  Koshin=16		#最終更新日時
  Yoyaku=17		#要約
  Status=18		#ステータス
  Jokyo=19		#解決状況
  Syusei_version=20	#修正済みバージョン

  def convDateFormat(s)
    s[6..7]+"/"+s[0..1]+"/"+s[3..4]
  end

  def initialize(f)
    @filename=f
  end

  def save(outf)
    f1=File.open(@filename)
    f2=File.open(outf,"w")
    while line=f1.gets
      a = Kconv.tosjis(line)
      b = a.split(",")
      if b[0] != "Id" then
        b[Toroku] = convDateFormat(b[Toroku])
        b[Koshin] = convDateFormat(b[Koshin])
      end
      c=b.join(",")
      f2.puts(c)
    end
  end
end

b=BugList.new("project_id_0000000001.csv")
b.save("sproject_id_0000000001.csv")
トラックバック - http://ruby.g.hatena.ne.jp/garyo/20061226