LingrからRSS生成するサービスつくった

最近(だいぶまえから?)Lingrがアツい!!


でも未読管理ができなかったり,
開きっぱなしにしておくのがだるかったりするので
発言をRSSに変換するサービスをつくりました.


使い方

  1. http://lingr.com/bot/lingr2rss このURLにアクセス
  2. Botをチャットに追加する(要チャットルームのオーナー権限)

かんたんですね!


登録したらあとは
http://lingr2rss.yayugu.net/
でみれます.


たとえばこんな感じになる
http://lingr2rss.yayugu.net/lokka_ja


割と便利だと思うので使ってみてください!


ソースコード
https://github.com/yayugu/lingr2rss

DataMapperでdefault_scope的なことをする

LokkaがDataMapperなのでしかたなく使ってるわけですが,正直DMはあんまりいいライブラリではありません.
ActiveRecordと迷っているなら間違いなくActiveRecordを使うべきです.

で,DataMapperにはActiveRecordでのdefault_scopeにあたるものがありません.
正確にはdefault_scopeというメソッドはありますがprivate APIですし,あなたの期待する動作はしないでしょう.

default_orderを使う

default_scopeで設定したかったものがorderの場合はdefault_orderで代替できます.

class MyModel
  include DataMapper::Resource

  default_order 'created_at DESC'
end
||<</del>

追記:ダメっぽい. default_scopeは他の用途で使うらしいので
↓の方法でやりましょう.orderだけならgetのことは関係ないので安心

**firstとallを上書きする
強引な方法としてfirstとallを上書きしてしまう手があります.
例えば :draft => false というscopeを付加したい場合,以下の様にします.

>|ruby|
  class << self
    def _default_scope
      {:draft => false}
    end

    def first_with_scope(limit, query = DataMapper::Undefined)
      unless limit.kind_of? Integer
        query = limit
        limit = 1
      end
      query = _default_scope.update(query) if query.kind_of? Hash
      query = _default_scope if query == DataMapper::Undefined
      first_without_scope query
    end
    alias_method_chain :first, :scope

    def all_with_scope(query = DataMapper::Undefined)
      query = _default_scope.update(query) if query.kind_of? Hash
      query = _default_scope if query == DataMapper::Undefined
      all_without_scope query
    end
    alias_method_chain :all, :scope
  end

  def self.unscoped
    klass = self.clone
    class << klass
      alias_method :first, :first_without_scope
      alias_method :all, :all_without_scope
    end
    klass
  end

問題点

この方法ではgetではscopeが作用しません.
getにscopeを付加するにはfirstに変換して考える必要がありますが
PrimaryKeyのcolumn名がわからないと変換できないからです.

sqliteの違う環境で動作させたときだけ発生する怖いバグ

Time Zone の異なる場所で記録したDateTimeのデータでソートしようとするとソート順が正しくなりません.

例.

sqlite> select id, created_at from entries;
1|2011-01-09T05:39:08+09:00
2|2011-01-09T05:39:08+09:00
3|2011-01-08T15:40:08-05:00
sqlite> select id, created_at from entries order by created_at desc;
1|2011-01-09T05:39:08+09:00
2|2011-01-09T05:39:08+09:00
3|2011-01-08T15:40:08-05:00

2011-01-08T15:40:08-05:00は
2011-01-09T05:39:08+09:00より1分あとのははずですが.ソート結果は逆になっています.

原因

sqliteにはそもそもDate型とかDateTime型といったものがありません.
created_atはただの文字列として定義されてるのでソート結果も頭の文字から
並べ換えていくだけなわけで,Time Zoneは正しく処理できません.

解決法

  • 異なるTimeZoneの時間を含めない
  • アプリケーション側で取得したあとでソートするようにする

DotCloudにSinatraアプリ(Lokka)を設置してみた

最近Lokkaにはまってる


で,せっかくなのでいろんな環境でデプロイしてみたりしてるんだけど,
その中でもDotCloudでのデプロイは面倒という話

DotCloudとは

PaaSとか言われるものに分類されるっぽい
HerokuとかGAEとかと一緒にされますが,
それらよりもいろいろな言語とかデータベースとか
その他ソフトウェアに対応してる

DotCloudめんどう

