SlideShare a Scribd company logo
1 of 28
Download to read offline
Rubyで自動日記
Twitter + DayOne
自己紹介

• Alex Onsager(アレックス)です。
  - 色々な場所で @aonsager

• Happy Elementsのプランナーです

• エンジニアではないですが、プログラミング勉強したことは
あって、今も趣味として続けています
突然ですが、
僕は日記が苦手です
そんな僕でも、継続的に使いたい
と思える日記アプリがありました
Day One
何が好きか

• UIがすばらしいので書きたくなる

• OSXとiOSに両方対応していて、同期が簡単

• Markdown使える

• データは plist ファイルにもっている (XML)
何が好きか

• UIがすばらしいので書きたくなる

• OSXとiOSに両方対応していて、同期が簡単

• Markdown使える

• データは plist ファイルにもっている (XML)
  - 今日はここに注目
自動日記

• 確かにこのアプリは好きだけど、やっぱり三日坊主な自分

• もしデータがわかりやすい形なら、なにか動的に書き込むスクリ
プト作ってみたい

• なんとか楽してコンテンツが増えていけば気持ちもいいし、サ
ボってもまた書き始めやすい

• その日のTwitterの様子をダイジェスト式に保存するのが良さそ
う!
どうにかなりそうか、
 の XML をチェック...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Creation Date</key>
  <date>2012-06-20T12:00:24Z</date>
  <key>Entry Text</key>
                            Text

 <string>今日は面白いことを沢山しました</string>
  <key>Starred</key>
  <false/>
  <key>UUID</key>
  <string>7CE4F200A67C45C8A1332778AE8E27C3</string>
</dict>
</plist>
よめる!
かけそう!!
作戦

• Twitterからツイートとふぁぼを取ってくる
  - 前の起動時にもう読み込んだツイートは無視する

• 日記エントリーのXMLを作って、情報をその中に書き出す
  - その日のエントリーがもうあれば、それを更新する形

• 最後に読み込んだツイートのIDを保存する

• 自動的に更新させる
Gem
require   'rubygems'
require   'time'
require   'twitter'
require   'nokogiri'
require   'nokogiri-plist'
require   'erb'




• Twitter
  - 簡単にAPI使える
• Nokogiri
  - XMLなどを簡単に作成・変更できる
• Nokogiri-plist
  - Macのplistファイルもできる
TwitterのOAuthを設定する
Twitter.configure do |config|
  config.consumer_key = "hogehoge"
  config.consumer_secret = "hogehoge"
  config.oauth_token = "hogehoge"
  config.oauth_token_secret = "hogehoge"
end
 
@username = "username"




• 簡単
• OAuth無しでもいけるAPI使ってる気もするけどまあいいか
ツイートとふぁぼを取ってくる
statuses = Twitter.user_timeline(@username, options)
favorites = Twitter.favorites(@username, options)



• オブジェクトとして帰ってくるので使いやすい

• 以前取ってきたツイートをまだ見てないなら、もっとあるかもし
 れないので繰り返す
XMLをつくる (Nokogiri)
@template = ERB.new <<-XMLTEMPLATE
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
      <key>Creation Date</key>
      <date><%= created_time %></date>
      <key>Entry Text</key>
      <string><%= text %></string>
      <key>Starred</key>
      <false/>
      <key>UUID</key>
      <string><%= uuid %></string>
    </dict>
    </plist>
    XMLTEMPLATE


• テンプレを先に作って、後から変数を差し込む
新しいファイルを作る場合
created_time = date.strftime("%FT00:00:00Z")
text = "Tweets for #{date.strftime('%F')}nn" + text
File.open(@dayone_journal_path, "w+") {|f|
f.write(@template.result(binding)) }




• @template.result(binding)) でさっきのテンプレに変数が差し
 込まれて、そのままファイルに書き出される
既存のファイルを更新する場合
if File.exists? @dayone_journal_path
      plist = Nokogiri::PList(open(@dayone_journal_path))
      plist['Entry Text'] += "nn#{text}"
     File.open(@dayone_journal_path, "w+") {|f|
f.write(plist.to_plist_xml) }




• Nokogiriでファイルを読み込む
• Entry Text 部分を更新する
• またファイルとして書き出す
最後に読み込んだツイートのIDを保存する
 File.open(File.join(AppRoot, "latest_tweet"), "w+") {|f|
f.write(first[:id]) }




