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

2023年6月1日木曜日

自分のホームページのコードをリファクタリングしたので感想

自分のホームページのコードをリファクタリングしたので感想

ホームページはこちら

コード概要

  • Ruby + Sinatra
  • redis

エディタは emacs で solargraph + robe で開発しています

リファクタ方針

  • ハッシュベースのルーティング定義をクラス化
  • rubocop の導入
  • TwitterAPI v2 への対応

クラス化について

routing = {
  '/about': {
    tpl: :about
  },
  '/apps': {
    tpl: :apps
  }
}

...

routing.each do |path, info|
  get path do
    # パスに応じて特定の処理をする場合は分岐
    erb info[:tpl]
  end
end

こんな感じでハッシュで定義してループで動的にルーティングを定義していたのを

class AboutPage < Sinatra::Base
  def initialize
    @path = '/about'
    @tpl = :about
  end

  def routing
    AboutPage.get @path do
      erb @tpl
    end
  end
end

こんな感じでクラスベースにして Rack::URLMap.new に設定します

メリット

  • ルーティングごとに分岐しなければいけない処理が複雑化しない
  • xxxPage クラスの親クラスを作って共通処理を抽象化できる
  • もしくは Mix-in を使って処理を共通化し特定のページでのみ使い回せる

デメリット

  • ルーティングを追加する際にクラスを追加しなければならない
  • ファイルが増える

rubocop について

基本は rubocop が出す警告などは全部対応します

基本辛いが特に辛い点

  • Metrics/MethodLength
  • Metrics/AbcSize

Method に限らず Block, Class, Module が長すぎるという警告に対応するのは大変です
個人的には以下のように対応しています

  • メソッドに分割
  • 抽象クラスの作成
  • One line 記述を使う
  • ハッシュなどのデータは外部ファイルに移動して JSON.parse(File.read('xx.json')) する

rubocop っぽいコードになる

特に以下のような記述が増えます

  • ガード
  • 細かいメソッドやモジュール、クラスに分割される
  • クエスチョンマークを使ったメソッドが増える
  • get set などを使ったメソッド名が消える
  • freeze がよく出る
  • __dir__ がよく出る
  • クラスやモジュールの先頭に必ずコメントが出てくる
  • do .. end or {} の使い方が明確になる
  • ハッシュは {key: 'value'} のような記述になる
  • ダブルクォートは使わなくなる
  • リテラルが増える

特に2つ目の細かいメソッドやモジュールへの分割ですがこれが個人的に何ともというか本当に良いコードになっているのか微妙でコードを読むときにいろいろなところにジャンプしなければいけないのが辛いかなと思っています
行は増えますが単純に上から処理を辿って行くだけで読み解くことができるコードのほうが自分は見やすいかなと思っています

rubocop は他の言語の linter に比べてかなり厳しい印象です

TwitterAPI v2 化について

古いアプリが pending され使えなくなっていたので新しく作り直したのと新しいアプリは v2 を使うようにしました (参考)

gem によっては v1.1 しか使っていないので v2 化していない部分は自作しました

全体通して

個人的にリファクタリングはテストを書くくらい嫌いです
理由はリファクタリングが直接利益につながることが少ないからです
また際限がなくどこまでもできてしまうのと人による好み (バイアス) により記述が変わるので正解がありません

今回のリファクタリングの目的はコードをキレイにしてメンテナンスしやすいコードにするというよりかは Ruby 力を高めるためにやりました

コードフォーマットについて

外部に公開しているコードは linter などを適用したほうがいいと思うのですが Ruby の場合いろいろな linter や formatter があるのでなかなか万人に共通するコードにするのは難しいかなと思います

また Sorbet や Tapioca など静的解析ツールがまだまだどうなるかわからないのでそれに追従すると特殊な記述がコード内にいろいろと現れます

lsp の登場による影響なのかもと思ったりしていますが最近は Type hint がやたら流行っている気がします
型があったほうが堅牢なコードにはなりやすいとは思います
ただ Ruby の場合 lsp のために (エディタのために) コード内に記述しなければいけないコードがあったりするのでそこは少し本質とは異なるので歯がゆいかなと思っています (実際になくても動くのであればないほうがいいのかなと)

Ruby の場合は無理して Type hint しなくてもいいのかなと思っています
Try & Error や Spec テストで補えばいいのかもしれません

テストについて

大規模リファクタリングをするときにテストがあるかないかで負荷がだいぶ変わってくる気がします
特にユニットテストではなく外部からテストするような運用テストなどがしっかり備わっているかどうかで大規模リファクタリングに踏み出せるかどうかが決まると言ってもおかしくないかなと思います

2018年11月3日土曜日

ホームページを自動デプロイできるようにしてみました

概要

久しぶりのテックネタの投稿です
自分のホームページ https://kakakikikeke.com は Ruby で書かれており docker コンテナとして動作しています
https に対応しているのですが内部で nginx コンテナも動いておりそこで SSL を受け付けています

デプロイは git push 後にホストマシンに SSH ログインして docker-compose build -> up という王道の流れなのですがいちいち SSH ログインするのが面倒でした
まぁコマンドも 2, 3 ほどなのでそこまで面倒な作業でもないのですが今回はそのデプロイ作業を自動化してみました

仕組みとしては bitbucket の webhook 機能を使ってホストマシンで webhook を受け取るアプリを起動します
そして、そのアプリに今まで実行していたデプロイコマンドを実行してもらうという何のひねりもない仕組みです

環境

  • CentOS 7.5
  • docker 18.06.1-ce
  • Ruby 2.5.0p0
  • bitbucket

bitbucket webhook にエンドポイントを追加する

まずは webhook にエンドポイントを追加します
homepage_autodeploy1.png

各リポジトリごとにエンドポイントを追加できます
今回はホストマシンでデプロイ用のアプリも動かします
Sinatra を使うので 9292 ポートに対して webhook を投げてもらうようにエンドポイントを追加します
/webhook にしていますがここは好きなものに変更してもらって OK です

スクショだと Enable request history collection にチェックがありませんがどんな webhook が飛んだかあとから確認したい場合はここにチェックを入れておくと履歴が確認できます

IP を許可

bitbucket のホワイトリスト IP は以下の通りです
ファイアウォールなどに設定の許可を入れましょう

  • 104.192.136.0/21
  • 34.198.203.127
  • 34.198.178.64
  • 34.198.32.85

今回の場合であれば 9292 ポートへのアクセスだけを許可すれば OK です

ライブラリインストール

ではアプリを作っていきます

  • bundle init
  • vim Gemfile
gem "sinatra"
  • bundle install --path vendor

webhook 用のアプリ

  • vim config.rb
require './app'
run Webhook
  • vim app.rb
require 'sinatra'
require 'json'
require 'open3'