DotCloudはいろいろな部分が低レベル
もともとruby専用だったHerokuと違い
使う言語やDBを指定しないと行けなかったり,
設定がruby環境変数ではなくファイルで置かれていたり,
sshで作業することが前提となっていたり(そのおかげでcronとか普通に使えるのは便利)


どちらかというとレンタルサーバで作業している気分になれる

仕様変更

ついこの間バージョンアップがあったようで使い方が変更されている
公式ドキュメント以外ほぼ情報がないところが多くて大変困る

Lokkaのデプロイ

めんどくさかったので一番楽そうな方法をまとめた

ダウンロード
git clone git://github.com/yayugu/lokka.git
git checkout dotcloud

あるいは
公式のLokkaをcloneして

diff --git a/config.yml b/config.yml
index 0dab043..98de2a4 100644
--- a/config.yml
+++ b/config.yml
@@ -1,5 +1,15 @@
+<% 
+# for dotcloud
+dotcloud = 
+  if File.exist? '/home/dotcloud/environment.json'
+    JSON.parse(File.read('/home/dotcloud/environment.json'))['DOTCLOUD_DATA_SQL_URL'].gsub('pgsql', 'postgres') + '/template1'
+  else 
+    nil
+  end
+%>
+
 production:
-  dsn: <%= ENV['DATABASE_URL'] || ENV['DUOSTACK_DB_MYSQL'] %>
+  dsn: <%= ENV['DATABASE_URL'] || ENV['DUOSTACK_DB_MYSQL'] || dotcloud %>
 development:
   dsn: sqlite3://<%= root %>/db/development.sqlite3
 test:
diff --git a/dotcloud.yml b/dotcloud.yml
new file mode 100644
index 0000000..3607612
--- /dev/null
+++ b/dotcloud.yml
@@ -0,0 +1,7 @@
+www:
+  type: ruby
+  exclude_bundler_groups:
+    - development
+    - test
+data:
+  type: postgresql

dotcloudではdbのURLとかはruby環境変数に入れてくれないので読みにいく必要がある.


それからpostgresなのはmysqlだとデフォルトデータベースがないので,dbのサーバにsshでログインして'create database lokka;'とかやる必要があるから.
postgresだとなぜかtemplate1という空のデータベースが1つつくられてあるのでそれを利用*1



デプロイ

dotcloudの各種設定をしてから

dotcloud create lokka
dotcloud push -bdotcloud lokka
dotcloud run lokka.www "cd current && rake db:setup"

dotcloudブランチをプッシュする*2


dotcloud runはsshでログインして1行実行するコマンド.wwwはrubyとかがおいてあるサーバ.dataだとmysqlのサーバになる.で,なぜかログインしたディレクトリ直下ではなく./currentにpushしたデータがあるのでcdしてrake

おしまい

自由度が高い&変な抽象化っていうのは厄介だね.
でも無料でいろいろできるしパフォーマンスもHerokuと比べて良かった気がしたので
そのへんはいいところ

特にHerokuの泣きどころの久しぶりのアクセス1回目はすごく遅いってもんだいがあんまりなさそう(な気がした)のはいいね

*1:Herokuだと基本はsharedな中にそのアプリ用のデータベースが自動でつくられる

*2:ちなみに'dotcloud push'はデフォルトではrsyncでgitかmercurialを使ってればそれでプッシュするという混乱極まりない仕様になっている

Twitterの(公式よりまともな)RSSを生成するサービス Twitter Good RSS をつくったよ!

改良版のTwitter Great RSSをつくりました。今後はこちらをお使いください









つくりました! こんな感じ↓にTwitter公式のアレなRSSと違いまともなRSSを生成します。



URL、#ハッシュタグ、@リプライに対応。さらに公式の画像サービスpic.twitter.comの画像をインライン展開できます。


さらに、リストからRSSを生成する機能もつけました。
なぜか公式ではRSSないみたいなので便利なのではないでしょうか。


URLはこちら↓

http://twittergoodrss.herokuapp.com/


こんな人に便利!?

  • ツイートを未読管理したい
  • 一人一人のtweetを混ぜずに集中的によみたい
  • リスト分けしてるけど全部巡回するのだるくなってきた
  • リストに人入れすぎて全部読んでないのにTwitterの制限で最後まで辿れなくなってる*1
  • Twitter公式のRSSまじうんこ。アイコンないと誰のツイートかピンと来ない。URLとかハッシュタグにリンクぐらいつけろよ!

