ブログパーツ    carp_qr    まとめったー    deliciousブクマ数API

Ruby

RubyからEvernoteのAPIを使ってみよう

先日EvernoteのAPIを触る機会があったのでまとめておきます。EvernoteのAPIをうまく使えば、いろいろな情報を自動的に記録していくことも簡単に出来るのでなかなか良さげです。

Evernote

まず、EvernoteのAPIを利用するためにはOAuthで認証する必要があります。ただし、自分自身のアカウントに対する操作だけであればデベロッパートークンを取得するだけでOKです。

参考:認証 - Evernote Developers

Rubyからの利用にはThriftで実装された低レベルなevernote-sdk-rubyを使う方法もありますが、基本的には高レベルなラッパーであるevernote_oauthというgemを利用するのが良いでしょう。

evernote_oauthを使う場合、基本的な使い方はこんな感じでしょうか。
(以下の例ではデベロッパートークンを使ってます)

module EvernoteExtension

  # noteを作成する
  def save_to_evernote(title, content, tags, guid = default_notebook_guid)
    client = EvernoteOAuth::Client.new(:token => token)
    note_store = client.note_store

    note = Evernote::EDAM::Type::Note.new
    note.title = title
    note.content = render_to_string 'evernote_template', :content => content, :layout => false
    note.tagNames = [tags]
    note.notebookGuid = guid # どのnotebookにnoteを作成するか

    note_store.createNote(note)
  end

  # notebookのguidを返す
  def default_notebook_guid
    notebook = note_store.listNotebooks.select {|notebook| notebook.name == notebook_name }.first

    if notebook.present?
      notebook.guid
    else
      notebook = Evernote::EDAM::Type::Notebook.new
      notebook.name = notebook_name

      note_store.createNotebook(notebook).guid
    end
  end

  private

  def notebook_name
    "sasata299's notebook"
  end

  def token
    YOUR_DEVELOPER_TOKEN
  end

  def note_store
    @note_store ||= EvernoteOAuth::Client.new(:token => token).note_store
  end
end

この例だと、sasata299's notebookというnotebookにどんどんnoteが記録されていきます。

ただ、このevernote_oauthはRuby1.8では動作しないので注意してください。今回はRuby1.8で使いたかったのでRuby1.8に対応させてみました。利用は各自の責任でお願いします。

8に対応させた

東京Ruby会議10で行われたコードゴルフの解答例を紹介します

だいぶ遅くなってしまいましたが、先日東京Ruby会議10で行われたコードゴルフの結果発表を行いたいと思います!(パチパチ

コードゴルフ

問題は、「引数を二つ受け取って(最小値と最大値)、その間の数字に対してFizzBuzz問題を解いてください」というものでした。

例えばこういうことですね。
$ ruby fizzbuzz.rb 1 5
1
2
Fizz
4
Buzz

東京Ruby会議10「コードゴルフに挑戦!」〜最終順位発表 - blog.code.iq│CodeIQにて、景品プレゼントのために上位の方にはメールを送っていただき、その結果、1位がttakuru88さん、2位がtmtmsさんと決まりました(3位は該当者なし)。おめでとうございます!!

そこでせっかくなのでこのお二人とあとは特別解としてhokacchaさんの解答を紹介したいと思います。コードゴルフに参加した方も参加してない方も、ぜひ参考にしてみてください〜

まず1位のttakuru88さん。
eval(ARGV*'..').each{|i|puts"#{i}\r#{[:Fizz][i%3]}#{[:Buzz][i%5]}"}

続いて2位のtmtmsさん。
puts eval($**'..').map{|k|a=[[:Fizz][k%3],[:Buzz][k%5]]*'';a==''?k:a}

お二人とも最初に引数を配列で受け取ってそれに '..' という文字列を掛けています。何が行われているかわかるでしょうか。

実はArrayクラスで*メソッドを利用すると数値か文字列かによって挙動が変わるのです。
# 数値を渡した場合
[1, 2, 3] * 3
=> [1, 2, 3, 1, 2, 3, 1, 2, 3]

# 文字列を渡した場合
[1, 2, 3] * '3'
=> "13233" # [1, 2, 3].join('3') と同じ挙動

joinを使った方が(圧倒的に)わかりやすいですが、コードゴルフということでこんな書き方になっているんですね。

また、お二人引数の受け取り方が微妙に書き方が違いますが、実は引数を受け取る ARGV は $* でも同じ意味になります。これを使えばttakuru88さんのコードももっと短くなりますね :)

