ホーム ブログ ページ 54

スタイルシートの小ネタ〜idとclassの合わせ技で指定する〜

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

スタイルシートを適用するのにidやclassを使いますよね。今回はその使い方の中から、たまに役立つ小ネタを紹介します。スタイルシートでidやclassを指定するとき、

#hogehoge

.hogehoge

という書き方をするのはご存知の通りで、

#hogehoge .hoge

という書き方(子孫セレクタ)も普段からよく使います。

さらに実際サイトを作っているとidとclassが同じdivに指定されることもよくあります。

こんなカンジ。

ここまではよく見るコードなんですが、さらにAjaxが絡んでくるとややこしくなってきます。

例えば

・タブメニューの背景をそれぞれidで指定している

・タブを切り替えたらリロードなしでメニューの背景もいれかわる

よくある動きです。

こんなときは#hogehogeでかつ.hoge_onの時、または.hoge_offの時という指定をします。

#hogehoge.hoge_on { background-color: #ff0000; }

#hogehoge.hoge_off { background-color: #0000ff; }

子孫セレクタに良く似てますが、idとclassの間にスペースはありません。

この書き方だと

この時は背景が赤

この時は背景が青

とclassが切り替わるだけで背景を出し分ける事ができます。

実際このくらいは子孫セレクタを使えば何とかなることが多いんですが、

Ajaxのライブラリを使ったり、プログラムでアレコレしていると

子孫セレクタだけではなんともならないことがあるので、

そんなときにはこの書き方(ちょっと調べたんですが呼び名が特に見つかりませんでした…)で対処できます。

手書きで検索できるシンプルな筆順辞典「常用漢字筆順辞典」

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


皆さん漢字は得意ですか?
今回紹介するアプリは、常用漢字筆順事典。350円です。

最近はパソコンやケータイの普及で、漢字が苦手な人が増えてきていると言われていますね。
筆者もご多分に漏れず漢字がとても苦手です。
ミーティング中ホワイトボードに書き込もうとして手が止まってしまうこともしばしば……
ということで、シンプルな筆順辞典アプリをご紹介します。


起動するとすぐに手書き検索用のキャンパスが開きます。シンプルですね。
調べたい漢字を手書きで入力します。


候補リストが現れるので目的の漢字を選択。


なぞって筆順を確認することができます。


あーこれ 「ふな」って読むのか。ふななー。

手書き認識の精度はかなり高く、一部記憶が曖昧な漢字であっても
適当に書いてみると候補リストに出てきたりします。


「挨拶」って、何回書いても覚えられないよね。

その他、普通に画数や読み、漢字そのもので検索することも可能。

現時点では用例は少なめ、筆順データが無い漢字も割とある
というところが少々イマイチですが
頻繁にデータ追加バージョンアップが行われているようなので
これはその内解消されるかもしれません。
ちなみに、筆順データが無い漢字については筆順の確認は出来ませんが
読みや部首名を調べることは可能です。
また熟語で検索することはできません。

全体としてシンプルな使い勝手にこだわりを感じました。
350 円という価格も辞書系アプリとしてはかなり安価なので
シンプルな漢字辞書を探している方にはオススメです。

常用漢字筆順辞典


えっ「必」ってその点から書くの!?

QRコードをベクター化する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

QRコードを作ったはいいものの、印刷物に載せるには解像度が足りない!
そんな時にQRコードをベクター化して、サイズの大きい印刷物にも使用できるようにする方法をご紹介します。

用意するもの
・ベクター化したいQRコード
・Photoshop
・Illustrator

QRコードの画像は、QRコード作成のできるサイトがいくつもありますので、
それらを利用するなどして用意してください。

それでは早速作ってみましょう。
まずは用意したQRコードをPhotoshopで開きます。
今回はこのQRコードをベクター化します。
QRコード

「選択範囲」→「色域指定」で黒い部分のみ選択されるように調整します。
黒い部分のみ選択できましたら、パスウィンドウの下の方にある
「選択範囲から作業用パスを作成」(下図の部分)をAltキーを押しながらクリックします。
選択範囲をパスに変換

許容値を入力するウィンドウが出てきますので、「0.5」と入力してOKを押します。
すると、下図のように見事選択範囲がそのままパスになります!
パスになりました
後はこれをパス選択ツールで全て選択して、Illustratorへコピペして色をつければ完成です。

ちなみに許容値は0.5~10の値で入力することができ、
数値が小さいほど詳細に、数値が大きいほどアバウトにパスへと変換することができます。
これは他の用途にも応用できますので、是非覚えておいてください。

ちなみに・・・
意外と知られていなかったりしますが、「QRコード」という単語を使用した際は
「QRコードは(株)デンソーウェーブの登録商標です」という登録商標文を記載しなければなりません。
掲載したくないorスペースがない場合は「二次元バーコード」、「二次元コード」などの言い換えを使用しましょう。

QRコードは(株)デンソーウェーブの登録商標です

Dockを多段ランチャーにする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、たろちゃんです。Mac OSXではなかなか良い多段ランチャーに出合ったことがありません。なので、いっその事Dockを多段ランチャーにしてみました。

みなさんはMac OSXでランチャーは何を使っているでしょうか?僕は普段はQuick Silverを使っています。このランチャーはキーボードのみでさくっとアプリケーションを開いたりタスクを実行したりできるため、非常に便利です。

しかしながら、Quick Silverでも欠点があります。それはアプリケーション名を覚えていないと使いづらいという点です。アプリケーションの名称を駆使するため、どうしてもこういう状況になってしまいます。

僕自身はWindowsを使っている場合はキーボードタイプのランチャーの他に、CLaunchというソフトを併用しています。このソフトはいわゆるボタン型のランチャーで、アプリケーションをカテゴリごとに分けられるので非常に便利です。

そこで、この手のソフトを探してみたのですが、そもそもDockがあるので需要がないのか、ほとんど見つかりません。見つかったとしてもSnow Leopard対応されていないもののようなので、あまり使いたくはありません。なので、Dockに一工夫をしてボタン型のランチャーっぽいものを作ってみました。

まず初めにアプリケーションのエイリアスを格納するためのフォルダを作成します。今回は以下のようにフォルダを作成しました。

  • $HOME/ショートカット/ユーティリティ
  • $HOME/ショートカット/ネットワーク
  • $HOME/ショートカット/画像系

そして、アプリケーションフォルダにあるアプリケーションをFinderで選択してメニューから「エイリアスを作成」もしくはCommand + Lを選択してエイリアスを作成します。

作成したエイリアスは先程作成したフォルダの中にコピーをして、ファイル名で「 のエイリアス」を削除します。

あとは、これはおまけになりますが、フォルダのアイコンを変更しておきます。まずは変更先のアイコンをアプリケーションのプレビューを使って表示をして、Command + Aで選択した上で Command + C でコピーをします。そして、Finderでフォルダを選択して、メニューから「情報を見る」もしくは Command + I を選択して情報のWindowを表示し、左上のアイコンを選択した状態で Command + V を押して画像を貼りつけます(図1参照)。アイコンの変更方法の詳しいやり方はAppleのドキュメントを参考にしてください。なお、フリーのアイコンはdeviantArtなどで探すと良いでしょう。