class Webhook < Sinatra::Base
  helpers do
    def deploy
      File.open("./deploy.txt", mode = "r"){ |f|
        f.each_line{ |line|
          o, e, s = Open3.capture3(line)
          halt 500, "missed: #{e}" unless s.success?
        }
      }
    end
  end
  post '/webhook' do
    body = JSON.parse request.body.read
    p body
    body['push']['changes'].each { |push|
      deploy if push.has_key? 'new'
    }
    'deployed'
  end
end
  • vim deploy.txt
cd /root/ruby-homepage && git pull
cd /root/ruby-homepage && docker-compose down
cd /root/ruby-homepage && docker rmi rubyhomepage_web
cd /root/ruby-homepage && docker-compose up -d

少し解説

特に解説は不要かなと思いますが一応

まず POST /webhook が bitbucket から送られてくる webhook を受け取る URI になります
ここは bitbucket に設定したエンドポイントと同じ URI にしてください
ボディに push 時のいろいろな情報が格納されてきます
コミットした人やコミット番号などがあります
詳しくは上記のリンクからサンプルリクエストなどが確認できるます

今回は特に条件はないですが、new という新規のコミットがある場合にデプロイを実行するようにしました
new がないケースとしてはブランチを削除した場合になります
デプロイ時の条件を厳密にしたい場合はここに条件を加えれば OK です

deploy は helpers を使って実現しています
デプロイコマンドを書き連ねた deploy.txt を読み込み open3 で逐一実行してるだけです
open3 であればコマンドの結果 (0 とか 127 とか) をチェックできるので、もし成功じゃない場合は halt でエラーを返却します

クソ簡単です

アプリ起動

  • bundle exec rackup config.ru -o 0.0.0.0 &

外部から受付できるように 0.0.0.0 で LISTEN します
また、バックグラウンドで動作させるようにします
tmux バッファ上でフォアグラウンドで動作させても良いと思います
もっとちゃんとやるならデーモン化させたり systemd 配下で動かすようにしても良いと思います
停止するときはプロセス番号を調べて kill してください

という感じで開発自体は完了です
あとは push して挙動を確認したりしてみてください

デメリット

今回の場合、直接ホストに対してコマンドを実行するのでコンテナで動かすとコンテナ内にコマンドを実行してしまいます
なのでホストマシンに ruby + bundler をインストールしなければいけません
これまですべて docker で動かしていた環境にいきなり謎の勢力のためにバイナリをインストールしなければいけないのは納得いかない点があるかなと思います

また git pull をするときに認証されないことを想定しています
git-credential を使ってホストマシンに認証情報を保存していることが前提になっています (もしくは .git/config に ID/PW が書かれていても OK)

代替策

今回は webhook + コマンドにしましたが他にもいろいろな方法があると思います
例えば Bitbucket Pipeline を使う方法です
ここにコマンドを記載できるので push 後にホストに SSH してコマンドを実行することでデプロイすることも可能です
これであれば web アプリを作る必要もありません

あとはどうしても webhook 用のアプリをコンテナで動かしたい場合はコンテナからホストに SSH ログインしてコマンドを実行するか sidekiq などを使ってコンテナからホストにデプロイの支持を渡してそこからホスト側の worker でデプロイするなどでしょうか
ただ、これもコンポーネントが 1 つ増えるので微妙です

エージェントを配置してエージェントに指示を送る方法でもいいですが、今回の webhook アプリ方式とあまり変わらないかなと思います

そもそもイメージをお腹に抱えてしまっているのでそれもあまりよくない気がします
docker build -> docker push でどこかのレポジトリにアップロードして、ホストマシン側では pull -> up だけする感じのほうが良いかなと思います
ただ、その場合でも結局ホストマシン側でコマンドを実行する仕組みは必要かなと思います 

k8s の Deployment と ReplicaSet を使えばローリングアップデートが使えるのでそれも手かもしれません
ただその場合は k8s 環境の構築から必要になりますが、、

今回の方法はリポジトリからの push 型なのでそうでなくホストマシンからの pull 型で良い感じに簡単にできる仕組みにすると良いのかなと思います
やはりコマンドをホストマシンで直接実行するのは何か微妙なやり方なような気がします

むしろ何か良い代替策があれば教えていただきたいです

参考サイト

2015年2月20日金曜日

CentOSにRVMをインストール

概要

RVM(Ruby Version Manager) を今更ながらCentOSに入れて試してみました
すごい昔はyumでインストールしたりRubyの公式サイトから.tar.gzをダウンロードしてソースコンパイルしてインストールしていましたが、さすがに卒業しようかと思います

環境

  • CentOS 6.6 64bit (Final)
  • RVM 1.26.10
  • AutoConf 2.69

各種インストール作業

RVMインストール

rootで実施しました
ユーザは適当に変更してください

gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
echo 'export PATH=$PATH:/usr/local/rvm/bin' >> /root/.bashrc
source /root/.bashrc
  • P.S 2015/04/06
    curl先のURLが変更されていたのでインストールコマンドを修正しました

curlの前の円マークは必要です
コマンドの前に円マークを付けることでaliasの設定を一時的に無視することができます

rvm -v
rvm 1.26.10 (latest) by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.io/]

ひとまずバージョンが表示されればOKです

autoconf2.69のインストール

rubyをインストールするのにautoconfのバージョン2.67以上が必要になります
2.67以上をインストールしないと

configure.in:6: error: Autoconf version 2.67 or higher is required

というエラーとなりrubyをインストールする際にmakeでエラーとなります
CentOS 6.6にデフォルトでインストールされているautoconfが2.63だったのでバージョンアップします

autoconf自体の最新バージョンは2.69のようです
せっかくなので最新版をインストールたいと思います

cd /var/tmp/
wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
tar zvxf autoconf-2.69.tar.gz
cd autoconf-2.69
./configure
make
make install

これでインストールできました
/usr/local/bin/autoconfにインストールされました
前のautoconfのPATHが効いている場合は再ログインすると新しいバージョンのautoconfを見るようになります

Rubyのインストール

まずインストール可能なRubyのバージョンを調べます

rvm list known

インストール可能なパッケージの一覧が表示されます
Ruby以外でのパッケージのバージョン一覧も表示されるので、ここからRubyの最新版を選択してインストールします

rvm install 2.2-head

Rubyの動作に必要なほかのパッケージの依存関係を解決してインストールしてくれます

インストールが完了すればrubyを使えるようになります
インストールされているディレクトリは以下のようです
/usr/local/rvm/rubies/ruby-2.2-head/bin/ruby

rvmを使ってみる

違うバージョンのRubyをインストールして切り替えてみる

次に違うバージョンのRubyをインストールしてみます
先ほどと同じようにrvm list knownでバージョンを確認して好きなバージョンをインストールしましょう
自分は1.9系をインストールしました

rvm install 1.9.3

インストールが完了するとすでに1.9.3にバージョンが切り替わっていました
パスは以下にインストールされています

/usr/local/rvm/rubies/ruby-1.9.3-p551/bin/ruby

ではここからまた2.2.0に切り替えてみましょう
すでにインストールされているRubyのバージョンを確認するにはrvm listを使います

rvm list

