ラベル ruby の投稿を表示しています。 すべての投稿を表示
ラベル ruby の投稿を表示しています。 すべての投稿を表示

2013年6月25日火曜日

ruby date 比較


$ irb
irb(main):001:0> require 'date'
=> true
irb(main):002:0> from = Date::strptime('2013-01-01', '%Y-%m-%d')
=> #
irb(main):004:0> to = Date::strptime('2013-01-02', '%Y-%m-%d')
=> #
irb(main):005:0> same = Date::strptime('2013-01-02', '%Y-%m-%d')
=> #
irb(main):006:0> from > to
=> false
irb(main):007:0> from < to => true
irb(main):008:0> to == same
=> true

2013年6月20日木曜日

rubyでFTPからCSV(?)をゲットして、DBに突っ込む

ftp.yml

remote_path: pub/test
retry: 3
host: 192.168.1.70
username: anonymous
password: anonymous


get_ftp.rb
sample usage: # ruby get_ftp.rb index_hist
will get 'index_hist.gz' from ftp and gunzip it to index_hist
require 'net/ftp'
require 'yaml'
cnt_retry = 0
puts "start process..."
begin
  ftp_cfg = YAML.load_file("ftp.yml")
  fn = ARGV[0]

  ftp = Net::FTP.open(ftp_cfg["host"])
  ftp.login(ftp_cfg["username"],ftp_cfg["password"])
  ftp.chdir(ftp_cfg["remote_path"])
  puts "getting #{fn}.gz from FTP for attempt #{cnt_retry}..."
  ftp.getbinaryfile("#{fn}.gz")
  system("gunzip -f #{fn}.gz")
  ftp.close
rescue => err
  if cnt_retry + 1 < 3
    cnt_retry += 1
    sleep 5
    retry
  else
    raise err
    log.error "There was an error: #{err.message}"
  end
else
  puts "Job done."
end
import to a mysql database db.yml host: 192.168.1.70
username: kagen
password: kagen
database: db_development
import_indices.rb
sample usage1: # ruby import_indices.rb master index_master
will import data from index_master into table 'indices'
sample usage2: # ruby import_indices.rb hist index_hist
will import data from index_hist into table 'index_value_hist'
require 'yaml'
require 'kconv'
require 'mysql'
puts "start process of data import..."
begin
  my = Mysql::init()
  db_cfg = YAML.load_file("db.yml")
  if ARGV[0] == "master"
    tbl = "indices"
    fld = "(itemcode, jpname, engname, jpsourcename, engunitname, unit, decimalpoint, startmonth, updated_at)"
  else
    tbl = "index_value_hist"
    fld = "(itemcode, subcode, cycle, yyyy, mm, dd, val, updated_at)"
  end
  puts "Connecting to host #{db_cfg["host"]} with user #{db_cfg["username"]} using database #{db_cfg["database"]}..."
  my.real_connect(db_cfg["host"], db_cfg["username"], db_cfg["password"], db_cfg["database"])
  puts "Connected Successfully"
  my.query("SET AUTOCOMMIT=0")
  puts "Start transaction..."
  my.query("START TRANSACTION")
  if ARGV[0] == "master"
    puts "Processing Index master"
  elsif ARGV[0] == "hist"
    puts "Processing Index values history"
  end

  begin
    File.open(ARGV[1]) do |f|
      f.each_line do |row|
        sql = nil
        rows = row.split(":")
        #puts rows.inspect
        if ARGV[0] == "master"
          sql = "INSERT INTO #{tbl} #{fld} VALUES('#{rows[0]}', '#{rows[1].toutf8}', '#{rows[2]}', '#{rows[3].toutf8}', '#{rows[4].toutf8}', '#{rows[5]}', '#{rows[6]}', '#{rows[7]}', CURRENT_TIMESTAMP)"
        elsif ARGV[0] == "hist"
          if rows[3] == "D"
            if rows[0].strip == "DEL"
              sql = "DELETE FROM #{tbl} WHERE itemcode = '#{rows[1].strip}' AND subcode = '#{rows[2].strip}' AND cycle = 'D' AND yyyy = '#{rows[4][0..3]}' AND mm = '#{rows[4][4..5]}' AND dd = '#{rows[4][6..7]}'"
            elsif rows[0].strip == "UPD"
              sql = "INSERT INTO #{tbl} #{fld} VALUES('#{rows[1].strip}', '#{rows[2].strip}', 'D', '#{rows[4][0..3]}', '#{rows[4][4..5]}', '#{rows[4][6..7]}', '#{rows[5]}', CURRENT_TIMESTAMP)"
            end
          elsif rows[3] == "M"
            if rows[0].strip == "DEL"
              sql = "DELETE FROM #{tbl} WHERE itemcode = '#{rows[1].strip}' AND subcode = '#{rows[2].strip}' AND cycle = 'D' AND yyyy = '#{rows[4][0..3]}' AND mm = '#{rows[4][4..5]}'"
            elsif rows[0].strip == "UPD"
              sql = "INSERT INTO #{tbl} #{fld} VALUES('#{rows[1].strip}', '#{rows[2].strip}', 'M', '#{rows[4][0..3]}', '#{rows[4][4..5]}', '', '#{rows[5]}', CURRENT_TIMESTAMP)"
            end
          end
        end
        if sql
          #puts sql
          my.query(sql)
        end
      end
    end
    my.query("COMMIT")
  rescue => err
    puts "rollback changes..."
    my.query("ROLLBACK")
    raise err
    log.error "There was an error while insert db: #{err.message}"
  end