これで準備が完了しました。あとはフォルダごとDockのTime Machineの箇所から下の方へドラッグをします。するとフォルダがDockに登録されます。

しかしながら、これだけだとフォルダのアイコンではなく、中身のアイコンが表示されてしまいます。そこでDockのフォルダを選択して右クリックを押し、表示形式でフォルダを選択します(図2)。

これで作業は完了です。どのようになったのか見てみましょう。

まず、Dockが下にあるパターンです。下の図の場合は内容の表示形式でファンを選んだ時の表示です。さっとアイコンが並ぶので結構かっこよいと思います。

次はDockを左に置いたパターンです。この場合は内容の表示形式でファンが選べません。下の図は内容の表示形式がグリッドを選んだ時の表示です。

このように簡単な作業でランチャーを作成する事ができました。標準的なしくみを使っているので、メジャーバージョンが上がっても同じテクニックが使えると思います。

git-svnによる実プロジェクトでのチーム開発

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、SHIMADAです。Gitネタはたろちゃんに先を越されてしまいましたが、自分の環境でも、実際のプロジェクトでGitを実用的に使える状況になってきたので、そのへんについて書こうと思います。

 前提

前提条件として、

1. プロジェクトのためのsvnリポジトリがサーバーに用意されていること

2. リポジトリが

