ブックマーク的メモ
OS XやiOSでグラフを描くときに使えそうなframwork
Archive for the ‘プログラミング’ Category
REXMLの文字エスケープに関するバグ
REXMLを使用してXMLを作成するとき、Elementに子ノードを追加する場合にadd_elementを使用し、同時に属性値も追加していた。しかし何故か&がエスケープされなかった。’はエスケープされるけど。以下コードで調べてみたら、add_elementで属性追加するとエスケープされないけど、add_attributeで追加するとエスケープされることが分かった。
require 'rexml/document' value = "<>&\'\"" sample = REXML::Element.new("a") sample.add_element("b", {"attr" => value}) c_tag = sample.add_element("c") c_tag.add_attribute("attr",value) xml = "" formatter = REXML::Formatters::Pretty.new formatter.compact = true formatter.write(sample, xml) puts xml
実行結果
<a> <b attr='<>&'"'/> <c attr='<>&'"'/> </a>
なぜ?
動作環境 Ruby 1.8.7
whenever の使い方
Railsアプリケーションで定期的に何かを実行したいという場合、wheneverを使用するという選択肢があるかと思います。wheneverは要するにLinuxのcronの設定をrubyから行えるというもの。environment.rbの設定も引き継いだrubyスクリプトを実行できるので、DBへのアクセスも簡単。
まずはインストール。
sudo gem install whenever
Railsディレクトリで
wheneverize
を実行すると ./config/schedule.rb が作成される。このファイルにcron設定を書く。
schedule.rbの中には書き方のサンプルがあるので多分大丈夫。たとえば sample.rb ってスクリプトを1時間毎00分に動かしたいときは
every 1.hours, :at => 0 do set :output, {:error => 'log/error.log', :standard => 'log/cron.log'} runner './sample.rb' end
runner は ./script/runner のこと。
cron設定を反映するには
whenever --update-crontab
内容を確認するには
crontab -l
logをみて No such file or directory のエラーが出ている場合、runnerに書かれてるrubyのパスが間違っている場合があります。デフォルトが #!/usr/bin/env ruby となっているので、環境に合わせてパスを修正する必要があります。
iPhoneでmixiにOAuth認証のサンプル
随分と前になるけれど、mixiが個人にもAPIを公開しました。
iPhoneアプリの場合だと、公開された中のmixi Graph APIを使用する形になり、このAPIが提供する機能を使用するにはmixiに対してOAuth認証を行って、アクセストークンを取得する必要があります。
で、アクセストークンを取得するまでを作ってみた。githubに公開してます。
mixiOAuth
ユーザに認可させる部分はUIWebViewで。UIWebViewのDelegateでレスポンスのURLをつかまえて、クエリからAuthorization Codeを取り出します。そしてHTTPURLConnectionでPOSTし、レスポンスをjson frameworkを使ってparse、リフレッシュトークンとアクセストークンを取得します。
コードはなるべく"iOS開発におけるパターンによるオートマティズム" (木下 誠)にのっとって書いてるつもりなんだけど、まとまらないなぁ難しい。
GoogleにClientLoginしてみる
GoogleのAPIを使用するためにClientLogin処理、C2DMを使ってみたいのでRubyで実装してみました。ClientLoginで取得するのは他のサービスを使うために必要なAuthのパラメータなので、それを取り出す。
require 'net/https' require 'uri' auth_hash = Hash.new url = URI.parse("https://www.google.com/accounts/ClientLogin") https = Net::HTTP.new(url.host, url.port) https.use_ssl = true https.verify_mode = OpenSSL::SSL::VERIFY_PEER https.verify_depth = 5 req = Net::HTTP::Post.new(url.path) req.set_form_data({ :accountType => 'HOSTED_OR_GOOGLE', :Email => 'hogehoge@gmail.com', :Passwd => 'hogehoge', :service => 'ac2dm', :source => 'hogetest' }) https.start do res = https.request(req) if res.code == "200" res.body.split("\n").each do |data| key,value = data.split("=") auth_hash[key] = value end end end print auth_hash['Auth'] # => 必要なAuth
ziprubyでディレクトリごと圧縮
RubyでZipを作成する方法はざっと調べた限りziprubyとrubyzipあたりが使われているっぽい。とりあえずziprubyをチョイスして、ディレクトリを含めた圧縮を実装。
RailsでXMLをBuilderすると日本語が文字参照になる対策
RailsでXMLを生成・出力するので Builder::XmlMarkup を使ってみたんだけど、日本語が文字参照になっちゃって使い勝手がよくない。ちょっと調べてみたらStringクラスのto_xsメソッドが原因のよう。そこでto_xsメソッドを例えばenvironment.rbでオーバーライドしちゃう。
class String def to_xs ERB::Util.html_escape(self) end end
今のところ問題はない。
Ruby開発環境をLeopardからSnow Leopardへ変更したときにはまったこと
いまさらながらLeopardからSnow Leopardへアップグレードしました。最近はRuby..Ruby…な案件が多いのでRuby開発環境必須。
OSのアップグレード自体はクリーンインストールしてTime Machineバックアップからデータを移行することで簡単にできました。楽でした。しかしMacPortsは引き継げないようなので削除して再インストール。あと必要そうなmysql5とかモロモロいれる。
そしてRuby。MacにはRuby1.8.7がすでに入っていて、あとはgemでrailsとかsequelとかいれるだけと思っていたのに問題発生。gemのmysqlが全然動かない。それまでに作ったスクリプトからSequel使ってDBにアクセスしようとするとアウト。何度もインストールしてはアンインストールして・・・を繰り返してアウアウアー。さすがにちょっと分からないと思って、検索したらありがたいことにこのページに原因が。gemのmysqlだけは例外的なインストールをしなくちゃいけないらしい。
sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5
上記でgem mysqlいれてSequel使ってみたらいけました。
Universally Unique Identifier
暗号化をちょいと調べていて、128bitの暗号キーをじゃあどうやって生成しようかというときにやっぱキーとなるのはこの世に一つのものだ!と。でUUID。Microsoft的にはGUID(Global Unique Identifiers)。
encyclopediaによると、ほぼすべての言語でUUID生成クラスやらライブラリやらがあるみたい。とりあえずC++のooidをチョイスしてみた。ライセンスはBoost。
ooid-0.99.tar.gzを落としてきて展開すると結構さっぱりとした中身。GUIは必要ないのでcli.cppをg++でコンパイル。
$ g++ -I./ -lstdc++ -Wall cli.cpp -o cli $ ./cli 907c1709-7014-46bb-afa3-f80b5eb20e44
引数がいまいち分からんのだが・・・