rescue => err
  raise err
  log.error "There was an error: #{err.message}"
else
  puts "Job done."
end
create tabless CREATE TABLE `indices` (
`itemcode` varchar(15) NOT NULL ,
`jpname` varchar(30) NOT NULL ,
`engname` varchar(28) NOT NULL ,
`jpsourcename` varchar(32) NOT NULL ,
`jpunitname` varchar(30) NOT NULL ,
`engunitname` varchar(30) NOT NULL ,
`unit` int(8) NOT NULL ,
`decimalpoint` int(8) NOT NULL ,
`startmonth` int(8) NOT NULL ,
`updated_at` datetime NOT NULL ,
PRIMARY KEY (`itemcode`)
) type=InnoDB;
CREATE TABLE `index_value_hist` (
`itemcode` varchar(15) NOT NULL ,
`subcode` varchar(5) NOT NULL ,
`cycle` varchar(1) NOT NULL ,
`yyyy` varchar(4) NOT NULL ,
`mm` varchar(2) NOT NULL ,
`dd` varchar(2) NOT NULL ,
`val` double(24,7) NOT NULL ,
`updated_at` date NOT NULL ,
PRIMARY KEY (`itemcode`, `subcode`, `cycle`, `yyyy`, `mm`, `dd`)
) type=InnoDB;
Sample Data to import (EUC, LF) No title row ☆index_value_hist only☆ UPD :AREGEN :A :M:201212:150463.7400000:20121218
UPD :AREGEN :C :M:201212:158030.9800000:20121218
UPD :AREGEN :C :W:2012124:158030.9800000:20121218
UPD :AREGEN :H :M:201212:158030.9800000:20121218
...

2012年3月1日木曜日

railsコンソールでモデルのfindメソッドで関節的に関係を持つデーブルへのアクセス

3つのテーブルそれそれ下記の関係

tmp_fund_index ○----● fund ●----○ fund_ranking

#models/fund.rb
class Fund < ActiveRecord::Base
  has_many :fund_rankings
end

#models/fund_ranking.rb
class FundRanking < ActiveRecord::Base
  belongs_to :fund
end

#models/tmp_fund_index.rb
class TmpFundIndex < ActiveRecord::Base
  belongs_to :fund
end
まずコンソールで確認すると、出ました $ ruby script/console Loading development environment.
>> FundRanking.find(:all, :limit => 1, :include => [:fund => [:tmp_fund_index]])
コントローラでは
#controllers/fund/ranking_controller.rb
  @rank_dtl = FundRanking.find :all,
                               :include => [{:fund => :tmp_fund_index}],

ビューアーでは、こうやって参照できる
#views/fund/ranking/detail.rhtml
<%- if @rank_dtl -%>
  <%- @rank_dtl.each_with_index do |rank, idx| -%>
    <%= rank.fund.tmp_fund_index.standard_price %>
  <%- end -%>
<%- end -%>

2011年12月30日金曜日

前回(サーバからcsvを複数取得する)の続きに、取得したcsvをDBにinsertする

app/libの下にprice_importer.rbを作成し、app/で実行する

$ ruby script/runner PriceImporter.execute

