upinetree's memo

Web系技術の話題や日常について。

fluentdを使ってIdobataでニコレポを取得する

はじめに

先日ニコレポ用のfluentdプラグインを書きました。

https://github.com/upinetree/fluent-plugin-nicorepo

このまえ作ったニコレポgemを使って、ニコ動からニコレポを逐次取得してくれるすごいやつです。 (別にfluentdじゃなくてもいいじゃんというのはなしの方向で…)

いわゆる完全に俺得プラグインなんだけれども、使い方の説明の意味も含めて記事を書くことにします。

セットアップ

今回、fluentdはherokuで動かすことにします。 準備とかは下記のリンクが詳しいので参考にしつつやっていきます。

http://docs.fluentd.org/ja/articles/install-on-heroku

ひな形のClone

heroku-td-agentというheroku用の便利なひな形があるので利用します。

次のような感じでリポジトリ作りましょう。

$ git clone git://github.com/treasure-data/heroku-td-agent.git heroku-fluentd-nicorepo
$ cd heroku-fluentd-nicorepo
$ rm -fR .git
$ git init
$ git add .
$ git commit -m 'initial commit'

herokuアプリの作成とデプロイ

Heroku Toolbelt が入っていれば、次の方法でアプリの作成とデプロイができます。

$ heroku apps:create your-app-name
$ git push heroku master

動作確認

ここまで来たらひとまず動作確認します。

$ curl http://your-app-name.herokuapp.com/debug.sample -F 'json={"hoge": "fuga"}'
$ heroku logs --tail

2014-06-09T16:13:38.544846+00:00 app[web.1]: 2014-06-09 16:13:38 +0000 debug.sample: {"hoge":"fuga"}

上記みたいなのが出力されてたらOKです。

confの設定

さて、いよいよニコレポを取得してIdobataに流していきます。 あたりまえのことですが、ニコニコ動画のアカウントがあり、ニコレポで誰かをウォッチしている状態でないと、いつまでたっても何も流れてきませんのでご注意を。

今回、gemはfluent-plugin-nicorepofluent-plugin-idobataを使用します。 従ってGemfileは次の状態にします。

source 'http://rubygems.org'

ruby '2.1.2'

gem 'fluentd', '~> 0.10.48'
gem 'fluent-plugin-nicorepo'
gem 'fluent-plugin-idobata'

また、td-agent.confを次のように設定します。 今回は1時間おきに生放送だけを取りに行くようにしてみました。

<source>
  type nicorepo
  mail your@email.com
  pass yourpassword
  interval 1h
  kind lives
  tag nicorepo.idobata
</source>

<match nicorepo.**>
  type copy
  <store>
    type idobata
    webhook_url https://idobata.io/hook/url
    message_template <%= record[:body] %> @<%= record[:date] %> / <%= record[:title] %>: <%= record[:url] %>
  </store>
  <store>
    type stdout
  </store>
</match>

ニコ動のアカウントmail, passと、Idobataのwebhook_urlを書き換えるのを忘れないでください。 Idobataのwebhook_urlとは、流したいスレのRoom Settingsから'Add a Hook'して取れるEndpoint URLのことです。

再度デプロイしてあとは流れてくるのを待つだけです!

$ git add .
$ git commit -m 'setup nicorepo on idobata'
$ git push heroku master

あと、取得を1時間以上の間隔に設定する場合はこの設定やっておいたほうが良いかもです。

Heroku の Dyno を寝かせない - present

たまにheroku側で再起動して同じニコレポが2回やってきたりしますがご愛嬌。

お疲れ様でした。

NicorepoというRuby gemを公開しました

f:id:upinetree:20140501000122p:plain

ニコニコ動画のニコレポというのがあって、ニコ動版のツイッタータイムラインみたいなやつなんですが、これがまた情報が分類されてなくて読みづらいし、フィルタリングもできない、非常に廃人仕様なわけです。

毎日ニコレポに張り付くわけにも行かないけど、見たい動画は見逃したくない…ので、日々あふれるニコレポを効率よくまとめてチェックできるgemを作りました。

https://rubygems.org/gems/nicorepo

https://github.com/upinetree/nicorepo

といっても今まで自分で便利に使っていたやつを、みんなで使えるように手直ししてgem化しただけです…。Rubyをまだそこまでガッツリ使っていなかったときに書いたやつなので、ザクザクっとリファクタリングしてみました。

でもcliとかカオスすぎるので近々なんとかしたいし、コマンドもなんだか分かりづらい(自分は慣れたパターン)し、汎用性ないし…プルリクお待ちしております!

なお、ニコレポがAPIも提供してないのでかなり力技でぱーすしています。

使い方は大体READMEに書いてあるのですが、下手な英語なので分かりづらかったらお叱りください〜。

では、良いニコ動ライフを!

実行中Rubyプログラムのbinding.pryを全て無効にする

Pry version: 0.9.12.4 on Ruby 2.1.0.

これだけ

pry(main)> disable-pry

どんな機能かというと

pry(main)> help disable-pry
Usage: disable-pry

After this command is run any further calls to pry will immediately return `nil`
without interrupting the flow of your program. This is particularly useful when
you've debugged the problem you were having, and now wish the program to run to
the end.

As alternatives, consider using `exit!` to force the current Ruby process
to quit immediately; or using `edit-method -p` to remove the `binding.pry`
from the code.

ということらしい。

例えばループ中とかshared_examplesとかでbinding.pryしたとき、これを使えば目的の動作を確認した後にぐぬぬってならなくて済みますね。