rvm rubies

=> ruby-1.9.3-p551 [ x86_64 ]
 * ruby-2.2-head [ x86_64 ]
   ruby-2.2.0 [ x86_64 ]

# => - current
# =* - current && default
#  * - default

1.9.3と2.2.0がインストールされていることがわかると思います
現在のバージョンが1.9.3になっていることもわかると思います

ここから2.2.0に切り替えるにはrvm useを使います

rvm use 2.2-head

これで2.2.0が使われるようになります
うまくrvm useが出来ない場合は一旦ログアウトしてから再度試してみてください

Gemの挙動を確認する

Rubyのバージョンを切り替えた場合のgemコマンドの挙動も確認しておきます
まずそれぞれのRubyのバージョンで使われるGemのバージョンを確認します

[root@localhost tmp]$ rvm use 2.2-head
Using /usr/local/rvm/gems/ruby-2.2-head
[root@localhost tmp]$ gem -v
2.4.6
[root@localhost tmp]$ which gem
/usr/local/rvm/rubies/ruby-1.9.3-p551/bin/gem
[root@localhost tmp]$ rvm use 1.9.3
Using /usr/local/rvm/gems/ruby-1.9.3-p551
[root@localhost tmp]$ gem -v
2.4.3
[root@localhost tmp]$ which gem
/usr/local/rvm/rubies/ruby-1.9.3-p551/bin/gem

それぞれの別のgemが使われているようです

ではこの状況でgem installを実行してみます
インストールするgemは何でもOKです
ruby 2.2.0の方でcapistranoをインストールしてみます

gem install capistrano

インストールの状況を確認すると

[root@localhost tmp]$ rvm use 2.2-head
Using /usr/local/rvm/gems/ruby-2.2-head
[root@localhost tmp]$ cap install
mkdir -p config/deploy
[skip] config/deploy.rb already exists
[skip] config/deploy/staging.rb already exists
[skip] config/deploy/production.rb already exists
mkdir -p lib/capistrano/tasks
[skip] Capfile already exists
Capified
[root@localhost tmp]$ rvm use 1.9.3
Using /usr/local/rvm/gems/ruby-1.9.3-p551
[root@localhost tmp]$ cap install
-bash: cap: コマンドが見つかりません

当たり前かもしれませんが1.9.3ではcapコマンドが使えませんでした
つまりgemも各バージョンごとで閉じていることになります

最後に

いまさらですがRVMを試してみました
これからはクリーンな環境にRubyをインストールするときはRVMを使いたいと思います
自分は特にRubyの各種バージョンを使い分けてテストしたり動作確認したりする必要のない人間だと思うのですが、検証とかにも便利そうなのとRuby自体のインストールも簡単にできるので使い続けてみたいと思います

参考サイト

Tips

  • ログインするとPATHが設定されていない
    rubyやgemコマンドへのパスはデフォルトでは通っていません
    どうやらrvm useで使用するrubyを指定するとPATHに通るようでコマンドを実行できるようになります
    なのでログイン時にデフォルトで使用するrubyを使うように.bashrcあたりに記載しておくといいと思います
echo 'rvm use ruby-2.2.1' >> /root/.bashrc

P.S 20150416
すでにrubyコマンドがPATHにある場合はuseしているのでその場合はuseしないほうがいいっぽいのでそこを制御した版は以下の通り
こっちのほうがCapistranoとかと絡んだ時に相性が良さそう

(! which ruby > /dev/null 2>&1) && rvm use ruby-2.2.1 > /dev/null 2>&1

2014年11月4日火曜日

Bloggerの記事を検索してpostIdを取得するスクリプト

概要

Bloggerに投稿した記事にはそれぞれを識別するためのIDが振られます
IDは管理画面でも確認することができますが、結構面倒です
自分はStackEditを使って記事を投稿、編集していて既存の記事を編集する場合にこのIDが必要になります
毎回UIで確認するのが面倒だったのでrubyからコマンドベースで確認できるようにしました

環境

  • Mac OS X 10.8.5
  • Ruby 2.1.2p95

ソースコード

https://gist.github.com/kakakikikeke/9ffc5427cf7f42a48ec5

使い方

上記のコードをgistから取得してapi_keyblog_idの部分を書き換えてください

そして

ruby get_post_ids.rb Blogger

と実行します
引数が1つ必要で、1つ目に指定したキーワードを元に記事を絞り込んで絞りこまれた記事のIDを表示します
上記の例では「Blogger」という単語を含む記事IDを表示します

BloggerのAPIの仕様で検索対象がタイトルも記事もURLも含まれるので1つに絞込みたい場合は、タイトル全文をキーワードとして指定するといいと思います

だいぶニッチですが、もし使う機会があれば使ってください

2014年8月14日木曜日

Rubyでグラフを描画してみた

Graphviz というAT&Tが開発したオープンなグラフを描画する仕組みを使ってグラフを描画してみました
dot言語という独自の言語で記述します
せっかくなので自分の身の回りのツールやシステムを可視化してみました
やっぱりソースコードで管理できるというのはいいですね

■環境
Mac OS X 10.8.5
Ruby 2.1.2p95
Gem 2.2.2n


■graphvizのインストール
http://www.graphviz.org/pub/graphviz/stable/macos/mountainlion/graphviz-2.36.0.pkg
からgraphvizをダウンロードします
ダウンロードが完了したらpkgファイルを実行してインストールしてください
利用規約に同意する以外、特に気にする部分はないと思います

インストールが完了すると /Applications/Graphviz.app/ が作成されていると思います

■gvizのインストール
gem install gviz

■サンプルコード
# -*- coding: utf-8 -*-
# sample.rb
require 'gviz'

gv = Gviz.new
gv.graph do
  # グラフ全体のレイアウトを定義
  global layout:'dot', overlap:false

  # 共通のサービスを宣言
  cloud_storage_services = [:Dropbox, :GoogleDrive, :Evernote, :Github, :codeBreak]
  local_storage = [:disk200a, :disk200b]
  net_services = [:Twitter, :Facebook, :Blogger, :Cacoo]

  # 起点となるノードからのつながりをここで定義
  ## ここですべてを定義しなくても後からedge等を使ってつながりを作成することは可能
  route :yoshi0 => [:Internet]
  route :yoshi1 => [:yoshi0] + cloud_storage_services + net_services + local_storage
  route :yoshi2 => [] + cloud_storage_services + net_services
  route :yoshi3 => [] + cloud_storage_services

  # すべてのノードに対するルールを定義
  nodes color:'black', fillcolor:'white', style:'filled'
  # 特定のノードに対するルールを定義
  cloud_storage_services.each {|k|
    node k, fillcolor:'green'
  }
  node :yoshi0, fillcolor:'gray99', label:'yoshi0\n(gateway)'
  node :yoshi2, label:'yoshi2\n(Jenkins)'
  node :fndb, fillcolor:'orange'
  net_services.each {|k|
    node k, fillcolor:'lavender'
  }
  node :Internet, fillcolor:'lavender'

  # 特定のエッジに対するルールを定義
  ## routeで定義したつながりを「_」で区切ることでエッジを特定して設定できる
  edge :yoshi1_yoshi0, color:'lightslateblue', label:'wi-fi'
  edge :yoshi1_yoshi2, style:'dotted', label:'rdp'
  edge :yoshi1_yoshi3, style:'dotted', label:'ssh'
  edge :yoshi2_yoshi3, style:'dotted', label:'ssh'
  edge :yoshi2_Github, style:'dotted', label:'git clone'
  edge :yoshi2_codeBreak, style:'dotted', label:'git clone'
  edge :yoshi2_fndb, style:'dotted', label:'xmlrpc'
  edge :fndb_Twitter, style:'dotted', label:'api-tweet'
  edge :fndb_Facebook, style:'dotted', label:'api-post'

  # ノードをグループにまとめる
  subgraph do
    global label:'cloud'
    node :yoshi2
    node :yoshi3
  end
  subgraph do
    global label:'home_net'
    node :yoshi0
    node :yoshi1
  end