PROJECT_NAME/
 `- trunk/
 `- branches/
 `- tags/

というSubversionの標準的なディレクトリ構成となっていること

3. ローカルに最新のgitがインストールされていること

が条件となります。

前者が揃っていないという人は、まずSubversionを導入できるように社内での推進をがんばってください。

申請書とUSBメモリがないとコミットできないんだよ……、という人は、残念ながらあきらめてください。

(あれはネタだと信じていますが……)

後者が揃っていない人は、がんばってググってインストールして下さい。

 下ごしらえ

さて、条件が揃ったところで、下ごしらえです。

まずローカルで、gitの設定をしましょう。

$ git config --global user.name "your name"
$ git config --global user.email account@example.com
$ git config --global color.ui auto
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.br branch

git config だと カレントワーキングツリーの .git/config に書き込まれます。

  • global オプションをつけると、 ~/.gitconfig に書き込まれます。

このへんは適宜使い分けてください。

あと、 ~/.gitconfig をエディタで開いて直接編集してもいいと思います。

 リポジトリのClone

次に、プロジェクトのリポジトリからローカルのgitリポジトリにcloneしてきます。

git svn clone -s --prefix svn/ [svnリポジトリのURL] [作成したいGitリポジトリのPATH]

svnリポジトリのURLは、/trunk をつけないプロジェクトのルートまでを書くのが注意点です。

git svn の -s オプションが、自動的に trunk と branch を見分けて git のリポジトリにとりこんでくれます。

名前がないと説明に不便なので、リポジトリの名前を仮に決めておきたいと思います。プロジェクトのリポジトリURLhttps://example.com/svn/repos/myproj/ローカルのリポジトリPATH/home/me/src/myproj-git/

この場合、上記のコマンドはこうなります。

$ git svn clone -s --prefix svn/ https://example.com/svn/repos/myproj/ ~/src/myproj-git

これで、 myproj のgitリポジトリが myproj-git/ に作成されました。

内容を見てみましょう。

$ cd ~/src/myproj-git
$ find .
$ git br -a
$ git svn info

find すると、ローカルのファイルシステムになにがあるか一覧できます。

うまくいっていれば、チェックアウトされたワークツリーと、.git/ 以下のローカルリポジトリが見えるはずです。

git br -a は、リポジトリに含まれるブランチを一覧できます。

git clone に –prefix svn/ をつけたので、リモートブランチは remotes/svn/hogehoge という風に見えているはずです。

git svn info で、カレントのローカルブランチがsvn上のどのブランチに対応しているかが分かります。

clone直後はローカルブランチはmasterのはずです。これが、svn/trunkに対応していない場合は、masterを作り直してみてください。

手順は、

  1. リモートのtrunkに対応したブランチを仮の名前で作成してそこに移動する
  2. 現在のmasterブランチを削除
  3. 仮の名前をmasterにリネーム

です。具体的なコマンドは、下記のようになります。

$ git co -b master2 remotes/svn/trunk
$ git br -D master
$ git br -m master2 master
$ git co master

(この項目の情報源はこちら

全部ローカルでの作業なので、上流のsvnリポジトリには一切影響が出ません。

うまくいかなくても怖がらずに、何度でも繰り返して試せるので安心してやってみてください。

 作業用ブランチの作成

さて、これでプロジェクトのsvnリポジトリの完全なクローンが、手元にgitリポジトリとして作成されました。

もし、自分の割り当てられているタスクにsvnのブランチが割り当てられているなら、まずそちらに移動しましょう。

仮にブランチ名が ver02 だったとすると、手順はこうなります。

$ git co -b ver02 remotes/svn/ver02

このコマンドでやったことは、

https://example.com/svn/repos/myproj/branches/ver02 にあるブランチを元にしたローカルブランチ ver02 を作成してワーキングツリーにチェックアウト

です。

git svn dcommit は、デフォルトの動作としてローカルブランチと同じ名前のリモートブランチにコミットしに行きます。

ブランチ名 ver02 を合わせるのは、自分の分かりやすさと同時にgit-svnのためでもあります。

 開発環境の準備

つぎにやることは開発開発の整備です。

まず、必要なgemやライブラリをそろえた後、チェックアウトしたワークツリーで開発ができる状態になるまでコードや設定ファイルを修正することになるでしょう。

Railsならdatabase.ymlやenvironment.rbの修正などです。

いろいろ環境を設定して、script/serverが動くようになったら、ワークツリーがどうなっているか確認してみましょう。

$ git st

いろいろ表示が出てきたと思います。

既存の変更したファイルは

# Changed but not updated:

というセクションに、新しく作成したファイルは

# Untracked files:

というセクションに表示されます。

 開発

開発をはじめましょう。

新しいコードを書き始める前に、まずブランチをきってそちらに移ります。

$ git co -b new_feature

すると、

M  ファイル名

というなにか見慣れた表示が出てくると思います。

これは、git st で

# Changed but not updated:

に表示されていたファイルです。

ワーキングツリー上では変更されているけど、リポジトリにはまだ反映されていないという状態です。

そのまま開発を続けて、一段落ついたらコミットします。

まず git st してみましょう。

# Changed but not updated:
# Untracked files:

両方のセクションに、自分がコードを書いたファイルが表示されています。

まず、Untracked files: の中にある、コミットすべきファイルをgitに教えてあげましょう。

$ git add ファイル名

次に、

$ git diff

として、自分の作業を思い返しながら変更点を見返していきます。

ここで思わぬ見落としや、作業の抜け、ミススペルなどを見つけることができます。

この「作業の振り返り」はなかなかあなどれないものがありますので、忘れずにやっておきましょう。

間違いを見つけたらすぐに diff を抜けてエディタを起動し、直してまた git diff に戻ります。

出てきたファイルごとに、これで大丈夫という状態になったら、

$ git add ファイル名

します。addされたファイルは、

# Changes to be committed:

というセクションに表示されます。また、addすると次から git diff には現れません。

git diff して確認 → OKならgit addというサイクルでひとつづつ片付けていくのがおすすめです。

あと、environment.rb など、リポジトリに変更をコミットしたくないファイルもありますね。

これは、git addをしないで

# Changed but not updated:

に置いたままの状態にします。

ここが、svnなどの普通のバージョン管理システムと違うgitの大きなメリットのひとつです。

すべての必要なファイルを git add したら、ローカルの new_feature ブランチにコミットしましょう。

$ git ci -m 'コミットメッセージ'

ここで記入するコミットメッセージは、特別なことをしない限りsvnのりビジョンログにそのまま送信されますから、

開発チームのルールに沿ったメッセージを書くようにしてください。

 作業ブランチからのマージと上流へのコミット

new_featureの作業が一通り終わってうまく動いているようなら、ver02ブランチに作業内容をフィードバックしましょう。

$ git co ver02
$ git merge new_feature

マージが終わったら、ver02 に new_feature で行った作業が反映されているはずです。

テストも通って、チームのコミット基準に達しているようなら、リモートのsvnリポジトリにコミットしましょう。

まず、

# Changed but not updated:

にあるファイルをワーキングツリーから片付けないといけません。

$ git stash

これで、stashと呼ばれるリポジトリ内の格納場所に、これらのファイルの変更が保存されました。

もう一度 git st してみると、ワーキングツリーがきれいになっていることが分かります。

さっきの消えてしまった変更はどこに行ったのか?

$ git stash list

これで表示される場所にあります。元に戻したい場合は、

$ git stash pop

でいつでも戻りますから安心です。

では改めて、コミット作業に戻りましょう。

$ git stash
$ git svn fetch
$ git svn rebase

まず、fetch/rebaseでリモートリポジトリの最新の状態を持ってきます。

ここでコンフリクトなどが起きていたらリポートされますので、 >>>>> ====== <<<<< のようないつものマーカーをみつけて衝突を解消してください。

衝突したファイルは、git上では unmerged な状態になっていますので、解消したら git add して、解消したことをgitに教えてやります。

衝突がすべて解決したら、あらためてコミットします。

$ git svn dcommit

これでうまくいけば、svnリポジトリに今回の作業 new_feature が反映されているはずです。

trac/redmineやほかのsvnクライアントツールなどで、無事反映されているか確認してみて下さい。

うまくいったようなら、また開発に戻るために、さきほどstashに片付けた変更を手元に戻しておきましょう。

$ git stash pop

もし、dcommit しようとしてエラーメッセージが出てしまっても大丈夫です。

作業内容はすべて git の new_feature ブランチに残っていますし、リモートのsvnリポジトリには迷惑がかかっていません。

深呼吸して落ち着いて、エラーメッセージを読んで、ググって、試して…体で git を覚えて行って下さい。

have a nice git hacking!

rufus-scheduler という、ちょっとかわいそうな子

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Webアプリとは、ユーザのリクエストに対してレスポンスを返す

アプリケーションですが、時にユーザのリクエストに関係なく

処理を行いたいシチュエーションが存在します。

そのような場合、通常「バッチ」と呼ばれるコマンドライン上で

動くアプリを作成します。

私は現在、Webアプリの開発にRailsを使っていますが、

Railsでは、下記のようにモデルとメソッドを指定すれば

特にバッチ用の各種インターフェイスを作成せずとも

Webアプリの設定をDRYに使い回して簡単にバッチを作成することができます。

ruby script/runner -e production ‘ModelClass.method(params)’

script/console コマンドと併せて大変重宝しています。

で、上記のようなバッチを「運用者のコマンドライン上での操作」という

人力を介さず、任意のタイミングで実行したいとき、*nix系OSの場合は

一般的にcronがよく使われます。

02 4 * * * rails_batch.sh

さて、ここで本題。

rufus-scheduler という gem  があります。

http://rufus.rubyforge.org/rufus-scheduler/

このgemは、Railsアプリにおいて以下の機能が行えるようになります。

あるモデルのメソッドに対して

・定期実行が可能(○秒/□分間隔)

・cronとしての予約処理が可能

詳しくは上のリンクを見てください。英語が苦手な方でも

Rails & cron がお分かりの方にはすぐに内容がつかめると思います。

さて、この rufus scheduler、従来の cron と比較してどのようなメリット/デメリットがあるでしょうか。

・記述が簡単

 ・Railsにおけるバッチ処理は基本的にモデルで完結するので、このような記法だとscript/runner よりもより簡潔に書ける

・処理が楽

 ・script/runner だと、いちいち、重たいRailsのプロセスを立ち上げるが、rufus-schedulerだと、rufus-schedulerが

 記述されたアプリ(プロセス)と同じpidで走るので立ち上げが軽い

・記述が柔軟

 毎秒/分ごとの処理の記述が、cronやwhile do hoge; sleep SLEEP_TIME; end よりも

 構造的に奇麗に記述できる。

と書くと、なかなか良い子のように思えるのですが、このrufus-scheduler、がっつり欠点もあります。

・つられて落ちる

 起動しているwebアプリが落ちるとき、webとは関係なく走ってほしいバッチ処理が走らなくなる。

・サブプロセスとして動く

 passengerなら問題になりませんが、mongrelで複数のプロセスを走らせているとき、それぞれのプロセスでschedulerが走り

 収集がつかなくなる。

といった具合に、長所が「あったらいいなぁ」というものに対して、欠点が「ゆるさない。絶対にだ」というものなので

どうしても、rufus-schedulerには出番がないわけです。

結構いいアプリだと思うのですがね。

不憫なやつです。

とりあえず自分がこれならいけるかも、と思うものは一つあります。

・クローラ

 あるバッチをバックグラウンドジョブで走らせる。そのバックグラウンドジョブで走らせているアプリの中で

 rufus-schedulerを使った処理を記述し、そのプロセスをkillするまで半永久的に

 ほぼ同じ動作を繰り返す。

例えば、クローラとか、WebAPIを叩く処理(例えばtwitterの最新の状態を反映するblogパーツ)

とかは、この処理を使うとぐっと記述しやすくなるのでしょうか。

以前はよく見かけたのですが、日本語の情報もさっぱり見つかりません。

誰かこの子の活躍の場、思いついた方、共有していただけますとありがたいです。

vim でメソッド単位で移動するコマンド

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

vim は色々なコマンドがありますが、色々ありすぎてなかなか覚えられません。

今回ご紹介の移動コマンド「メソッド単位で移動」も、便利っぽいけど

なかなか覚えていられないたぐいのものですので、メモがてら投稿します。

]m 次のメソッドの始めに移動


]M 次のメソッドの終わりに移動

[m 前のメソッドの始めに移動

[M 前のメソッドの終わりに移動

ぜひお試しください!

MacBookにCentOS5を入れてみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

会社で使っていたPCが壊れ、新しいPCを申請したらMacBookが来ました。ようこそ。

Macに慣れなかった為、Cent5を入れることに。

仮想サーバーとか、共存とかではなく、Macを全部消してCentを入れます。

WindowsPCにCentを入れる感覚で普通にインストールすると、普通に完了画面まで進みました。

なんだ、入るじゃん。と思いPCを再起動すると、フォルダにクエッションマークがついたアイコンが点滅していました。つまり駄目でした。

普通に入れるとブートローダーがうまく行かないらしい。

下記URLの記事通りにMacのCDでフォーマットしてからインストールしたらうまく入りました。

http://mobile-dev.izanagi-izanami.net/blog/?p=8

・MS-DOSファイルシステム、サイズ:0.1GB

ここがポイントですね。

私のMacだと0.1GBにならなくて7GBが最小単位でしたが、問題ありませんでした。

最後にMacを潰してCentを入れたメリットデメリットをご紹介。

とはいっても、まだあんまり使っていないのですが。

 メリット

(私は)開発しやすい。

なんといっても使い慣れたOSは使いやすいです。

本番環境に近い

クライアントのサーバーと近い環境で開発出来るのはバグが少なくなる気がします。

 デメリット

マウス、キーボードが一部使えない

MacBookに付いているキーボードに支障が出ています。

基本は使えますが記号系が一部互換性ないです。

致命的なのはパイプが使えません。history | grep hogeが入力出来ません。

別のキーボードを差して使っています。

Palm Pre アプリを作ってみよう (準備編)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

iPhone や Android を凌ぐとも言われる[要出展]スマートフォン、Palm Pre 向けのアプリケーションを作ってみましょう。

下記の解説は Mac を用いています。Windows 版はそのうち書かれることでしょう。

SDK インストール

Palm Developer Center より、VirtualBox と Palm webOS SDK をインストールします。

Eclipse プラグインのインストール

DoRuby! は Ruby の解説サイトらしいので、Eclipse ではなく Aptana を使ってみることにします。Aptana のインストール方法は aptanaのインストールと使い方について をご覧ください。

メニューの Help > Install New Software… を開きます。

Add… ボタンを押して出る画面の Location 欄に http://cdn.downloads.palm.com/sdkdownloads/eclipse-update-site/site.xml を入力。

Palm webOS SDK を選択し、Next を押します。その後色々聞かれますが OK ないし Yes ボタンを選んでいけばインストールが完了します。

Hello world アプリケーションを作る

メニューの File > Other… を選択。

Palm webOS > Hello World Application を選択。

実行してみる

アプリケーションフォルダに入っている Palm Emulator を起動します。色々ダイアログが出ますが適当に切り抜けてください。

Aptana に戻って実行ボタン(緑色の丸に三角が描かれたボタン)を押すと見事起動します。おめでとうございます!

さいごに

Palm Pre 端末が日本でも発売されることを願っています。

モバイルでの開発の際の識別ID取得の注意

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近モバイルでの開発をしていた際、各キャリアのユーザ識別IDを取得し、自動ログインをさせる機能を作成したことがあるのですが、その識別IDはいろいろとお約束があるらしく、少しハマったところなので、メモ書き程度にまとめてみます。各キャリア(DoCoMo、au、SoftBank)で取得できる端末識別ID・ユーザ識別IDについて、いろんな決まりごとがあるので、調べた範囲で書きます。
まずはDoCoMoからー

☆DoCoMo
DoCoMoでは、端末識別番号・iモードID・UID(公式サイトのみ)が取得できます。
・iモードID
URLのパラメータに「guid=ON」を付けると取得できる半角英数7桁の識別子。
公式サイトでなくても取得出来ますが、SSL対応しているページでは取得出来ません。
・UID
DoCoMo公式サイトに限り、URLのパラメータに「uid=NULLGWDOCOMO」を付けると取得できる半角英数12桁の識別子。
これも、SSL対応ページでは取得できません。
また、「uid=NULLGWDOCOMO」となっていますが、「NULLGWDOCOMO」の部分は12桁の半角英数であれば、「NULLGWDOCOMO」である必要はないらしいです。

だから、UIDを取得するときは12桁かどうかのチェックが必要になりますね!

SSLページで取得出来ないというのは結構クリティカルでした。。。
ちなみに対応としては、SSLページへの遷移の前に1つアクションを挟む(iモードID・UIDが取得できるアクションで取得する)か、SSLページへのリンクに何かパラメータをつけて、そのパラメータが無いと自動ログインとしてみなさない、といった対応が必要です。
(セッション情報を用いた成りすましに注意!!)

au、SoftBankに関しては、また別途追記します。

findをする際にincludeを指定するとselectが無効になる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ActiveRecord(以下AR)のバージョンが低いとfindでincludeとselectの併用ができません。

※確認バージョン:1.14.4

下記findを実行するとidだけの結果を取得することができます。

Hoge.find(:all, :select => "id")

ただ古いARでincludeオプションを含めて実行するとselectが効きません。

Hoge.find(:all, :select => "id", :include => :foo)

対応策としてはincludeの代わりにjoinを使うことで回避をすることはできます。

冗長になってしまいますが。

ARのバージョンが新しければ問題無く動作します(2.1で確認)

100段階のレベル調整が出来る将棋アプリ「金沢将棋レベル100」

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

さて、突然出来たiPhoneアプリレビューコーナー。今回は筆者の趣味によるチョイスで「金沢将棋レベル100」を紹介します。昔からあるコンピュータ将棋の老舗、「金沢将棋」のiPhone版です。

名前からも分かる通り、本アプリの特徴はコンピュータの強さを100段階!に調節できることです。レベル1だと定跡も使わず、ほぼランダムで動かしているような印象。レベル100だとアマチュア初段ぐらいの力はありそうです。

コンピュータとの対局に勝つと、手合い(ハンデ)に応じてメダルが貰えます。飛車角を落として勝つと玉メダル。 また、貰ったメダルに応じて、使える盤・駒が増えていきます。メダルの一覧を一つずつ埋めていくのが地味に楽しいです。

個人的にはiPhoneの将棋アプリは盤の見やすさと駒の操作性が勝負と思っていますが、本アプリではメニューが簡潔に表示されていて盤が広く取ってありとても見やすく、操作もストレス無くスムーズに行えます。デフォルトではタップするとズームするようになっていますが、設定でズームをOFFにしたほうが操作がしやすいかもしれません。

さて、本アプリのメイン機能であるコンピュータとの対局も期待通りのクオリティですが、 さらに本アプリを良くしているのが、棋譜の保存とメール送信機能です。

単にコンピュータとの対局を保存してメールするだけならそれほど便利ではありませんが、自由に棋譜が入力できる対人戦モードを利用すると、外出先で指した将棋の棋譜を入力して、メール送信する事が出来ます。

しかもうれしい事に棋譜の形式は、通常テキスト形式とCSA形式から選ぶ事が出来ます。CSA形式はコンピュータにとって読み易い形式で、読み込み対応しているアプリケーションが多いため、他のアプリケーションにデータをインポートし易くて便利です。棋譜を管理できるiPhoneアプリもありますが、このアプリだけでも手軽に棋譜が保存できますね。

ご購入はこちらからどうぞ。金沢将棋レベル100

SWFバイナリ解析

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。エンジニアの はる です。
今回はちょっとだけマニアックにswfのバイナリ解析方法について書いてみたいと思います。

バイナリって何となく苦手意識のある方も多いかと思いますが、swfのバイナリ解析は数パターンの計算方法だけ抑えてしまえば意外と素直に読み解けてしまいます。

文系大学出身&英語が読めない私でも大丈夫だったので、興味のある方は是非!

用意するもの

バイナリエディタ

まずはバイナリファイルを閲覧・編集できる環境を用意します。

バイナリエディタは様々なものがありますが、自分の環境や好みに合わせて選んでみてください。代表的なものを下記します。

1. バイナリモードでswfファイルを開く
vi -b hoge.swf
2. テキスト形式から16進数ダンプ形式に変換
:%!xxd
3. 16進数ダンプ形式からテキスト形式に変換
:%!xxd -r

解析用SWF

解析するためにはSWFファイルが必要です。適当にSWFをパブリッシュして用意しておきましょう。
※今回の記事では、非圧縮のSWFをもとに解説させていただきます。解析用SWFは、「ファイル」→「パブリッシュ設定」→「SWF設定:ムービーの圧縮」のチェックをはずしたものをパブリッシュしましょう。

基数変換の基礎知識

解析中に2進数・10進数・16進数の相互変換が沢山あります。このあたりの計算方法は事前に覚えておくか、基数変換を簡単に行えるWEBサイトやソフトが沢山ありますので、用意しておきましょう。

以上の用意ができたら、解析用SWFをお好きなバイナリエディタで開けば、準備完了です。

SWFフォーマット

SWFのバイナリは下記のような形式で構成されています。
ヘッダ(header、header_movie)に基本情報が格納されており、コンテンツ(tag block)にシェイプやスクリプト等のコンテンツ情報が順々に格納されています。

SWF
header(8バイト)header_movie(可変長)tag block(可変長)tag block(可変長)..end tag
圧縮有無(3バイト)SWFのバージョン(1バイト)ファイルサイズ(4バイト)ステージの幅・高さ(可変長)フレームレート(2バイト)_rootのフレーム数(2バイト)TLC構造(可変長)TLC構造(可変長)2バイト

ヘッダ

まずはヘッダから読み解いていきましょう。ヘッダから読み取れる情報は以下の6種類です。

ヘッダから読み取れる情報

  1. 圧縮されているかどうか
  2. Flash Player のバージョン
  3. ファイルサイズ
  4. ステージの幅・高さ
  5. fps(frame per second)
  6. _rootのフレーム数

上記の情報が格納されているヘッダの構成は以下のようになっています。

ヘッダのバイナリフォーマット

ヘッダ
header(8バイト)header_movie(可変長)
圧縮有無(3バイト)SWFのバージョン(1バイト)ファイルサイズ(4バイト)ステージの幅・高さ(可変長)フレームレート(2バイト)_rootのフレーム数(2バイト)

それでは実際にバイナリを読み解いていきましょう。1バイト目から順に解説していきます。

バイナリ詳解

1. 1〜3バイト(長さ:3バイト)

SWFが圧縮されたものがどうかを判別します。

16進数説明備考
46 57 53圧縮されていないSWFFWS
43 57 53圧縮されたSWF(※SWF6以降のみ)CWS

CWSの場合、8バイト以降がZLIB圧縮されていることを示しています。この場合、8バイト以降をZLIB展開する必要があります。
※以降の解説はFWSの前提ですすめさせていただきます。

2. 4バイト目(長さ:1バイト)

SWFのバージョンが格納されています。以下の例の場合、SWF7形式であることが分かります。

16進数説明備考
07SWFのバージョン

3. 5〜8バイト(長さ:4バイト)

swfファイルのファイルサイズが格納されています。ただし、数値はリトルエンディアン形式で格納されているため、注意が必要です。

16進数説明備考
ec 52 01 00ファイルサイズリトルエンディアン形式

<計算方法>1. バイトスワップ

ec 52 01 00
逆順00 01 52 ec

2. 10進数に変換

1.の結果(16進数)000152ec
10進数86764

3. ファイルサイズ = 86764 byte

4. 9バイト〜(長さ:可変長)

ステージの幅・高さが格納されています。ただし、数値はRECT構造体で表現されているのに加え、単位はTWIPSのため、注意が必要です。

16進数説明備考
70 00 09 60 00 00 96 00 00 …ステージの幅・高さRECT構造体で表現。単位はTWIPS(トゥイップ)

<計算方法>1. 2進数に変換

16進数70 00 09 60 00 00 96 00
2進数01110000 00000000 00001001 01100000 00000000 00000000 10010110 00000000 00000000

2. 最初の5ビットを10進数に変換

2進数01110
10進数14

3. 2.の結果毎に6ビット目以降を区切る(余りのビットは捨てられます)

最初の5ビット14ビット14ビット14ビット14ビット余りのビット
01110000 00000000 00001001 01100000 00000000 00000000 10010110 00000000

4. 3.の結果を10進数に変換

X座標の最小値X座標の最大値Y座標の最小値Y座標の最大値余りのビット
16進数00000000000000010010110000000000000000000001001011000000000
10進数0480004800

5. 4.の結果がtwipのため、ptに変換(1pt=20twips)

X座標の最小値X座標の最大値Y座標の最小値Y座標の最大値
twips0480004800
pt02400240

6. 縦幅 = 240px, 横幅 = 240px

5. 長さ:2バイト

フレームレートが格納されています。

16進数説明備考
00 08フレームレート逆順にした結果の1ビット目が整数部、2ビット目が小数部

<計算方法>1. バイトスワップ

00 08
逆順08 00

2. 整数部、小数部を10進数に変換

1.の結果(16進数)08.00
10進数8.0

3. フレームレート = 8 fps

6. 長さ:2バイト

_root(メインタイムライン)のフレーム数が格納されています。

16進数説明備考
14 00_rootのフレーム数リトルエンディアン形式

<計算方法>1. バイトスワップ

14 00
逆順00 14

2. 10進数に変換

1.の結果(16進数)00 14
10進数20

3. _rootのフレーム数 = 20

ヘッダの解析はこれで終了です。SWF解析の肝は次バイトからのコンテンツ(tag block)ですが、これはヘッダ解析で行った計算方法の応用です。

ここから先は、tagの種類毎にtag blockの構造が異なるため、Adobe社が配布している『SWF file format specification』を片手にtagの種類を特定し、それに合った計算方法で解析していくことになります。

今回は一例として、ヘッダに続くtab block(SetBackgroundColor)の解説を行います。

コンテンツ

コンテンツのバイナリフォーマット

  • コンテンツは tag block毎に続き、tag blockは[ tag | length | contents ]の構造(以下、TLC構造)となる。
  • tag block の構造は2種類存在し、”「length < 3f」の場合”と”「length >= 3f」または特殊形式の場合”で異なる。

1. タグ形式1(※「length < 3f」)の場合

コンテンツ
tag block(可変長)
record header(2バイト)contents(lengthバイト)
tag(10ビット)length(6ビット)contents(lengthバイト)

2. タグ形式2(※「length >= 3f」または特殊形式)の場合

コンテンツ
tag block(可変長)
record header(6バイト)contents(lengthバイト)
tag(10ビット)3f(6ビット)length(4バイト)contents(lengthバイト)

バイナリ詳解

16進数43 02 ff ff ff ff 0a 05 00 00 00 69 6e 69 74 00 3f 03 3a 03 00 00 88 06 01 1e 00 00 …
2進数01000011 00000010 11111111 11111111 11111111 11111111 …

1〜2バイト(長さ:2バイト)

16進数説明備考
43 02tag(10ビット)+length(6ビット)リトルエンディアン形式

<解析方法>1. バイトスワップ

43 02
逆順02 43

2. 2進数に変換

16進数02 43
2進数00000010 01000011

3. 10ビット、6ビットに分割

taglength
0000001001000011

4. 『SWF file format specification』のp.271〜p.273をもとにtagの種類とlengthを算出する

2進数10進数結果
タグ種別00000010019SetBackgroundColor
length00001133

5. タグ形式2(※「length >= 3f」または特殊形式)の場合、続く4ビットを取得し、lengthを算出する6. 続くlengthバイトを取得し、『SWF file format specification』の各タグ処理の記載に沿って解析
※SetBackgroundColorの場合

RGBff ff ff

※setBackgroundColorは、必ずコンテンツの先頭に位置し、「長さ:5バイト」となる

setBackgroundColor(5バイト)
tag(1バイト)length(1バイト)RGB(3バイト)

あとはtagの種類毎に決められたフォーマットで解析していき、順々にコンテンツ(tag block)を解析していきます。
このswfのバイナリ構造を抑えておくと、例えば、Flash単体では通常取得することが困難な情報をバイナリレベルでswf内に埋め込んでから出力するアプリケーション開発したり、swfmillで出力されるxmlフォーマットもバイナリ構造と近いので理解しやすくなったりします。 皆さんもちょっとアブノーマルなバイナリの世界にいかがでしょうか?

tritonn(MYSQL+Senna)で全文検索。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

MYSQLで高速な日本語全文探索を実現するため、tritonnでMYSQL+Sennaにする。
■tritonnとは?
MySQLから全文検索エンジンSennaを利用可能にするための改造を行うプロジェクトのこと。

■Sennaってなんなの?
Sennaは組み込み型の全文検索エンジン。

■Sennaの特徴
 ・組込み型
  MySQLに組み込んで使用する為、MySQLがアプリケーションからSennaを隠蔽します。
  開発者の方はSQL文を操作するだけで、全文検索を実行できます。
 ・高速
  キーワードがテキスト内のどの位置にあるかという位置情報を持った、
  完全転置インデックスを採用している為、フレーズ検索においても高速な検索が可能です。
 ・即時検索
  作成したインデックスに対して、インクリメンタルに文書の追加/変更/削除の操作を加えることができるため、
  文書に次々と変更が加えられる場合にも、一度作成したインデックスを作成し直す必要がありません。

■なんでSennaをいれる必要あるの?
1. MySQLには日本語環境で使用するための十分な全文検索機能ができない。
 ・MySQLのFULLTEXTインデックスのキーワード抽出を行うパーサが、
 「半角スペースで区切られているものをキーワードとして認識する」という実装になっているため。
   ・LIKE演算子による部分一致検索は可能だが、インデックスを一切使用することができなくなってしまうため、
  テーブルのフルスキャンが発生します。
2. MYSQLでは全文検索を行うための実装面での十分な高速化が行われていない。

■toritonn 導入について
toritonnのダウンロードについて
http://qwik.jp/tritonn/download.html
toritonnのユーザガイド
http://qwik.jp/tritonn/userguide.html

■tritonnの2ind機能(2インデックス同時使用機能)
MySQLではクエリを実行する際、1つのテーブルに対してFULLTEXTインデックスと他のインデックスを組み合わせて利用することができません。
従ってFULLTEXTインデックスを用いる用いた場合、以下のような問題が生じます。

1. limit指定で出力を制限しても応答が遅い問題
2. count(*)等で件数を取得するだけでも応答が遅い問題
3. 全文検索以外の条件で絞り込む処理が遅い問題
4. 全文検索以外の条件でソートする処理が遅い問題

上記の問題を解決するために、MySQLが全文検索用のインデックスと通常のインデックスの両方を併用できるようにするのが2ind機能です。

■2ind利用法
Tritonnパッチをあてると、MySQLのサーバ変数(SESSIONスコープ)に”senna_2ind”という変数が追加されます。

下記のどちらかの方法で、2ind機能の利用を動的にOn/Offすることができます。

・my.cnfあるいはmysqldの起動オプションで”–senna-2ind”を指定する。
・SETコマンドでONを設定してください。→ mysql> SET SESSION senna_2ind=ON;

以下、公式より2ind機能使用について、注意書きがあります。

注意:2ind機能はまだ安定度合いとしてはβ段階にあります。
   実際に利用する前に有効かどうか、利用環境で問題は無いかどうかをご確認の上、使用してください。

■参考文献

■Senna 組み込み型全文検索エンジン
http://qwik.jp/senna/FrontPageJ.html
■toritonnプロジェクト
http://qwik.jp/tritonn/
■toritonn ユーザガイド
http://qwik.jp/tritonn/userguide.html
■MySQLで全文検索 – FULLTEXTインデックスの基礎知識
http://www.tatamilab.jp/rnd/archives/000389.html

場所を覚えられない人必見!?「ここメモ!」を試しました

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回は、場所を覚えられない人必見の「ここメモ!」を試してみました。

自分も一度行ったところを忘れてしまうタイプなので、周辺情報など記録しておくと便利!?

起動すると、GPSが動きますが現在地を地図上に表示してくれるので、 後はタイトルと写真を写して保存する。いちいち場所入力せずに済むのでとても便利です!!

ここメモ!情報詳細画像

録音機能もあるので、音声でコメントなんか吹き込んでおいたり、特徴的な音を録音しておくと更に分かりやすいかも・・・

ここメモ!一覧

登録した場所なんかは、登録日を軸として日別/週別/月別にリストで表示されます。

ここメモ!一覧(週別)

まだ使いこなせてないのですが、登録日を軸として表示ではなく、全てのリストを表示して欲しいなと思いました。

ここメモ!地図から検索

地図からのピン検索などユニークな検索もあったので、面白いです。

色々な場面での話題にもなりそうなので重宝しそうです。

iTunesのリンク貼っておきます!!こちらからどうぞ

ここメモ!

Ruby1.9でRailsる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Ruby1.9 で Rails2.3 を動かす方法を紹介します。

 今回の環境

  1. Ruby1.9.1p376
  2. Rails2.3.5

 はじめに

Ruby1.9 を Rails で動かす上で、一番頭を悩ませる問題が、

incompatible character encodings: ASCII-8BIT and UTF-8

というエラーかと思います。

Ruby1.9 から String に Encoding を持つようになりました。

これにより異なる Encoding 同士では、比較・結合を行うことができず、上記のようなエラーが発生してしまいます。

これは、Magic Comment で script encoding をUTF-8で指定しても、DB の Encode を UTF-8 に指定しても発生してしまいます。

これには色々と原因があるのですが、大きくは ActionView のレンダリング時に、ASCII-8BIT で出力される部分があるのが問題となります。

通常、Ruby1.9 でコーディングする際には、Magic Comment を記述し、script encoding を明示します。

この方法だけで、基本的な1ファイルでの View のレンダリングは問題なく行えます。

しかし、partial や layout を利用して、複数の View を組み合わせた場合に、問題が発生します。

ActionView は、内部的に読み込んだ View ファイルを buffer に格納し、順次結合していきますが、

buffer の Encoding が、partial した View と結合される際に、ASCII-8BIT となってしまうため、エラーが発生するようです。

 ActionView にパッチを当てる

ということで、ActionView にパッチを当てます。

View ファイルを読み込み、順次結合してる部分に問題があるので、その部分を UTF-8 に Encode するように指定します。

パッチを当てる方法は何でもいいのですが、今回は alias_method_chain を使った方法で記述します。

下記コードをlib以下などに格納して、起動時に読み込まれるようにします。

action_view/renderable.rb

# -*- coding:utf-8 -*-
module ActionView
  module Renderable
    private
    def compile_with_magic_comment!(render_symbol, local_assigns)
      locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join

      source = <<-end_src
        # -*- coding:utf-8 -*-
        def #{render_symbol}(local_assigns)
          old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
        ensure
          self.output_buffer = old_output_buffer
        end
      end_src

      begin
        ActionView::Base::CompiledTemplates.module_eval(source, filename, 0)
      rescue Errno::ENOENT => e
        raise e # Missing template file, re-raise for Base to rescue
      rescue Exception => e # errors from template code
        if logger = defined?(ActionController) && Base.logger
          logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
          logger.debug "Function body: #{source}"
          logger.debug "Backtrace: #{e.backtrace.join("\n")}"
        end

        raise ActionView::TemplateError.new(self, {}, e)
      end
    end
    alias_method_chain :compile!, :magic_comment
  end
end

actionpack/lib/action_view/renderable.rb の68,69行目に Magic Comment を追加するだけです。

このパッチだけで、レンダリング時の Encoding の問題はほぼ解決できるのですが、

次に問題になってくるのが、日本語の文字列をフォームから GET で送信した場合です。

この場合は、

incompatible character encodings: UTF-8 and ASCII-8BIT

というエラーが発生します。

これは、送信されたデータを text_field などに再セットする場合に発生します。

UTF-8 の view に対して、ASCII-8BIT の文字列を結合しようとしているのがエラーの原因となります。

どうやらこの問題は Rack::Utils.unescape にあるようです。

Rack は、URL をデコードする際に、マルチバイト文字列を ASCII-8BIT として Encode してしまいます。

POST も同様に Form データの parse 時に同様の問題が発生しますが、GET と同じ対応で対処することは可能です。

ただし、POST の場合はこれだけでは解決せず、multipart 指定のフォームについては別途対処する必要があります。

multipart 用の parser である、Rack::Utils::Multipart.parse_multipart の戻り値の文字列は ASCII-8BIT となってしまうので、こちらも別途対処する必要があります。

上記の問題は、Rack にパッチを当てることで解決することは可能です。

ただし、この挙動自体は Rack としては正しい動作ではあります。

Encoding の問題はアプリケーション側で解決すべきで、Rackは関知すべきではないからです。

 ActionControllerにパッチを当てる

ということで、上記の問題を解決するパッチを ActionController に当てます。

パッチの適用方法は ActionView と同様です。

action_controller/request.rb

# -*- coding:utf-8 -*-
module ActionController
  class Request
    private
    def normalize_parameters_with_force_encoding(value)
      (_value = normalize_parameters_without_force_encoding(value)).respond_to?(:force_encoding) ? 
         _value.force_encoding(Encoding::UTF_8) : _value
    end
    alias_method_chain :normalize_parameters, :force_encoding
  end
end

actionpack/lib/action_controller/request.rb の472行目の normalize_parameters を修正します。

これにより、アプリケーションのコントローラでparamsを利用する時点で、リクエストパラメータに含まれる文字列は、UTF-8 に Encode されているので、view との結合も問題なく行うことができます。

 最後に

今回紹介した ActionView、ActionController を修正する方法で、Ruby1.9 上で Rails2.3 系をとりあえず動かすことはできそうです。

ただし、利用するプラグインやAPサーバによっては、別途対応が必要な場合があるようです。

SourceForge.JP のプロジェクトを Subversion から Git へ移行する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


たろちゃんです。SourceForge.JP のプロジェクトをSubversionからGitへ移行しましたのでその時に記録から手順を紹介します。

僕が現在開発しているエレコマSourceForge.JPにてホスティングを行っており、開発リソースをすべて一元管理しております。

開発当初、弊社内のレポジトリがSubversionであった事や僕自身にSubversionの運用ノウハウがあったことからSourceForge.JPでもSubversionを採用していました。

しかしながら、Railsのプロジェクトという特性からか、何人かgit-svnを利用している方がおり、また開発に集中するという意味でもGitの方が魅力的であるため、今回SubversionからGitへ移行しました。

まずはGit自体を有効にします。Gitを有効にするためにはSourceForge.JPへ管理者としてログインしてからプロジェクトのメニューの「管理」から「プロジェクト情報変更」を選択して「プロジェクト情報変更画面」を出します。この中にある「利用する機能」にあるGitを利用のチェックボックスを有効にして情報を保存します。

続いてプロジェクトのメニューの「ソースコード」から「Git管理」を選択して、「新規Gitレポジトリを作成」というリンクを辿り、必要な情報を入力をしてGitレポジトリを作成します。数分のち、作成済が解除され、レポジトリが有効になります。

エレコマの場合は以下の内容で生成されました。

git clone tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git

では、さっそく移行作業を開始しましょう。

まずは作業用ディレクトリを作成し、移動します。

$ mkdir -p ~/develop/elecoma/tomove_git
$ cd ~/develop/elecoma/tomove_git

次にgit svn cloneを使ってSubversionのデータをすべて取得します。–prefixには svn/ を追加してリモートレポジトリをわかりやすくします。

$ git svn clone --prefix svn/ -s svn+ssh://tmatsuzawa@svn.sourceforge.jp/svnroot/elecoma/

そしてgit remote add を使ってSourceForge.jpのGitレポジトリを追加します。リモートレポジトリの名前はoriginとします。

$ cd elecoma
$ git remote add origin tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git

あとはmasterの内容をリモートレポジトリ(origin)へ push します。念のため –dry-run をつけて内容を確認しておくとよいでしょう。

$ git push origin master --dry-run
(初回実行時にgit.sourceforge.jpをsshのknown_listへ追加するか確認されます)
To tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git
 * [new branch]      master -> master
$ git push origin master
Counting objects: 2581, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2504/2504), done.
Writing objects: 100% (2581/2581), 6.94 MiB | 2.83 MiB/s, done.
Total 2581 (delta 1006), reused 0 (delta 0)
To tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git
 * [new branch]      master -> master

以上で、masterの内容をリモートレポジトリへすべて push しました。しかし、エレコマではリリースごとに tag を切っていますので、こちらも反映します。

Subversionでの tag はGitにおいては branch に相当します。まずはリモートの branch を確認します。

$ git branch -r
  origin/master
  svn/1.0.x
  svn/tags/1.0.6
  svn/tags/1.0.7
  svn/tags/release-1.0.1
  svn/tags/release-1.0.2
  svn/tags/release-1.0.3
  svn/tags/release-1.0.4
  svn/tags/release-1.0.5
  svn/trunk

この場合は svn/tags/release-1.0.1 という branch がGitにおける tag に相当します。なので、branch に移動して tag を切ってそれを push していきます。

$ git checkout svn/tags/release-1.0.1
$ git tag 1.0.1
$ git push --tags origin --dry-run
To tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git
 * [new tag]         1.0.1 -> 1.0.1
$ git push --tags origin
Counting objects: 1, done.
Writing objects: 100% (1/1), 266 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git
 * [new tag]         1.0.1 -> 1.0.1

これで tag が切れました。他の tag も同様に作業をしていきます。

$ git checkout svn/tags/release-1.0.2
$ git tag 1.0.2
$ git push --tags origin
Counting objects: 2, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 454 bytes, done.
Total 2 (delta 1), reused 0 (delta 0)
To tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git
 * [new tag]         1.0.2 -> 1.0.2

.
.
.

$ git checkout svn/tags/1.0.7
$ git tag 1.0.7
$ git push --tags origin
Counting objects: 1, done.
Writing objects: 100% (1/1), 259 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To tmatsuzawa@git.sourceforge.jp:/gitroot/elecoma/elecoma.git
 * [new tag]         1.0.7 -> 1.0.7

以上ですべての tag が切れました。

あとは、別のディレクトリで git clone をして確認をしましょう。

なお、エレコマでは 1.0.x という branch も存在していましたが、 git ではリリースされたものに対しては branch を用意する必要がないためこのままにしておきます。必要に応じて、以下のようにして branch を作成して作業をするとよいでしょう。

$ git branch RB_1.0.7_1 1.0.7

なお、このテクニック自体はSourceForge.JP以外でも使えると思います。SubversionからGitに移行を検討している方はぜひ参考にしてください。

さて、これで2.x系の開発が…はかどるといいなぁ…

WEBサーバ2台構成でpoundによるLBを行う例

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


WEBサーバ2台構成でpoundによるLBを行う例を書きます。

 WEBサーバ2台構成でpoundによるLBを行う例を書きます。

サーバの情報など

web-vip : 10.0.0.10

web1 : 10.0.0.11

web2 : 10.0.0.12

今回の例ではpoundをweb1に設置し、負荷分散先をweb1、web2とします。

設定方法としては、poundでport80をListenし、web1のport8000、web2のport80へLBする。

という感じです。

poundの設定です

ListenHTTP

Address 10.0.0.10

Port 80

Service

BackEnd

Address 10.0.0.11

Port 8000

End

BackEnd

Address 10.0.0.12

Port 80

End

End

End

以上の設定で完了です。

必要に応じて負荷分散の割合を変更することができますので、

様子をみてweb1の分散を減らしてあげる必要があるかもしれません。

また、インストールに関しては、下記エントリーが大変参考になりました。

http://doruby.kbmj.com/curi/20100313/Pound_HTTP_2048kb_

あと、poundをweb1のみに設置している理由はListenのAddressの重複が許されていないが為です

なのでpoundが落ちた場合などはweb2へvipをうつしますので、web2は80でlistenしてます

mod_rpafを使ったIPアドレスのアクセス制限

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

mod_rpafを使ったIPアドレスのアクセス制限に悩まされたので紹介します。

リバースプロキシ(pound)などを使った環境でapacheのアクセスログに

出力されるIPアドレスがプロキシサーバのIPになる問題を解決するために利用されるmod_rpafですが、

ログの問題はクリアしたところで、IPアドレスを使ったアクセス制限が機能しない問題に悩まされました。

今回利用したmod_rpafのバージョンは0.6です。

apache2.2.xの環境で試しています。

インストール方法は割愛です。

インストール後に以下のような設定ファイルを記述します。

LoadModule rpaf_module modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname Off
RPAFproxy_ips <プロキシサーバのIPアドレス>

「Allow from」にIPアドレスを記載したアクセス制限は機能しなかったのでRewriteCondを使った制限に書き換えました。

Order deny,allow
Deny from all
Allow from xxx.xxx.xxx.xxx

RewriteCond %{REMOTE_ADDR} !^XXX\.XXX\.XXX\.XXX$
RewriteRule ^.*$ - [F,L]

mod_rpafのソースまでは見ていないですが気付き難いですね。

当然mod_authとmod_rewriteで扱う変数が違うのでしょう。

Ruby On Rails 正規表現で改行を探す

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ども、 rick No.17です。
今回は正規表現で以外とはまりがちというか忘れがちなことについて書きます。Railsのvalidateの一つである
validates_format_ofを使用している時にちょっとはまりました。

前提

こんな記事があるとします
hoge
hogehoge

しかし、開発者は改行を付けてほしくない。
なので改行をした記事は、投稿できない様にしたいわけです。

問題

$vi app/models/hoge.rb
class Hoge < ActiveRecord::Base
validates_format_of :body, :with => /^[^\r\n]*$/, :message => “は、改行禁止です”
end

記事のカラムはbodyカラムで、改行禁止の正規表現を書いたつもりでした。。が、、、、
全然問題なく改行しても登録されてしまう。。。

なぜか???

解説

答えは^と$でした。
^は行頭、$は行末であり文の先頭から最後ではない。
つまり改行前の「hoge」と改行後の「hogehoge」しか見てくれない為、
改行の\nはマッチしない。
hoge\n
hogehoge

上記の下線部分しかみてくれないわけですね。

解答

では、どうすればいいか?
\Aと\zを使用すればいいのです。
\A\zは改行を無視して文頭、文末を見てくれるので一文の中から改行の有無を探してくれます。
$vi app/models/hoge.rb
class Hoge < ActiveRecord::Base
 validates_format_of :body, :with => /\A[^\r\n]*\z/, :message => “は、改行禁止です”
end

あぁそういえばそうだね。といったかんじですが、
なにげに忘れてしまいがちなので覚えておきましょう。

undefined method `fdiv’ for 0:Fixnum

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

急にタイトル通りのエラーが出てしまいました。

ruby-1.8.6にてgemいじってたら

% gem install rails -v=1.2.6




  WARNING:  RubyGems 1.2+ index not found for:


RubyGems will revert to legacy indexes degrading performance.
        Updating metadata for 1 gems from http://gems.rubyforge.org/
           .
complete
                                                                                                ^U
Bulk updating Gem source index for: http://gems.github.com/
Successfully installed activesupport-1.4.4
Successfully installed activerecord-1.15.6
Successfully installed actionpack-1.13.6
Successfully installed actionmailer-1.3.6
Successfully installed actionwebservice-1.2.6
Successfully installed rails-1.2.6
6 gems installed
Installing ri documentation for activesupport-1.4.4...
ERROR:  While executing gem ... (NoMethodError)
    undefined method `fdiv' for 0:Fixnum

な事をいわれてしまいました。インストール自体はできている模様なので問題なさそうですが、ドキュメントのインストールでこけてます。たぶん。その場しのぎの回避策で~/.gemrcに

install: --no-ri --no-rdoc
update: --no-ri --no-rdoc

とか書いてみました。

根本的な解決になってないですが気が向いたらまたおってみます。

最近人気な記事