というわけで

TwitterGoodRSSで快適なRSSライフを!
http://twittergoodrss.herokuapp.com/


ソースコード

https://github.com/yayugu/twitterGoodRSS
気軽にpull requestとかissueとかお待ちしています。
herokuに簡単にデプロイできるようになってます。



2013/03/05 追記:
Twitter API 1.1に対応しました

*1:リストは普通のタイムラインよりさかのぼれる制限が厳しい…気がする

TwitterのOAuthでrequest tokenを取得しようとして401 Unauthorizedがでるときの原因と対処法3つ

たとえばRubyのOAuth Gemだと
OAuthConsumer#get_request_tokenすると
OAuth::Unauthorized - 401 Unauthorized:
みたいなそっけないエラーがでてどうしたらいいかサッパリわからない時がある。
一応KeyとSecretを確認したけど合ってるし……みたいなとき


俺が調べたところ原因は3つあって

  1. コンピュータの時刻が狂っている
  2. アプリがTwitterからSuspendされてる
  3. アプリの設定画面のCallbackURLに何も入力されていない


最後のが特に気づきにくくてすごく厄介だ。
WebアプリなどでCallbackを用いる場合

ここんところに適当でいいので何かURLを入力しておかないといけない。
本当に適当でいいみたいなので何かを入れておこう!


Twitterが悪いのかOAuthが悪いのか知らないけどひでえ仕様

カタログスペックではわからないMacBook Airの欠点

今までMacBook Pro 13inch Mid 2010を使っていたんだけど新型のAir 13inchに乗りかえた!

で、薄さと安さのために意外と犠牲にされているところがあるように感じられたのでかいとく

質感

明らかにProのほうが上
Apple製品のガワは基本的にアルミとガラスでできている。
でもAirでは従来ガラスが使われていた部分がアルミになっているところがある。

  1. ディスプレイの外枠 Proでは液晶の枠は黒く、またその枠の部分までを1枚のガラスで覆っていたため、美しく統一感が出ていた。Airでは外枠はアルミになっている。iPad2なんかを見るとわかるが、液晶の外枠は白より黒のほうが画面と一体感がでる
  2. トラックパッド Proではガラスだったがアルミかアルミに何らかのコーティングをしたものになっている

操作性

  1. キーボード 浅い。ベコベコしている
  2. トラックパッド アルミになったせいで滑りが悪い気がする

液晶

ProではグレアだったがAirでは低反射のグレアになっている。パッと見ノングレアに見える。
薄くできる液晶を使っているためか発色は悪い。モニタはちゃんとSpyderでキャリブレーションする色に細かい芸大の友人に聞いたらやっぱり悪いそうだ。

スピーカの音

Proに比べるとだいぶ悪い。音楽を再生すると誰でもわかるレベル。まあスピーカは基本的に重いほうが音がいいので、軽いと音が悪くなるのは当たり前だよね

バッテリー

Proの半分しかもたない。というかProのバッテリー量が異常だった。

LANポート

無いと地味に困るケース多め。ホテルとか。USB変換ケーブルかって持ち歩くしかないか…

パフォーマンス

基本的にAirのほうがよかった

  1. ストレージ Airにして良かった! SSDは最高だった! ノートを揺らすとHDDが「カコン」と鳴る精神衛生によろしくない現象から解放された!
  2. CPU いくらSandyBridgeとはいえ0.7Ghzのクロックダウンになるので厳しいかと思ったが意外と大丈夫だった。ニコ動やYoutubeでの動画再生では今までとあまり変わらない感じ。
  3. GPU Macでゲームしないのでわからない
モデル名 MBP 13inch(今まで) MBA 13inch(買ったの)
OS Snow Leopard Lion
CPU Core2Duo 2.4GHz Core i5 1.7GHz
メモリ 4GB 4GB
ストレージ 256GB 128GB
光学ドライブ DVDマルチ なし
ディスプレイ 13.3(1280×800) 13.3(1440×900)

まとめ

Appleのサイトみてるだけじゃわからない欠点はいろいろありましたが、なんだかんだ言ってAir最高です。薄いし軽いしProに戻れる気がしないね。迷っているProユーザは買っちゃえばいいと思うよ!