end

gv.save :my_system, :png

■実行
ruby my_system.rb

と実行するとmy_system.dot と my_system.png というファイルが作成されます
pngを直接開いても問題ないですが、dotファイルを開いてもgraphvizが立ち上がりグラフを見ることができます

もしdotファイルを開いたときにgraphivzで開かない場合にはFinderでsample.dotのところまで開き
Cmd+i でファイルの情報を開き「このアプリケーションで開く」の部分をGraphvizに変更してください

※クリックすると拡大します

簡単に凡例を説明すると(完全にUMLは無視していますが。。)
  • 点線のつながりはTCP接続
  • 緑はストレージサービス的な
  • 薄い青はWebサービス的な
  • 白はマシンノード
的な感じを表しています

■Tips
gviz man
gviz man layouts
で各メソッド名を指定すればそのメソッドで指定できる属性情報を調べることができます
使用できる命令はほぼこれで網羅できると思います

■参考サイト

2014年7月18日金曜日

コマンドラインからAmazonアソシエイトの広告リンクを作成してみた

AmazonアソシエイトのHTMLリンクを1商品分だけコマンドで簡単に生成できたらいいなーと思って作ってみました
Rubyの「amazon-ecs」というGemを使っています

■環境
Mac OS X 10.8.5
Ruby 2.1.2p95
Gem 2.2.2
amazon-ecs 2.2.5

■設定
gem install amazon-ecs
gem install launchy

■ソースコード
touch call_amazon_api.rb

# -*- coding: utf-8 -*-
require 'amazon/ecs'
require 'launchy'

if ARGV.length != 1
then 
  p "Please input search keyword using the argument"
  exit 1
end
keyword = ARGV[0];

amazon_tracking_id = "Please input your amazon asociate tracking id"
access_key = "Please input your aws access_key or specified evn ACCESS_KEY at executing"
secret_key = "Please input your aws access_key or specified evn SECRET_KEY at executing"

if ENV["ACCESS_KEY"]
then
  access_key = ENV["ACCESS_KEY"]
end

if ENV["SECRET_KEY"]
then
  secret_key = ENV["SECRET_KEY"]
end

Amazon::Ecs.options = {
  :associate_tag => amazon_tracking_id,
  :AWS_access_key_id => access_key,
  :AWS_secret_key => secret_key
}

res = Amazon::Ecs.item_search(keyword, :response_group => 'Small, ItemAttributes, Images', :search_index => 'All', :country => 'jp')

#puts res.marshal_dump

res.items.each do |item|
  element = item.get_element('ItemAttributes')
  
  data = {
    :asin => item.get('ASIN'), 
    :title => element.get("Title"), 
    :page_url => "http://www.amazon.co.jp/dp/#{item.get('ASIN')}?tag=#{amazon_tracking_id}", 
    :isbn => element.get("ISBN"), 
    :author => element.get_array("Author").join(", "), 
    :product_group => element.get("ProductGroup"), 
    :manufacturer => element.get("Manufacturer"), 
    :publication_date => element.get("PublicationDate"), 
    :small_image => item.get_hash("SmallImage"), 
    :medium_image => item.get_hash("MediumImage"), 
    :large_image => item.get_hash("LargeImage")
  }
  image_info = data[:medium_image]
  html_file = "index.html"
  file_path = File.dirname(__FILE__) + "/" + html_file
  f = File::open(File.dirname(__FILE__) + "/" + html_file, "w+");
  f.puts(
         "<a href=\"#{data[:page_url]}\" target=\"_blank\"><table style=\"border-style: solid;\">" + 
         "<tr>" +
         "<td><img src=\"#{image_info['URL']}\" /></td>" +
         "<td><div>#{data[:title]}</div><div style=\"margin-top: 5px; font-size: 11px;\">#{data[:manufacturer]}</div><div style=\"font-size: 11px;\">#{data[:author]}</div></td>" +
         "</tr>" +
         "</table></a>"
         );
  f.rewind
  puts f.read
  f.close();
  Launchy.open(file_path)
  break;
end

まず「amazon_tracking_id」に自分のAmazonアソシエイト用のtrackingIDを指定します
次に「access_key」と「secret_key」ですが、これは直接ソースを編集してもいいし、ruby実行時の環境変数(ACCESS_KEY, SECRET_KEY)で指定しても大丈夫です

各自で設定する箇所は以上であとは ruby call_amazon_api.rb Java と実行すればOKです
Javaと指定している部分はAmazonで検索するキーワードで好きなキーワードを指定することができます
日本語もきっと使用できます

処理の流れとしてはキーワードを元にランキングを取得し1位の情報だけを取り出してWebサイトで表示するためのHTMLを作成します
作成したHTMLはターミナルの標準出力に表示されるので使いたい場合はコピペして使ってください
また、作成すると同時にHTML情報をデフォルトのブラウザで表示するようにしているので、HTMLのサンプルを作成することもできます

■サンプルレスポンス
<a href="http://www.amazon.co.jp/dp/4844330861?tag=kakakikikeke-22" target="_blank">
  <table style="border-style: solid;">
    <tr>
      <td>
        <img src="http://ecx.images-amazon.com/images/I/51fRtwXdWLL._SL160_.jpg" />
      </td>
      <td>
        <div>スッキリわかるJava入門</div>
        <div style="margin-top: 5px; font-size: 11px;">インプレスジャパン</div>
        <div style="font-size: 11px;">中山 清喬, 国本 大悟</div>
      </td>
    </tr>
  </table>
</a>


Web上での表示は以下の通り
スッキリわかるJava入門
インプレスジャパン
中山 清喬, 国本 大悟


ちょっとした商品を紹介するときには役にたつかなと思います

■参考リンク
Amazon-ECS APIリファレンス
ソースコード