さらにこのようなコードが書かれてることに気付きます。
[:Fizz][i % 3]

これは :Fizz という要素をひとつだけ持つ配列に対してインデックスを指定しています。
[:Fizz][0 % 3] # => :Fizz
[:Fizz][1 % 3] # => nil
[:Fizz][2 % 3] # => nil
[:Fizz][3 % 3] # => :Fizz

コードゴルフは普段使わないような記法を使ったりするけど、頭の体操みたいで面白いですね!そんな書き方出来るのかー!!みたいな発見がきっとあると思います。

最後に特別解のhokacchaさん。http://690.jp/24にアクセスすると…w
eval `curl -sL 690.jp/24`

東京Ruby会議10と黒Ruby会議を終えて #tkrk10 #黒Ruby会議

千葉市美浜文化ホールで東京Ruby会議10が行われました。参加していただいた方、ありがとうございました。

"話そう、集まろう、いつものRuby、日常のRuby"
東京Ruby会議10 #tkrk10 - Regional RubyKaigi 会期:2013/01/13(日)〜14(祝・月)

東京Ruby会議10

微力ながらスタッフとして参加したんですが、印象に残っているうちにブログにまとめておきたいと思います。ブログを書くまでがRuby会議ですからね。

東京Ruby会議10

まずはお疲れさまでした!!二日目が雪の影響で14時に終了したりするハプニングもあったけど無事開催することが出来て良かったです。特に僕はスタッフ側の目線になっちゃうんですけど、裏方は何ヶ月も前から何度も集まって準備したり当日もいろいろやることがあったりで大変なんです。でも参加者のみなさんが楽しんでくれていたようで良かったー。やってよかったです。二日間あるのかと思ってたけどいざ始まっちゃうとあっという間でした :)

企画のひとつとしてバッジをみんなで交換して交流しましょうっていうものがあったんですけど、この中に入っていたささたつバッジが予想外にバズっていたのでびっくりしました。これ元ネタは「ビーチエンジニア」っていう写真で、ビーチでプログラミングしたっていうネタなんですけど、キーボードの中に砂が入ってしまって大変だったのが懐かしいなぁ。次の日Macのキートップを外して掃除してたんですよ…。

ビーチエンジニア


黒Ruby会議

ところで僕は一日目の夜に「黒Ruby会議」という企画を行いました。この企画がほんと大変だったんです。企画名しか決まってなかったので何を話してもらうのか、誰に話してもらうのか、すべてが未定でした。というか、僕自身も「ほんとにこの企画やるの?ネタじゃなくて?」と疑ってました。

最終的にはそうそうたるメンバーに集まってもらえて(無理矢理集めて)、自分も含めて10名が発表したんですが、みんな「何話したら良いの!?」っていう感じだったと思います。ほんと無茶ぶりすいません。リアルに黒くてこわい話もあったりしましたが、発表直前からみんな謎のテンションになり、楽しんでくれたようなので良かったです。この発表をつまみに今度打ち上げやりましょう。

そういえば同僚の @mrkn さんや @sora_h くんがヤジを飛ばしてくれたのでやりやすかった!お酒は一滴も飲んでなかったけど、飲んでいるときのようなテンションでしたw あと「結婚してください」っていうヤジ?も聞こえたけど どう考えても男の声だったので 丁重にお断りしましたm(_ _)m

導入部分だけですがスライド公開しておきます。




あと、舞台袖に発表者が全員いたんですけど、そこの雰囲気というか盛り上がりがかなり楽しかったです。これは発表者しか味わえない特典ですね。みんなでわいわいヤジを飛ばしつつキャッキャしながら聞いてるの楽しかったなー。あの雰囲気は最高でした。 @udzura さんのこの発言がいいですね!



最後に黒Ruby会議のtogetterまとめを置いておきます。空白の時間があるのは……そういうことです。面白かったからツイートする暇が無かったんでしょう!きっと!!