以下の内容
require 'csv'
class PriceImporter
  class << self
    def execute()
      begin
          result = system("/path/to/script/getfile.sh")  #←<a href="http://kagen88.blogspot.com/2011/12/shelllftp.html">前回作成したshellスクリプト</a>
          print result
          Dir::glob("/path/to/data/*.csv").each {|f|  #←取得したcsvファイルを保存する場所の(すべての?)csvをループ
            puts "#{f}: #{File::stat(f).size} bytes"  #←サイズを表示してみる
            cf=File.open(f,"r")  #←開く
            buf=cf.read()  #←読む
            @parsed_file = CSV::Reader.parse(convertSjis2UTF8(buf))  #←CSVハッシュに格納、その前にsjisをutf8に
            @parsed_file.shift  #←最初のタイトル行をスキップ
            @parsed_file.each  do |row|
              pd = Product.find_by_code(row[0])  #←既存のテーブルモデルを使って、コードの有無を確認
              if pd
                Price.delete_all "pd_id = " + pd.id.to_s + " AND base_date_on = '" + row[4] + "'"  #←上書きしたいので、一致したレコードを削除
                p = Price.new
                p.pd_id = pd.id
                p.base_date_on = row[4]
                p.price = row[5]
                p.save  #←インサート
              else
                RAILS_DEFAULT_LOGGER.debug("コード(" + row[0] + ")がproductsテーブルに存在しない。ご確認ください。")
                puts "コード(" + row[0] + ")がproductsテーブルに存在しない。ご確認ください。"
              end
            end
          }
      rescue => e
        RAILS_DEFAULT_LOGGER.debug(e)
        raise
      end
    end
    def convertSjis2UTF8(val)←utf8変換
      val.kconv(Kconv::UTF8, Kconv::SJIS) unless val.blank?
    end
  end
end
以上

2011年12月20日火曜日

CentOS6(64bit)にHTML+CSSをPDFに変換するprince8

railsのプロジェクトでHTML+CSSをPDFに変換する必要がありました。
ApacheのFOPがありました。無料ですが、それはHTMLとCSSではなくXSL-FO(XML)からPDFに変更するというものでした。しかもいろいろできないことが有るみたい(文字を画像の回り込みなど)。
さらに調べたら、princeがあって、HTML+CSSをPDFに変換できる。特徴はいろいろ、かなりイケてる感じ
1.各プラットフォームに対応http://www.princexml.com/download/
2.PDFファイルの出力は当然ですが、標準出力も対応
3.テーブルの中でページが割れないように設定できる
4.ヘッダー、フッター、ページナーンバー
5.大きくしてもボヤけないSVGの読み込みが対応
6.いろんな言語のWrappersがある(Java/Python/Perl/PHP/VB....)⇒rubyがない…でも大丈夫みたい
取り敢えずインストールしてみる

$ cat /etc/redhat-release
CentOS Linux release 6.0 (Final)
$ uname -a
Linux localhost.localdomain 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

OSはCentOS6(64bit)みたい。
ここからダウンロード
RHEL5: CentOS 5.5 / 64-bit
prince-8.0-1.centos55.x86_64.rpm

$ cd ~/download
$ wget http://www.princexml.com/download/prince-8.0-1.centos55.x86_64.rpm

普通にインストールしたら怒られた、openssl64bitはちゃんとあるのに

$ sudo rpm -ivh prince-8.0-1.centos55.x86_64.rpm
エラー: 依存性の欠如:
libcrypto.so.6()(64bit) は prince-8.0-1.x86_64 に必要とされています
libcurl.so.3()(64bit) は prince-8.0-1.x86_64 に必要とされています
libexpat.so.0()(64bit) は prince-8.0-1.x86_64 に必要とされています
libfontconfig.so.1()(64bit) は prince-8.0-1.x86_64 に必要とされています
libfreetype.so.6()(64bit) は prince-8.0-1.x86_64 に必要とされています
libgif.so.4()(64bit) は prince-8.0-1.x86_64 に必要とされています
libjpeg.so.62()(64bit) は prince-8.0-1.x86_64 に必要とされています
libpng12.so.0()(64bit) は prince-8.0-1.x86_64 に必要とされています
libpng12.so.0(PNG12_0)(64bit) は prince-8.0-1.x86_64 に必要とされていま す
libssl.so.6()(64bit) は prince-8.0-1.x86_64 に必要とされています
libtiff.so.3()(64bit) は prince-8.0-1.x86_64 に必要とされています
libungif.so.4()(64bit) は prince-8.0-1.x86_64 に必要とされています
[kagen@localhost download]$ rpm -qa | grep openssl-devel
openssl-devel-1.0.0-4.el6_0.2.x86_64