進め方としては基本はAPIリファレンスベースに進めるといいと思う
APIのリクエストパラメータはruby内部でcamelizeしているので
SearchIndex -> :search_index
みたいな感じで変換してパラメータを設定することができる
レスポンスに関してはget_elementメソッドを使ってXMLの要素名を指定することでオブジェクトを取得してそこからgetなどでString情報を抜き出すことができる

2014年7月15日火曜日

BloggerAPIv3をrubyから使ってみた

■環境
Mac OS X 10.8.5
Ruby 2.1.2p95
Gem 2.2.2

■事前準備
  • Googleアカウントの作成
  • Google Developer Consoleでプロジェクトの作成
  • RubyおよびGemのインストール
※ここは説明を省略します

■作成したプロジェクトが持つアクセスキーに紐づくリダイレクトURLを設定する
何かややこしい書き方をしていますが、BloggerAPIv3は認証時にOAuth2を用いるためリダイレクトURLを設定する必要があります

  1. https://code.google.com/apis/console/b/0/?noredirect#project:[project_number]:access にアクセス
  2. [project_number]にはDevelopers Consoleで確認できるプロジェクトの番号を入力してください
  3. 左メニュー上部に現在のプロジェクトを切り替えるプルダウンがあるので作成したプロジェクトに切り替え
  4. 左メニューの「API Access」を選択
  5. 「Client ID for web applications」用のアクセスキーが存在するか確認します、ない場合は「Create another client ID」から新規にアクセスキーを作成
  6. 新規アクセスキー作成時に「Redirect URIs」を「http://localhost:9292」に設定
  7. 作成が完了したら一覧に戻り作成したアクセスキーに「Redirect URIs」が設定されているか確認

ここでリダイレクトURLに localhost:9292 を設定しているのは、使用しているgoogle-api-clientのgemが勝手にコールバックしてくれるURLになります
アプリ側(google-api-client を使用した ruby アプリ)から指定するリダイレクトURLとDevelopers Console側に登録したアクセスキーが持つリダイレクトURLは同一である必要があるためです
またこの作業はURLを見てもわかりますが旧Developer Consoleで実施する必要があります

以下のような感じになっていればOKです

■Google Developers Consoleから認証用のjsonファイルを取得する
  1. https://console.developers.google.com/ にアクセス
  2. Googleアカウントでログイン後、プロジェクトの一覧から作成したプロジェクトを選択
  3. 左メニューからCredentialsを選択
  4. OAuthの「Download JSON」をクリックし適当な位置にダウンロード
  5. ダウンロード後ファイル名をclient_secrets.jsonに変更、サンプルソースコードと同じディレクトリに保存

ここでダウンロードしたjsonファイルを元にgoogle-api-clientが勝手にOAuth2認証を実施してくれます

以下の箇所からダウンロードするイメージです

■google-api-clientのGemインストール
gem install google-api-client

■サンプルソースコード
先ほどダウンロードした認証用のJsonファイルがと同じ階層に以下のサンプルコードを配置してください

# -*- coding: utf-8 -*-
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'json'

blog_id = "Please input your blogger_id"

client = Google::APIClient.new(
  :application_name => 'Sample Blogger API App',
  :application_version => '1.0.0'
)
blogger = client.discovered_api('blogger', 'v3')

# この処理でダウンロードしたアクセスキーが記載されたJsonファイルを読み込む
client_secrets = Google::APIClient::ClientSecrets.load

flow = Google::APIClient::InstalledAppFlow.new(
  :client_id => client_secrets.client_id,
  :client_secret => client_secrets.client_secret,
  :scope => ['https://www.googleapis.com/auth/blogger']
)
# アプリを認証許可するまでここでwaitする
client.authorization = flow.authorize

# APIを実行する
result = client.execute(
  :api_method => blogger.posts.list,
  :parameters => { 'blogId' => blog_id }
)

# return Google::APIClient::Schema::Blogger::V3::PostList
# puts result.data.class
# puts result.data.methods
# puts result.data.to_json

json = JSON.parse(result.data.to_json)
json['items'].each do |item|
  puts "id : " + item['id']
  puts "title : " + item['title']
  puts "content : " + item['content']
end

blog_id = "Please input your blogger_id"
の部分に自分のbloggerのIDを入力してください
blog_idはbloggerの管理UIにログインしてURLに表示される番号を入力してください

ruby test_blogger_api.rb

と実行するとリダイレクトURLに設定したlocalhost:9292のページが表示されアプリからのアクセス承認を求められます
その後、ターミナルに戻るとポストの一覧が結果がされていると思います
1回の取得で最大10件しか取得できないので次のページを取得する場合はレスポンスのobjectをページネートして次の10件を取得してください
(たしか、resultオブジェクトにページネートできるメソッドが実装されていたと思います)

以上です
ポイントはOAuth2.0を使っているのでプロジェクトに作成するアクセスキーにちゃんとRedirect URLを設定するところでしょうか
あとはRubyのリファレンスが少ないのでmethodsで使えるメソッド名を確認したり参考サイトにも紹介しているAPIExplorerで実際のJsonレスポンスを見てレスポンスオブジェクトへのアクセス方法を自分調べる必要がありました

■参考サイト
google-api-client本家サイト
https://developers.google.com/api-client-library/ruby/start/get_started?hl=ja

Google API Explorer
ここを参考にしてexecuteするリクエストのパラメータ等は調べられると思います
https://developers.google.com/apis-explorer/#p/blogger/v3/

2014年4月28日月曜日

CentOS6.3でrailsのサンプルアプリを動かしてみた

■環境
CentOS release 6.3 (Final) 64bit
ruby 2.1.1p76
gem 2.2.2
rails 4.1.0
sqlite 3.6.20

■インストール
yum -y groupinstall "Development Tools"
yum -y install zlib zlib-devel openssl openssl-devel sqlite-devel
wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.1.tar.gz
tar zvxf ruby-2.1.1.tar.gz
cd ruby-2.1.1
./configure
make
make install
gem update
gem install rails --no-rdoc --no-ri
gem install execjs --no-rdoc --no-ri
gem install therubyracer --no-rdoc --no-ri
cd /var/tmp
rails new "rails-test"
cd rails-test
echo 'gem "therubyracer"' >> Gemfile
rake db:create
rails server

http://localhost:3000 にブラウザでアクセスしてrailsのサンプルが表示されることを確認する

■サンプルアプリ作成
cd /var/tmp/rails-test
rails generate controller test-app
create  app/controllers/test_app_controller.rb
invoke  erb
create    app/views/test_app
invoke  test_unit
create    test/controllers/test_app_controller_test.rb
invoke  helper
create    app/helpers/test_app_helper.rb
invoke    test_unit
create      test/helpers/test_app_helper_test.rb
invoke  assets
invoke    coffee
create      app/assets/javascripts/test_app.js.coffee
invoke    scss
create      app/assets/stylesheets/test_app.css.scss

vim config/routes.rb
Rails.application.routes.draw do
  get 'hello' => 'test_app#hello'
  get 'bye' => 'test_app#bye'
end