黒Ruby会議まとめ - Togetter

ということでみなさまありがとうございました!!!1

くろたつ
くろたつ photo by @sora_h

グラフ描くならMorris.jsがお手軽で良いかも

こんにちわ。寒くなってきましたがみなさまお元気ですか?

さて、先日ちょっとしたグラフを描画したかったんですよ。それでなにか使いやすいライブラリ無いかなーと思っていたら railscast (revisedなので有料です) で Morris.js ってjQueryプラグインが紹介されてて良さげだったので使ってみました。google analytics みたいなツールチップも出してくれます。

使い方はとっても簡単です。

まず、jQuery (>=1.7) と Raphael (>=2.0) が必要です。あとは Morris.js があれば動作します。
これらを app/assets/javascripts/application.js に設定してください。この記事執筆時点での Morris.js のバージョンは 0.3.3 でした。

//= require jquery
//= require raphael.min
//= require morris.min

これでもう使えます。

表示したいデータをこのような形式にしましょう。今回は日付とアクティブ、非アクティブの割合をデータとして持つとします。X軸が日付、Y軸がアクティブ、非アクティブの割合のイメージです。

@user_infos = UserInfo.scoped.map do |user_info|
{
  :date => user_info.date,
  :active_rate => user_info.active_rate,
  :inactive_rate => user_info.inactive_rate
}

あとはview側で適当なid要素を定義してください。値もそのdata属性に持たせるとすっきりして良いかなーと思います。

= tag :div, :id => 'chart', :data => { :user_infos => @user_infos.to_json }

あとはグラフを描画する処理を記述するだけです。例えば単純な線グラフならこのようになります。あ、このファイルもapplication.jsに追加するのは忘れないでくださいね。