ただ、binding.prynilを返す動作は変わらないのでそこだけ注意です。

他の方法としては、exit!を使うか、edit-method -pbinding.pryを削除してくれと書いてありますね。

ちなみに、edit-methodすると "DISABLED: Use edit instead." と怒られるので、指示に従ってedit -p method-nameとでもしておきましょう。

CoffeeScriptでインスタンスメソッドを関数バインディングする

忘れないようにメモ。

イベントをバインディングする時、関数をコールバックで渡すことがある。

$('.hoge_field').on('blur', (e) -> updateHoge(e.target))

updateHoge = (hoge_field) ->
  hogehoge

でも、インスタンスメソッドを渡すときは同様にこうしてはいけない。

index: ->
  $('.hoge_field').on('blur', (e) -> @updateHoge(e.target))

updateHoge: (hoge_field) ->
  hogehoge

なぜなら、コールバックとして渡す際、thisの示す先が変わり、updateHogeが未定義となってしまうから。

なのでこう書く。

  $('.hoge_field').on('blur', (e) => @updateHoge(e.target))

ファットアロー => を使うと、thisの示す先を変えずに扱うことができる。

JavaScript苦手意識あったけど、CoffeeScript触るようになってからわりと楽しくやってるかも。

非表示要素はCapybaraのfindで検索対象になるのか

今日はもう一個書く!

Capybara使ってると、display: noneで非表示にしてあるものはCapybaraのfind対象なのか??

という疑問がでてきたわけです。

ここは公式みてみますか。

Module: Capybara::Node::Finders

visible (Boolean) — Only find elements that are visible on the page. Setting this to false finds invisible andvisible elements.

ふむふむ。

でもどっちがデフォルトなのかよくわからん。 ちょっとソースつついてみる。

lib/capybara/query.rb

def visibleありますね。visibleオプション指定がないときは、 Capybara.ignore_hidden_elementsを見て判定しているようです。

こいつはlib/capybara.rbにありました。

[ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)

デフォルトはtrueなので、見えないものは探さないってことですね。 Configureで設定可能のようです。

つまり

visible: true #=> display: noneのものは検出しない(デフォルト)
visible: false #=> disiplay: noneでも検出する

ということですね。

実際確かめてみる。

  • visible: trueで検索すると、@resultにdisplay: noneの要素が入らなくて@restに入る。
  • visible: falseで検索すると、@resultに要素が入って@restが空になる。

うん、そのようだ。 スッキリ。

テキストをクリックして入力フォームを出現させる (rails+haml+coffee)

一覧画面とかで、表示されているテキストクリックしたら入力フォームが出現して、 サクッと内容変更できたらカッコ良いじゃないですか。 例えばブログ記事のタイトルとか、クリックしたら編集できるようになるとか。

というわけで毎度のメモです。

haml

#posts
  - @posts.each do |post|
    .title
      .value= post.title
      = text_field :post, :title, class: :field

scss

.title {
  .value {
    display: inline;
  }
  .field {
    display: none;
  }
}

coffee

$('.value').on('click', ->
  $(@).hide()
  $(@).next('.field').show()
                     .val($(@).text())
                     .focus()
)

$('.field').on('blur', ->
   # $.ajax
   #   hogehoge

   $(@).hide()
   $(@).prev('.value').show()

# 直感的にはEnterで確定したいので作ったる
$('.label_field').keypress (e) ->
  if e.which == 13
    e.target.blur()

ちなみに

単純なテキストの切り替えだったらこんな感じ。

haml

#toggle_me
  #showing.toggle_pair Toggle Me!!
  #hidden.toggle_pair Toggled!!

:scss
  #hidden {
    display: none;
  }

coffee

$('#toggle_me').on 'click', ->
  $(@).children('.toggle_pair').toggle()

表示する要素と表示しない要素を用意して同時に表示・非表示を切り替えることで、見かけ上変化させるのがコツですね〜。

FactoryGirlでファクトリ継承時、クラス指定を忘れて困った

困ったのでメモ。

次のようなSTIな感じのモデルがあるとき、ファクトリ側でも継承を使いたいなーと思うわけです。

モデル

class Post < ActiveRecord::Base
end

class PhotoPost < Post
  belongs_to :album
end

Factory

FactoryGirl.define do
  factory :post do
  end

  factory :photo_post, parent: :post do
    album
  end
end

photo_postをparentオプションでpostから継承した。でも、こう書いた場合albumなんて知らんと怒られる。

pry(main)> FactoryGirl.build(:photo_post)
NoMethodError: undefined method `album=' for #<Post:0x007f8e1b52ccd0>

なぜなら、photo_postは継承元(post)のインスタンスとして生成されるため。

albumの記述を削除して確認。

pry(main)> FactoryGirl.create(:photo_post).class
=> Post(id: integer, title: string, body: text, type: string, created_at: datetime, updated_at: datetime)

postにはalbumとの関連はないため、参照しようとして怒られていた。 これを回避するには、ファクトリ定義時にclassオプションを指定する。

  factory :photo_post, class: PhotoPost, parent: :post do
    album
  end

classオプションによりファクトリphoto_postがPhotoPostを生成することを教えられた。 これで、生成されるインスタンスはPhotoPostになる。

pry(main)> FactoryGirl.create(:photo_post).class
=> PhotoPost(id: integer, title: string, body: text, type: string, created_at: datetime, updated_at: datetime)

class指定忘れずにしようねというお話でした。