検索したら、ここにたどり着いた。同じ困っている人がいた。http://www.princexml.com/bb/viewtopic.php?f=2&t=7021
8.1から対応してくれそうです。

$ wget http://www.princexml.com/download/prince-8.0-linux-amd64-static.tar.gz
....
$ tar xzvf prince-8.0-linux-amd64-static.tar.gz
....
$ cd prince-8.0-linux-amd64-static
$ sudo ./install.sh
[sudo] password:
Prince 8.0

Install directory
This is the directory in which Prince 8.0 will be installed.
Press Enter to accept the default directory or enter an alternative.
[/usr/local]:⇒ブランクのままエンター

Installing Prince 8.0...
Creating directories...
Installing files...

Installation complete.
Thank you for choosing Prince 8.0, we hope you find it useful.
Please visit http://www.princexml.com for updates and development news.
$ prince --version
Prince 8.0
Copyright 2002-2011 YesLogic Pty. Ltd.
Non-commercial License

取り敢えずインストール出来たみたい。

2011年11月10日木曜日

railsのscaffoldで作成したcontrollerが余計のお世話をする

railsのscaffoldを作成したら、controllerでactionを追加したら、actionをidとして探してしまうという余計のお世話は、実はscaffoldの仕業
rorr(ruby on rails rookie)の私にyuoさんがいろいろ教えてくれてありがとうございました。

$ rails anydesign -d mysql #まずはプロジェクト作成(データベースはmysql)
$ cd anydesign
$ rake db:create #DB作成
$ ruby script/generate scaffold report title:string header:text body:text footer:text #scaffoldで簡単なreport機能を作成
$ rake db:migrate #DBを更新
$ ruby script/server #サーバを立ててみる

ブラウザーでhttp://localhost:3000/を叩いたら、タイムアウト…
調べたら、iptables(firewall)がオンになってる

$ sudo service iptables status #状態を調査する
$ sudo service iptables stop #やっぱりオンになってるから、止める

もう一回ブラウザーでhttp://localhost:3000/を叩いたら、出ました。on rail...
先作ったscaffoldで作ったreportを見てみるhttp://localhost:3000/report
あ!ちゃんと空の一覧が出来ました、便利。
一覧、新規、変更、削除一応全部できる。取り敢えず
title, header, body, footerを入れて、一レコードを作りました。
そして、controllerで新しいaction、「test」を追加しました、空のaction
in reports_controller.rb

def test
end

http://localhost:3000/report/testを叩いたら、[ActiveRecord::RecordNotFound (Couldn't find Report with ID=test):]という
エラーが出来ました、なぜaction名がidに無理やりも当てるの?railsの大きなお世話だね、yuoさんが教えてくれた
scaffoldで作成するとき、config/routes.rbで

map.resources :reports

を追加してくれたので、こうなった、一番簡単なのはこの一文を削除すればいいですが、config/routes.rbで

map.resources :reports, :only => ['create','show'] #適応actionを絞る
あるいは
map.resources :reports, :except=> ['test'] #action testを除外する

でもいいらしい。

2011年8月26日金曜日

Ruby on Rails DateTimeやTimeオブジェクトの比較謎

データベースにavailable_toというdatetime型のフィルドがあります
active recordのfindメッソドを使って取り出した時は値の型は何でしょうか?

railsのバージョンによるかもしれないが、少なくでもrails1.16ではDateTime
やTimeオブジェクトと直接比較できなかった、謎!


if rec.available > DateTime.now
comparison of Time with DateTime failed
怒られました!なんで??
findメソッドを経由して、型が変わった?そんなわけないだろう...
取り敢えずこうして見る
if rec.available > Time.now
comparison of DateTime with Time failed
え?!冗談でしょう!
...仕方がない、最後の一撃!
if rank.fund.available_to.to_s.to_date > DateTime.now.to_s.to_date
やっと出来た...激汚いですけど

仕方がない、そして謎が一杯残ってます...
取り敢えず忘れよう。うん!

RailsのactiveRecordのfindメッソドで複数テーブル(Join)からクエリー