jQuery ($) ->
  Morris.Line(
    element: 'chart' // グラフを描画するid要素
    data: $.parseJSON($(#chart).data('user_infos'))
    xkey: 'date' // X軸として使う値
    ykeys: ['active_rate', 'inactive_rate'] // Y軸として使う値
    labels: ['アクティブ', '非アクティブ']
    ymin: 0
    ymax: 100
    postUnits: '%'
    lineWidth: '5px'
    xLabels: 'day'
    hideHover: true
    lineColors: ['red', 'blue']
  )

そしたらこういう結果が得られるわけです。ツールチップも何気に嬉しいですね。

jsのグラフ例

ちなみに、以前は Line charts しか描けなかったんですが、最近激しくバージョンアップしていて、0.3.0で Donut charts、0.3.2で Area charts、0.3.3で Bar chartsと続々と対応してきています。これは期待できそう!

なんかメソッド名もわかりやすいしw
Line charts  -> Morris.Line
Donut charts -> Morris.Donut
Area charts  -> Morris.Area
Bar charts   -> Morris.Bar

詳しくはこちらをご覧ください〜。 Morris.js oesmith/morris.js

Rails3.1から導入されたAsset Pipelineがよくわかってなかったから調べた

Asset PipelineというのはRails3.1から追加された機能で、以下のような特徴を備えています。なかなか便利そうなやつです〜。

・cssやjsは各々一つのファイルにまとめられる(ブラウザのリクエスト回数を減らせる)
・それらのファイルは自動で圧縮/難読化される(ファイルサイズを減らして負荷軽減)
・ついでに、SassやCoffeeScriptを使ってcssやjsを記述することが可能になっている

ではどういった仕組みなのか見てみましょう。

例えばRails3.2.3で新しいアプリを作成したとします。このとき、Gemfileにはデフォルトでjquery-railsが指定されています。そしてapp/assets/javascripts/application.jsはこのように書かれていると思います。

//= require jquery
//= require jquery_ujs
//= require_tree .

application.jsではいろんなjsをrequireしていますが、ここで指定したファイルの中身が展開されて一つにまとめられてapplication.jsとなります。そのため、Rails側ではこのapplication.jsを読み込むだけでjqueryやjquery_ujsの機能が利用できるようになるわけです。

では、これらのファイル (jquery.js, jquery_ujs.js) はいったいどこに存在しているのでしょう、、?public以下には存在していないようですががが。。

実はAsset Pipelineのロードパスを見てみるとわかるんですが、app/assets以下だけでなく、lib/assetsやvendor/assets以下も探してくれます。

> y Rails.application.config.assets.paths
---
- /Users/sasata299/sample/app/assets/images
- /Users/sasata299/sample/app/assets/javascripts
- /Users/sasata299/sample/app/assets/stylesheets
- /Users/sasata299/sample/lib/assets/javascripts
- /Users/sasata299/sample/lib/assets/stylesheets
- /Users/sasata299/sample/vendor/assets/javascripts
- /Users/sasata299/sample/vendor/assets/stylesheets
- /Users/sasata299/.rvm/gems/ruby-1.9.3-head/gems/jquery-rails-2.1.3/vendor/assets/javascripts
- /Users/sasata299/.rvm/gems/ruby-1.9.3-head/gems/coffee-rails-3.2.2/lib/assets/javascripts

そして、注目は下二つです。それぞれjquery-railsとcoffee-railsのgemを参照しています。つまり、アプリケーション内には無くてもgemの中に置かれていればそれを参照することが出来るというわけですよ。クール。

実際中身を覗いてみても、ファイルが存在していることは確認できますね :)

$ ls -l /Users/sasata299/.rvm/gems/ruby-1.9.3-head/gems/jquery-rails-2.1.3/vendor/assets/javascripts/
total 1872
-rw-r--r--  1 sasata299  staff  365231 10 26 19:20 jquery-ui.js
-rw-r--r--  1 sasata299  staff  200748 10 26 19:20 jquery-ui.min.js
-rw-r--r--  1 sasata299  staff  266882 10 26 19:20 jquery.js
-rw-r--r--  1 sasata299  staff   93436 10 26 19:20 jquery.min.js
-rw-r--r--  1 sasata299  staff   17894 10 26 19:20 jquery_ujs.js

さらに、aseetsにはhttpベースでアクセスすることも可能です。例えば app/assets/javascripts/application.js には http://localhost:3000/assets/application.js でアクセスすることができます。
app/assets以下はどのサブディレクトリに置いたとしても同様に扱われます。

つまりこんな感じ。

app/assets/dir1/hoge.js #=> http://localhost:3000/assets/hoge.js
app/assets/dir2/foo.css #=> http://localhost:3000/assets/foo.css

application.jsを見れば難読化されていることも確認できます。知らないところでいろんなことやってくれてるんですねぇ。けなげなやつですほんまに。

# jquery.js単体 (難読化されてない)
jquery

# 各jsファイルがまとめられたapplication.js (難読化されてる)
application

--- 以下、ちょっと余談 ---

ただ、このままだとdevelopment環境であれば問題ないですが、production環境で動かそうとするとアクセスできないと言われちゃいます。ギャー。

$ rails s -e production

ActionView::Template::Error (application.css isn't precompiled):

これはprecompileしてあげることで回避できます。

bundle exec rake assets:precompile RAILS_ENV=production

もしくはconfig/environments/production.rbの以下の設定をtrueにしてリアルタイムに都度都度コンパイルするようにするか…(負荷高そう)

# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true

ただ、これでもまだエラーは出ます。production環境にしたら急にルーティングが効かなくなってassetsが見れなくなった。ヒー。

ActionController::RoutingError (No route matches [GET] "/assets/application-7270767b2a9e9fff880aa5de378ca791.css"):

これはconfig/environments/production.rbの以下の設定をtrueにすることで回避できます。これは静的ファイルの扱いをRailsで行うかどうかっていう設定です。

ApacheやNginxを使っていればそれらが静的ファイルを返してくれてRailsではやる必要がないからfalseでいいけど、今回みたいに手元でちょろっと動かしてみるときにはこの値をtrueにするといいんですかね。

# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = true

おしまい。
ささたつについて


寄稿した記事

Ruby Freaks Lounge (28,30)
NoSQLを試してみる

作ったもの

カープ戦速報ボット
まとめったー
YouTube Oricon Ranking
NicoNicoブックマーク
ねたばれ見る?


この日記のはてなブックマーク数


ブックマーク数



購読者数





つぶやき
あわせて読みたいブログパーツ
Archives
Amazonサーチ
RSS登録
Subscribe with livedoor Reader