touch app/views/test_app/bye.html.erb
touch app/views/test_app/hello.html.erb
vim app/views/test_app/hello.html.erb
<h1>Hello</h1>
This page is created by template file.
<%= @msg %>

vim app/controllers/test_app_controller.rb
#coding: utf-8
class TestAppController < ApplicationController
  def hello
    @msg = 'hello'
  end

  def bye
    render :text => 'bye'
  end
end

rails server

http://localhost:3000/hello にアクセスするとテンプレートのファイルを表示
http://localhost:3000/bye にアクセスすると文字列を表示

■DBサーバ設定と接続テスト
rails generate model test_app

vim db/migrate/20140425074927_create_test_apps.rb
class CreateTestApps < ActiveRecord::Migration
  def change
    create_table :test_apps do |t|
      t.string :name
      t.timestamps
    end
  end
end
rake db:migrate
   うまくmigrateできない場合、スキーマを変更する場合は「rake db:migrate:reset」でDBを再作成できます
   id, created_at, updated_at カラムは自動で生成されるようです

vim db/seeds.rb
TestApp.create(:name => 'test1')
rake db:seed
   この操作でseeds.rbに記載したレコードをinsertしてくれます
   マスターデータ等事前に登録しておかなければいけないデータを記載します

rails dbconsole
select * from test_apps;
   sqlite3を使ってDBの中を見ることができます、上記SQLでデータが存在することを確認する
   sqlite3自信はファイルDBなので実データはrails上で管理しているファイルを参照しています

vim app/controllers/test_app_controller.rb
#coding: utf-8
class TestAppController < ApplicationController
  def hello
    @msg = 'hello'
    @test_app_all_record = TestApp.all
  end

  def bye
    render :text => 'bye'
  end
end
   モデル名.all とするとDB内にあるデータをすべて取得することができます

vim app/views/test_app/hello.html.erb
<h1>Hello</h1>
This page is created by template file.
<%= @msg %>

<br>
<br>

<table border="1">
  <tr>
    <td>id</td>
    <td>name</td>
    <td>created_at</td>
    <td>updated_at</td>
  </tr>
<% @test_app_all_record.each do |test_app| %>
  <tr>
  <td><%= test_app.id %></td>
  <td><%= test_app.name %></td>
  <td><%= test_app.created_at %></td>
  <td><%= test_app.updated_at %></td>
  </tr>
<% end %>
</table>
   controller内で取得したDBのオブジェクトをeachで回して全レコードを表示してあげます

rails server
httpd://localhost:3000/hello
にアクセスするとDB内の情報が表示されることを確認します

■Tips
ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime

gem install therubyracer --no-rdoc --no-ri
して
echo 'gem "therubyracer"' >> Gemfile
すれば解消する

rubyのインストールにchefのオムニバスインストールをするとgemのバージョンが古くてうまく動作しません

sqlite3でテーブルのスキーマを確認する方法は「select * from sqlite_master;」 or 「.schema table_name」

■参考サイト

P.S 20140508
insertやdeleteできるサンプルを含んだサンプルのソースコードをGithubで公開しました
https://github.com/kakakikikeke/ruby-rails-sample-app

2014年1月15日水曜日

minaをインストール

■環境
CentOS 5.9
Ruby ruby 1.9.3p125
gem 2.1.4
mina 0.3.0

■インストール
cd /var/tmp
touch Gemfile
vim Gemfile
cat Gemfile
source :rubygems

gem 'mina'
bundle install --path vendor/bundle
bundle exec mina init
  すると「/var/tmp/config/deploy.rb」が作成されます

■設定
vim /var/tmp/config/deploy.rb
set :domain, 'hostname'
set :deploy_to, '/var/tmp/deploy'
set :user, 'root'
set :repository, 'https://github.com/kakakikikeke/ruby-kakabot.git'

#invoke :'rails:db_migrate'
#invoke :'rails:assets_precompile'
  今回はrailsアプリでなくDBも使っていないため上記2行をコメントアウトします
  コメントアウトしないとrakeファイルがない(No Rakefile found)と言われてデプロイに失敗します

■デプロイ先設定
cd /var/tmp
bundle exec mina setup
  設定に合わせた事前準備を先ほど設定ファイルに記載したデプロイ先に対して実行します

■デプロイ実行
cd /var/tmp
bundle exec mina deploy
ls /var/tmp/deploy/releases/1/
  にgitからcloneしたデータがデプロイされていると思います

■Tips
・mina tasks
実行できるタスクの一覧を表示してくれます
・gem install mina --no-rdoc --no-ri
・mina init
上記の手順でもインストールと初期設定ができるみたいなんだけどGemfileがないためCould not locate Gemfileとなって怒られてしまいます
・デプロイ先ホストへのSSHノンパス設定
今回は同一ホストに対して実施しましたがデプロイ先のサーバに対してはSSHのノンパスログインを設定する必要があります
公開鍵を使ったSSHのノンパス設定方法は以下を参照してください
http://kakakikikeke.blogspot.jp/2012/03/10ssh.html
・cap shell的なコマンド
capistranoでいうところの「cap shell」みたいなコマンドはあるのか気になりました
mina console というタスクがデフォルトで用意されていたのでそれかなと思い実行したので裏側はrails console を実行していたので違うっぽい(?、未検証)
⇒mina run["ls -la"]といった感じで実行するとcap shellと同じようなことができるようです

■参考サイト

今回はデフォルトのレシピを使ってデプロイしてましたが次回は独自のレシピを使って実行してみたいと思います

2014年1月6日月曜日

【ruby】'encode': "\x85" followed by "\"" on Windows-31J (Encoding::InvalidByteSequenceError)

ruby自体のファイルの文字コードとマジックコメントはUTF-8とします
rubyコマンドを実行する際に文字コードを指定しないと実行しているターミナルのデフォルトの文字コードが使われてしまいうまくマルチバイト文字が処理されないようです

ruby -Eutf-8 sample.rb

環境は以下のとおり
  • Windows7 64bit
  • ruby 2.0.0p195 (2013-05-14) [x64-mingw32]

2013年11月3日日曜日

Growlと連携してRedmineのチケットが自分に来た時に通知してくれるRubyスクリプト

https://gist.github.com/kakakikikeke/7289446

Gistでソースコードを公開しました
Rubyで作っています

■環境
Windows7 64bit
Ruby 2.0.0p195
Growl 2.0.9.1

■インストール方法
1. 事前準備

2. 必要なgemのインストール
コマンドプロンプトを開いて以下のコマンドを実行し必要なモジュールをインストールします
デフォルトでインストールされているモジュールもありますので必要に応じて実行してください
gem install json
gem install open-uri
gem install mail
gem install date

3. スクリプト設定
Gistからダウンロードしたcheck_ticket.rbをGrowlをインストールしたディレクトリに配置します
配置したcheck_ticket.rbに対して「rubyw.exe」で開くようにプログラムを紐付けます
※ruby.exeではなくrubyw.exeを紐付けてください、rubyw.exeを紐付けることで実行時にコマンドプロンプトを表示させないようにします