• 前もって保存してた、一番最近のツイートのIDをファイルに書き
 出す
結果
<dict>
  <key>Creation Date</key><date>2012-10-15T00:00:00Z</date>
  <key>Entry Text</key><string>Tweets for 2012-10-15

* ☆ 心ないらくがき http://t.co/wfQ90fWh [(_kyocha)](https://twitter.com/#!/_kyocha/status/
257667654196797440)

* @_kyocha @daihay0217 本人も否定できないクオリティー [(12:47)](https://twitter.com/#!/aonsager/status/
257689026247655426)

* RT @idiot: I'm not saying I code too much, but whenever I go through a door labelled "push", I
have to pull first to avoid conflicts. [(15:36)](https://twitter.com/#!/aonsager/status/
257731686131965952)

* 今日やけにiPhoneの電池消費が激しいのはなぜだ [(19:45)](https://twitter.com/#!/aonsager/status/
257794243203063808)

* はっ!LTEか? [(19:47)](https://twitter.com/#!/aonsager/status/257794878283595776)


* ☆ 10fpsしか出ないとは情けないぜ∼∼ [(kusakari)](https://twitter.com/#!/kusakari/status/
257797888447479810)

* 今週土曜日、友達と2人で東京に行きます!
時間がある人は遊んでください ^_^ [(23:25)](https://twitter.com/#!/aonsager/status/257849733756895232)</
string>
  <key>Starred</key><false/>
  <key>UUID</key><string>TWITTER00000000000000020121015</string>
</dict>
結果
自動的に更新させる

• 最近のOSXは cron ではなく launchd を使っているらしい

• 「なにをいつ起動するのか」という情報を plist ファイルに保存

• その plist ファイルを ~/Library/LaunchAgents にいれると
勝手に色々してくれる
たとえば
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/
DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.aonsager.TwitterToDayOne</string>
   <key>ProgramArguments</key>
   <array>
        <string>/Users/aonsager/Dropbox/Documents/scripts/TwitterToDayOne/
twitter_to_dayone.rb</string>
   </array>
   <key>StartInterval</key>
   <integer>3600</integer>
   <key>RunAtLoad</key>
   <true/>
   <key>StandardErrorPath</key>
   <string>/tmp/TwitterToDayOne.err</string>
   <key>StandardOutPath</key>
   <string>/tmp/TwitterToDayOne.out</string>
</dict>
</plist>
たとえば
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/
DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.aonsager.TwitterToDayOne</string>
   <key>ProgramArguments</key>
   <array>
        <string>/Users/aonsager/Dropbox/Documents/scripts/TwitterToDayOne/
twitter_to_dayone.rb</string>
   </array>                                このスクリプトを
   <key>StartInterval</key>
   <integer>3600</integer>
   <key>RunAtLoad</key>
   <true/>
   <key>StandardErrorPath</key>
   <string>/tmp/TwitterToDayOne.err</string>
   <key>StandardOutPath</key>
   <string>/tmp/TwitterToDayOne.out</string>
</dict>
</plist>
たとえば
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/
DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.aonsager.TwitterToDayOne</string>
   <key>ProgramArguments</key>
   <array>
        <string>/Users/aonsager/Dropbox/Documents/scripts/TwitterToDayOne/
twitter_to_dayone.rb</string>
   </array>
   <key>StartInterval</key>
   <integer>3600</integer> 〇〇秒毎に起動する
   <key>RunAtLoad</key>
   <true/>
   <key>StandardErrorPath</key>
   <string>/tmp/TwitterToDayOne.err</string>
   <key>StandardOutPath</key>
   <string>/tmp/TwitterToDayOne.out</string>
</dict>
</plist>
たとえば
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/
DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.aonsager.TwitterToDayOne</string>
   <key>ProgramArguments</key>
   <array>
        <string>/Users/aonsager/Dropbox/Documents/scripts/TwitterToDayOne/
twitter_to_dayone.rb</string>
   </array>
   <key>StartInterval</key>
   <integer>3600</integer>
   <key>RunAtLoad</key>
   <true/>
   <key>StandardErrorPath</key>
   <string>/tmp/TwitterToDayOne.err</string>
   <key>StandardOutPath</key>                  ログとかはここ
   <string>/tmp/TwitterToDayOne.out</string>
</dict>
</plist>
Githubにもあります

• https://github.com/aonsager/TwitterToDayOne

• それなりに使えそうなので、forkしていただけると超嬉しいです

• 色々おかしい部分もありそうなので、指摘していただけると
 超嬉しいです
ありがとうございました

More Related Content

Similar to TwitterToDayOne

⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2Nishida Kansuke
 
C#アプリの作り方入門
C#アプリの作り方入門C#アプリの作り方入門
C#アプリの作り方入門森理 麟
 
pythonでオフィス快適化計画
pythonでオフィス快適化計画pythonでオフィス快適化計画
pythonでオフィス快適化計画Kazufumi Ohkawa
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 
第3回 Magento Cafe Plus モジュール開発入門
第3回 Magento Cafe Plus モジュール開発入門第3回 Magento Cafe Plus モジュール開発入門
第3回 Magento Cafe Plus モジュール開発入門Hirokazu Nishi
 
最高のツイッタークライアントを求めて
最高のツイッタークライアントを求めて最高のツイッタークライアントを求めて
最高のツイッタークライアントを求めてairtoxin Ishii
 
Reflexの紹介
Reflexの紹介Reflexの紹介
Reflexの紹介Rie Nakau
 
SQLマッピングフレームワーク「Kobati」のはなし
SQLマッピングフレームワーク「Kobati」のはなしSQLマッピングフレームワーク「Kobati」のはなし
SQLマッピングフレームワーク「Kobati」のはなしKazuki Minamitani
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackkimukou_26 Kimukou
 
Html5 Web Applications
Html5  Web ApplicationsHtml5  Web Applications
Html5 Web Applicationstotty jp
 
【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]
【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]
【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]Hideo Takagi
 
脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_QueryHidekazu Ishikawa
 
ゼロから始めたE2Eテスト
ゼロから始めたE2Eテストゼロから始めたE2Eテスト
ゼロから始めたE2Eテストushiboy
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へDevelopers Summit
 
【プログラミング教室】テキスト
【プログラミング教室】テキスト【プログラミング教室】テキスト
【プログラミング教室】テキストManabu Ikarashi
 
ウェブから情報をあつめる
ウェブから情報をあつめるウェブから情報をあつめる
ウェブから情報をあつめるShuhei Iitsuka
 

Similar to TwitterToDayOne (20)

Teclab3
Teclab3Teclab3
Teclab3
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
C#アプリの作り方入門
C#アプリの作り方入門C#アプリの作り方入門
C#アプリの作り方入門
 
pythonでオフィス快適化計画
pythonでオフィス快適化計画pythonでオフィス快適化計画
pythonでオフィス快適化計画
 
後期02
後期02後期02
後期02
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 
第3回 Magento Cafe Plus モジュール開発入門
第3回 Magento Cafe Plus モジュール開発入門第3回 Magento Cafe Plus モジュール開発入門
第3回 Magento Cafe Plus モジュール開発入門
 
最高のツイッタークライアントを求めて
最高のツイッタークライアントを求めて最高のツイッタークライアントを求めて
最高のツイッタークライアントを求めて
 
Reflexの紹介
Reflexの紹介Reflexの紹介
Reflexの紹介
 
20120118 titanium
20120118 titanium20120118 titanium
20120118 titanium
 
SQLマッピングフレームワーク「Kobati」のはなし
SQLマッピングフレームワーク「Kobati」のはなしSQLマッピングフレームワーク「Kobati」のはなし
SQLマッピングフレームワーク「Kobati」のはなし
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
 
Html5 Web Applications
Html5  Web ApplicationsHtml5  Web Applications
Html5 Web Applications
 
【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]
【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]
【ウェブ セミナー】AI / アナリティクスを支えるビッグデータ基盤 Azure Data Lake [実践編]
 
脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query
 
ゼロから始めたE2Eテスト
ゼロから始めたE2Eテストゼロから始めたE2Eテスト
ゼロから始めたE2Eテスト
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ
 
【プログラミング教室】テキスト
【プログラミング教室】テキスト【プログラミング教室】テキスト
【プログラミング教室】テキスト
 
ウェブから情報をあつめる
ウェブから情報をあつめるウェブから情報をあつめる
ウェブから情報をあつめる
 

TwitterToDayOne