fund(1)<------>(*)fund_ranking
fundとfund_rankingは一対多の関係です。キーはfund_rankingsテーブルのfund_id
まずはmodelsでそれぞれ関係を作りましょう
fund.rbに追加
has_many :fund_rankings #ここは複数形
fund_ranking.rbに追加
belongs_to :fund #ここは単数形
ここで単数複数を間違うとActiveRecord::ConfigurationError と怒られる
コントローラー側 fund/ranking_controller.rb
@pcipu1m = FundRanking.find :all,
               :conditions => ["yyyymm = ? and period = '1m'", @yyyymm.yyyymm],
               :include => [:fund], #ここでfundsテーブルをインクルード
               :order => "rank asc",
               :limit => 10
ビュー側 fund/ranking/index.rhtml
<%- if @pcipu1m.size > 0 -%>
<%- @pcipu1m.each_with_index do |rank, idx| -%>
    第<%= rank.rank %>位 #fund_rankingsのrank
    銘柄名:<%= rank.fund.name %> #fundsのname
<%- end -%>
<%- end -%>
まぁ、私みたいなror超初心者の参考のために(。・ω・。)





2011年7月6日水曜日

Rubyで月末を取得

railsなどは直接Dateオブジェクト使えますが、Ironrubyなどはまずrequire

>>> require 'date'
=> true


ある日の月末
yyyymmdd

>>> ((Date.parse('20110501') >> 1)-1).strftime("%Y%m%d")
=> "20110531"


yyyy/mm

>>> ((Date.parse('2011/05') >> 1)-1).strftime("%Y%m%d")
=> "20110531"


本日

>>> ((Date.today >> 1)-1).strftime("%Y%m%d")
=> "20110805"

2011年1月13日木曜日

Ruby 1.8.6 インストール on CentOS with Yum

引用元

Ruby 1.8.6 インストール(32-bit)

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
# rpm -Uvh http://download.elff.bravenet.com/5/i386/elff-release-5-3.noarch.rpm
# yum install ruby ruby-shadow ruby-ri ruby-rdoc gcc gcc-c++ ruby-devel -y
...
Complete!
# ruby -v
ruby 1.8.6 (2010-02-05 patchlevel 399) [i386-linux]


RubyGems 1.3.7 インストール

# wget http://rubyforge.org/frs/download.php/70696/rubygems-1.3.7.tgz
# tar xzvf rubygems-1.3.7.tgz
# cd rubygems-1.3.7
# sudo ruby setup.rb
...
# gem --version
1.3.7


Rails 1.2.3 インストール

# gem install rails -v1.2.3
...
# rails -v
Rails 1.2.3

2011年1月7日金曜日

ruby on railsのweb service mongrel

最近ruby on railsで開発しています。
web serverはrails標準付いているmongrelです。

Rails Shellでサーバを起動します。RailsのデフォルトのDocumentRootは [pulic]が、今回のプロジェクトは[htdocs]
-rでDocumentRootを指定できる

mongrel_rails start -e development -a 127.0.0.1 -p 3009 -r 'C:\path\proj\www.projname.com\htdocs'


また、ソースコードで変更があった場合、controllerやviewは問題ないですが、modelの変更なら、必ずweb serviceを
再起動しないと反映されないです。何回もこれでやられ、時間を無駄にした T_T

2010年12月16日木曜日

クラスとモジュールの違い

引用元:http://www.rubylife.jp/ini/module/index1.htmlhttp://www.rubylife.jp/ini/module/index1.html

モジュールはクラスと同じくメソッドを定義する事が出来ます。クラス変数に相当するものはモジュールにはありませんが定数は定義する事が出来ます。

このようにモジュールはクラスに非常に似た構成を持っていますが大きな違いとしてクラスはクラスからオブジェクトを作成することが出来ますがモジュールでは作成することは出来ません。モジュールの利用方法としては「モジュール名.メソッド名」の形式で関数のように実行するか、または他のクラスの中にインクルードして利用することが出来ます。

クラスでは継承をサポートしており1つの基幹クラスを継承して複数のクラスを作成する事が出来ます。これによって同じような機能を持つクラスを別々に1から作成する必要はありません。ただ、同じ様な機能が必要だったとしてもまったく別の目的のクラスである場合はクラスの継承によって共通化する部分を作成するにはおかしい場合があります。そのような場合に共通となる機能をモジュールとして定義し、各クラスにインクルードして利用することでコードの再利用性を高めることができます。

感想:
クラスができることの一部は、モジュールもできます(メソードや定数)が、使い分けは原則上の言い方だと私的に結構すーっと入りますね