check_ticket.rbの以下の項目を設定してください
  • user_id・・・redmine上で管理されているユーザのIDを入力します、URLに表示される「query_id=」の数字を入力します
  • username・・・redmineにログインするユーザ名を入力します
  • password・・・redmineにログインするユーザのパスワードを入力します
  • redmine_hostname・・・redmineが動作しているドメインもしくはIPアドレスを入力します
  • redmine_port・・・redmineが動作しているポートを指定します、80番の場合も省略せずに入力してください
  • proxy_hostname・・・プロキシのホスト名またはIPアドレスを指定します(プロキシを利用する場合は23行目のopen_uriの部分のコメントアウトを切り替えてください)
  • proxy_port・・・プロキシが動作しているポート番号を入力します、80番の場面も省略せずに入力してください

4. Windowsタスクスケジューラの設定
タスクスケジューラを開き右上「タスクの作成」を選択します
名前、説明は適当に入力します(「Redmineチケット通知」とかにしておきましょう)
タスクの実行は「毎日」で設定します(あとで更に設定変更します)、間隔も1日で大丈夫です
タスクの実行は「プログラムの開始」を選択し、プログラムにダウンロードしてGrowlのインストールディレクトリに配置したcheck_ticket.rbを参照から選択します
そのまま確認画面にいってOKを押下してタスクを作成します

作成したタスクが一覧に表示されるのでプロパティを表示します
トリガータグから編集を選択し「トリガーの編集」ダイアログを表示します
繰り返し間隔を「1分間」に設定し、継続時間を「無期限」に設定します
繰り返し間隔はプルダウンに1分間というのがないのですが、5分間を選択したあとにプルダウンを編集して1に変更してください


これで設定は完了です
うまく動作しない場合はcheck_ticket.rbをデバッグしてエラーが出ていないか確認してください

■Tips
デバッグしたい場合は以下の内容のファイルをGrowlのインストールディレクトリに配置して実行してください
rubyの実行内容がコマンドプロンプトに表示されます
cd C:\Program Files (x86)\Growl for Windows
ruby check_ticket.rb

現状の設定だと過去5分間に更新されたチケットを通知します
なので1分毎に回るタスクだと一回の更新で通知が3から4件ほど来てしまいます
通知を減らしたい場合は時間をbefore_minute変数の時間を「60*5」ではなく「60*2」とかにしてください

2013年10月28日月曜日

【ruby】invalid multibyte char (US-ASCII)

先頭に以下を追加する

# encoding: utf-8

いつも忘れのでメモ

2013年9月21日土曜日

Invalid gemspec in [/usr/local/lib/ruby/gems/1.9.1/specifications/ZenTest-4.9.3.gemspec]: Illformed requirement ["< 2.1, >= 1.8"]

とりあえずgemコマンドを打つと必ずタイトルのエラーが出力されるようになったので対処してみた

gem uninstall ZenTest
mv /usr/local/lib/ruby/gems/1.9.1/specifications/ZenTest-4.9.3.gemspec /var/tmp

でとりあえず出なくなった
これでいいのかだろうか。。。

2013年6月26日水曜日

【Ruby】sinatraインストール方法

■環境
CentOS release 6.3 (Final)
ruby 1.9.3p286
gem 1.8.24

■rubyとgemをインストール
sudo true && curl -L https://www.opscode.com/chef/install.sh | sudo bash

■sinatraインストール
cd /opt/chef/embedded/bin
./gem update
./gem install sinatra
mkdir -p /var/tmp/sinatra
cd /var/tmp/sinatra
vi hello.rb
require 'sinatra'
get '/' do
  'Hello world!'
end
/opt/chef/embedded/bin/ruby hello.rb -e production
でブラウザからhttp://localhost:4567/にアクセスする

2013年5月14日火曜日

Windows7にrubyをインストール

■環境
Windows7 64bit
インストールするrubyのバージョンは2.0.0とします

■ruby&gemインストール
  1. http://rubyinstaller.org/downloads/にアクセス
  2. Ruby 2.0.0-p0 (x64)をクリックしてWindows用のexeインストーラをダウンロード
  3. ダウンロードが完了したらインストーラを実行
  4. インストールの途中で「Ruby の実行ファイルへ環境変数PATHを設定する」にチェック
  5. あとは気にせずインストール
  6. デフォルトでインストールすると「C:\Ruby200-x64」にインストールされます
  7. コマンドプロンプトを開いてバージョンを確認
  8. ruby -v
    ruby 2.0.0p0 (2013-02-24) [x64-mingw32]
    
  9. gemのインストールも確認
  10. gem -v
    2.0.0
    

■Development Kitインストール
  1. rubyのインストーラをダウンロードした同様のサイトからDevKit-mingw64-64-4.7.2-20130224-1432-sfx.exeをダウンロード
  2. C:/ruby_dev_kitフォルダを作成しそこでダウンロードしたインストーラを実行しファイルを展開
  3. 展開した C:/ruby_dev_kit に移動し「ruby dk.rb init」を実行
  4. config.yml ができるので編集、以下の一行を追加(rubyをインストールしたパスを追加)
  5. - C:/Ruby200-x64
  6. ruby dk.rb review
  7. ruby dk.rb install(INFOレベルのログが表示されエラーがでなければDevelopment Kitのインストール成功)
  8. gem update ができるようになっていることを確認

こんな簡単にインストールできるようになったんですね。。。

■トラブルシューティング
・gem installに失敗して以下のエラーがでる
ERROR: Could not find a valid gem 'bundler' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/latest_specs.4.8.gz)

-> gem install bundler -r --source http://rubygems.org/
-> のように一時的にhttpを使うようにしてinstallする

・Jekinsからrubyが認識されない
Jenkins側にまだ環境変数の情報が反映されていません
一度Jenkinsを再起動してください
それでもダメな場合はrubyをインストールするときに環境変数に反映するチェックボックスがONになっていたか確認してください

2012年9月11日火曜日

【redmine】ガントチャートで表示されるデフォルトの開始月を変更する方法

ガントチャートはデフォルトだと当月から表示されます
プロジェクトによっては何ヶ月か前から進行しているものもあり数ヶ月前の状況を確認したい場合もあります
一応プルダウンから月の変更は可能ですが、毎回当月から変更するのはめんどくさいですね
その場合の対処方法をご紹介します
※今回は2ヶ月前にしてみます


cp -p lib/redmine/helpers/gantt.rb{,.back}
emacs lib/redmine/helpers/gantt.rb
53行目あたり
@month_from ||= Date.today.month

@month_from ||= Date.today.month - 2
にすることでガントチャートの開始月が現在の付きの2ヶ月前となります


redmineを再起動しガントチャートを見ると当月の2ヶ月前から表示されていると思います
お試しあれー

P.S 20130201
すいません。上記だと2月に@month_fromが0になるので、エラーとなりガントチャートが表示されません。。。
以下の部分を上記で修正した箇所の下に追記してください
if @month_from = 0
  @month_from = 12
  @year_from = @year_from - 1
end
0の場合は12月をセットしかつ年も一年前にします
2013年2月の場合は2012年12月から表示されます

2012年8月13日月曜日

【Ruby】Railsを使ってみた(MySQL接続)【サンプルコードあり】

P.S 20140425
だいぶ手順が雑でしたので見直しました、見栄えも修正しております
またCentOS6系でも試してみましたのでCentOS6系の場合はこちらをご参照ください

■概要
Ruby on Railsを使って簡単なアプリを作ってみました
scaffold的なサンプルアプリを作成してみました

■バージョン
CentOS 5.10 64bit
Rails 3.2.7
ruby 1.9.3p125
mysql 5.0.95

■事前
ruby、railsのインストールは必須です
http://kakakikikeke.blogspot.jp/2012/04/centos56ruby.html

足りなかったインストール系は以下
gem install therubyracer
gem install execjs

■rails基本設定
cd /var/tmp
rails new "simpledbform" -d mysql
cd simpledbform/
vi Gemfile
   gem 'therubyracer'
   を追記
rake db:create
   DB作成に関してはこれで代用
rails server
   ブラウザで3000番にアクセスするとRailsのサンプルを表示
   http://localhost:3000/

■controller作成
rails generate controller sdfctl
   sdfctlは好きなアプリ名を入れてください
emacs config/routes.rb
   ここはgenerateしたコントローラの名前を記載します
match 'hello' => 'sdfctl#hello'
match 'bye' => 'sdfctl#bye'

■view設定(controllerとの連携)
touch app/views/sdfctl/hello.html.erb
touch app/views/sdfctl/bye.html.erb
   ここで作成するファイル.erbファイルはテンプレートファイルです
   テンプレートファイルはコントローラで記載したURLマッピングの名称と同値(必須ではないが)にしておくといいです

emacs app/views/sdfctl/hello.html.erb
<h1>Hello</h1>
こんにちは。お元気ですか。
<%= @msg %>
emacs app/controllers/sdfctl_controller.rb
# coding: utf-8
class SdfctlController < ApplicationController
     def hello
          #render :text => 'Hello!' ⇒これは直接テキストを表示する命令、未使用なのでコメントアウト
          @msg = "おげんきだぜー";
     end
                                                                                                                                                                                               
     def bye
          render :text => 'bye!'
     end
end
再起動して/helloにアクセスするとテンプレートを表示

■modelとDB連携
rails generate model name
invoke  active_record
create    db/migrate/20120809010634_create_names.rb
create    app/models/name.rb
invoke    test_unit
create      test/unit/name_test.rb
create      test/fixtures/names.yml

emacs db/migrate/20120809010634_create_names.rb
t.string :first_name
t.string :family_name

rake db:migrate
   migrateコマンドでテーブルを作成
emacs db/seeds.rb
# coding: utf-8
Names.create(:first_name => 'keke', :family_name => 'kakakiki')
Names.create(:first_name => 'keke2', :family_name => 'kakakiki')
emacs app/models/name.rb
attr_accessible :first_name, :family_name
   Can't mass-assign protected attributesのエラーに対応

rake db:seed --trace
   この段階でsimpledbform_developmentにレコードがインサートされるので別途mysqlコマンドで確認
   rails dbconsoleでも確認可能

emacs app/views/sdfctl/hello.html.erb
<h1>Hello</h1>
こんにちは。お元気ですか
<%= @msg %>

<% @name_all.each do |name| %>
[苗字] <%= name.family_name %>, [名前] <%= name.first_name %>

<% end %> 
emacs app/controllers/sdfctl_controller.rb
# coding: utf-8
class SdfctlController < ApplicationController
     def hello
          @sum = 1 + 1
          @msg = "おげんきだぜー";
          @name = Name.all
     end

     def bye
          render :text => 'bye!'
     end
end

rails server
でこの状態で/helloにアクセスするとDBのデータを取得してその値を取得し表示してくれると思います

以上で簡単なサンプルは完了です

■メモ
public/配下が静的ファイルを置く場所
config/routes.rbがリクエストの振り分けを行う、URLのマッピング
controllerのURLマッピングとviewのhtml.erbファイルは密接に関係
MVCモデルの設定ファイルはapp/models, views, controllersがそれぞれ対応
rubyで2バイト文字を先頭で使うときには# coding: utf-8を記載
railsではデータベースを作成する際にmigrateという機能を使用
(DBに直接コマンドを打つのではなくrails特有のスクリプトからDBを構築する手法)
rails serverは毎回行わなくてもMVCの更新でリアルタイムに反映
rubyの「:」はテキストを表している、「:text」「'test'」「"test"」は同値

2012年8月8日水曜日

【Ruby】フレームワークRackを使ってみた(サンプルコードあり)

RubyとGemは以下の記事を参考にインストールしてください
http://kakakikikeke.blogspot.com/2012/04/centos56ruby.html

■Rackインストール
gem install rack
mkdir /usr/local/rack/
cd /usr/local/rack/

■サンプルプログラム取得
git clone git://github.com/kakakikikeke/kakabot.git
cd kakabot
rackup geme.ru

ブラウザで9292ポートにアクセスすると(実はワタシが作った)kakabot.のサンプルプログラムが動作します
rackは非常に簡単ですw

気になったのはRuby中で日本語などの2バイト文字を使用するときには
  • # coding: utf-8 をRubyファイルの先頭に付与する
  • formタグ等でリクエストを制御するときにはaccept-charsetやenctypeでしっかりとUTF-8と指定する必要がある
ってところです。まぁ当たり前なんですが


2012年8月5日日曜日

Redmineの活動ページで「Wiki編集」「メッセージ」「作業時間の記録」をデフォルトで表示する方法

Redmineの活動ページの表示で「Wiki編集」「メッセージ」「作業時間の記録」はデフォルト設定ではチェックがONになっておらず、わざわざONにして再表示する必要があります

またログインをしなおしたりしてもチェックが外れてしまいます

ので今回はそれをデフォルトでチェックONにする方法を紹介します

解決方法は直接ソースコードを編集するしかありませんw
Redmineがインストールしてあるフォルダの
lib/redmine.rb
を編集します

編集するのは以下の部分です

Redmine::Activity.map do |activity|
  activity.register :issues, :class_name => %w(Issue Journal)
  activity.register :changesets
  activity.register :news
  activity.register :documents, :class_name => %w(Document Attachment)
  activity.register :files, :class_name => 'Attachment'
  activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => true
  activity.register :messages, :default => true
  activity.register :time_entries, :default => true
end

下3行赤字の部分がデフォルトではfalseになっているためチェックが入っていません
ここをtrueの設定にすることでデフォルトでONになっています

どうしてUIから設定できるようにしなかったんだw

ちなみにRedmineのバージョンはちょっと古くて1.4.3.stableですw(それがいけないのかもねw)