<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>橋本商会 &#187; Twitter</title>
	<atom:link href="http://shokai.org/blog/archives/tag/twitter/feed" rel="self" type="application/rss+xml" />
	<link>http://shokai.org/blog</link>
	<description>なんか作ったりした記録を忘れないうちに書くblog</description>
	<lastBuildDate>Sun, 20 May 2012 10:50:20 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com/" />
			<item>
		<title>twitterのlistに自分を追加できない件</title>
		<link>http://shokai.org/blog/archives/5899</link>
		<comments>http://shokai.org/blog/archives/5899#comments</comments>
		<pubDate>Thu, 19 Apr 2012 13:47:52 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=5899</guid>
		<description><![CDATA[自分が作ったリストに自分を追加できない（昔はできた） API使ったら追加できた。rubygemsのtwitterを使った場合 Twitter.list_add_member(&#34;test&#34;, &#038;quot [...]]]></description>
			<content:encoded><![CDATA[<p>
自分が作ったリストに自分を追加できない（昔はできた）<br />
<br />
API使ったら追加できた。rubygemsのtwitterを使った場合<br />
<pre class="prettyprint">
Twitter.list_add_member(&quot;test&quot;, &quot;shokai&quot;)<br />
</pre>
<br />
<br />
ここに置いた<br />
<a href="https://github.com/shokai/twitter-api-console/blob/master/cmds/add_list.rb">https://github.com/shokai/twitter-api-console/blob/master/cmds/add_list.rb</a><br />
<br />
<br />
こんな感じで使えるはず<br />
<pre class="prettyprint">
git clone git://github.com/shokai/twitter-api-console.git<br />
cd twitter-api-console<br />
gem install bundler<br />
bundle install<br />
cp sample.config.yml config.yml<br />
ruby auth.rb<br />
# oauthで認証される<br />
ruby cmds/add_list.rb "shokai" "test"<br />
</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/5899/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sfc_ikiteru</title>
		<link>http://shokai.org/blog/archives/5473</link>
		<comments>http://shokai.org/blog/archives/5473#comments</comments>
		<pubDate>Fri, 25 Mar 2011 09:46:03 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[bot]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=5473</guid>
		<description><![CDATA[@sfc_ikiteruというtwitter botができた。1時間ごとにSFCの状況をtweetする。 ソースはここにあるhttps://github.com/shokai/twitter_sfc_ikiteru あと [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://twitter.com/sfc_ikiteru">@sfc_ikiteru</a>というtwitter botができた。1時間ごとにSFCの状況をtweetする。<br />
<br />
ソースはここにある<a href="https://github.com/shokai/twitter_sfc_ikiteru">https://github.com/shokai/twitter_sfc_ikiteru</a><br />
<br />
<br />
あといつのまにか<a href="http://sfc.死ぬ.jp">SFC.死ぬ.jp</a>がymrlによって作られていた。こっちの方が詳細がわかりやすい。<br />
<br />
<br />
gem sfc_ikiteruは、pingをeventmachineで並列化したので監視対象のサーバーを増やしても大丈夫になった。<br />
今こんな感じ<br />
<pre>
% sfc_ikiteru<br />
sfc_ikiteru => 生存率 80%<br />
web.sfc.keio.ac.jp => 正常です<br />
ccz01.sfc.keio.ac.jp => 正常です<br />
ccz02.sfc.keio.ac.jp => 正常です<br />
mail.sfc.keio.ac.jp => 正常です<br />
gw2.sfc.keio.ac.jp => 正常です<br />
keio.gw.sinet.ad.jp => 正常です<br />
shonan.sfc.wide.ad.jp => 正常です<br />
masui.sfc.keio.ac.jp => 正常です<br />
www.mag.keio.ac.jp => 応答なし<br />
cpu0.mag.keio.ac.jp => 応答なし<br />
</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/5473/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>26歳になったので</title>
		<link>http://shokai.org/blog/archives/5322</link>
		<comments>http://shokai.org/blog/archives/5322#comments</comments>
		<pubDate>Wed, 18 Aug 2010 10:12:56 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Wikipedia]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=5322</guid>
		<description><![CDATA[8月15日に26歳になったので、新しい自分を探すためにtwitterのプロフィールを自動的に更新するようにした 人間以外にもなれる ソースコードは全部githubに置いた ランダムに適当な紹介文を取ってくる wikipe [...]]]></description>
			<content:encoded><![CDATA[<p>
<p>8月15日に26歳になったので、新しい自分を探すために<a href="http://twitter.com/shokai">twitterのプロフィール</a>を自動的に更新するようにした<br /><br />
<a href="http://www.flickr.com/photos/shokai/4903244203/" title="30ed9b71553d2f33922bc39e7368a008 by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4121/4903244203_4bb03acf09.jpg" width="253" height="225" alt="30ed9b71553d2f33922bc39e7368a008" /></a></p>
<p><a href="http://www.flickr.com/photos/shokai/4904183134/" title="838d669e96f189702c3f9844965ace8e by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4135/4904183134_77a40b2fe2.jpg" width="247" height="244" alt="838d669e96f189702c3f9844965ace8e" /></a><br /></p>
<p>人間以外にもなれる<br /><br />
<a href="http://www.flickr.com/photos/shokai/4903239191/" title="eac518c56870949065eeeed905d34ae4 by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4117/4903239191_61c18437a9.jpg" width="254" height="200" alt="eac518c56870949065eeeed905d34ae4" /></a></p>
<p><a href="http://www.flickr.com/photos/shokai/4903423129/" title="e85cb1527f60394255fe556f41cc3e62 by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4140/4903423129_e74e2c5a3c.jpg" width="251" height="354" alt="e85cb1527f60394255fe556f41cc3e62" /></a></p>
<p><a href="http://www.flickr.com/photos/shokai/4903820452/" title="9c4c1cb1c6fadac1ff09f120b5585892 by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4117/4903820452_2bd60a5065.jpg" width="264" height="276" alt="9c4c1cb1c6fadac1ff09f120b5585892" /></a></p>
<p><a href="http://www.flickr.com/photos/shokai/4903251901/" title="7d4fcd1cd71ba0e8693133439b4751eb by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4076/4903251901_af1e028e41.jpg" width="271" height="312" alt="7d4fcd1cd71ba0e8693133439b4751eb" /></a><br /></p>
<p>ソースコードは<a href="http://github.com/shokai/twitter-change-profile">全部githubに置いた</a><br /></p>
<p>ランダムに適当な紹介文を取ってくる<br /><br />
<a href="http://github.com/shokai/twitter-change-profile/blob/b04a978f51f173f8e9997b8f2f89984152061eb8/lib/wikipedia.rb">wikipedia.rb</a><br /><br />
<pre class="prettyprint"><br />
# -*- coding: utf-8 -*-<br /><br />
require 'rubygems'<br /><br />
require 'open-uri'<br /><br />
require 'uri'<br /><br />
require 'nokogiri'<br /><br />
require 'kconv'<br /><br />
require 'net/http'</p>
<p>class Wikipedia</p>
<p> def initialize(agent_name)<br /><br />
 @agent_name = agent_name<br /><br />
 end</p>
<p> def random<br /><br />
 get('特別:おまかせ表示')<br /><br />
 end<br /><br />
 <br /><br />
 def get(name)<br /><br />
 doc = Nokogiri::HTML open(URI.encode("http://ja.wikipedia.org/wiki/#{name}"), 'User-Agent' =&gt; @agent_name).read.toutf8<br /><br />
 <br /><br />
 title = doc.xpath('//title').first.text<br /><br />
 name = doc.xpath('//h1').first.text<br /><br />
 descriptions = doc.xpath('//div[@id="bodyContent"]//p').map{|i|i.text}<br /><br />
 {<br /><br />
 :title =&gt; title,<br /><br />
 :name =&gt; name,<br /><br />
 :descriptions =&gt; descriptions<br /><br />
 }<br /><br />
 end</p>
<p>end<br /><br />
</pre></p>
<p>このスクリプトをcronで定期的に実行して更新してる<br /><br />
<a href="http://github.com/shokai/twitter-change-profile/blob/1baaf76b52f9d377c39ce1ceb8c1edb232550f57/change-profile.rb">change-profile.rb</a><br /><br />
<pre class="prettyprint"><br />
#!/usr/bin/env ruby<br /><br />
# -*- coding: utf-8 -*-<br /><br />
require 'rubygems'<br /><br />
require 'twitter'<br /><br />
require 'yaml'<br /><br />
require File.dirname(__FILE__)+'/lib/wikipedia'<br /><br />
$KCODE = 'u'</p>
<p>begin<br /><br />
 conf = YAML::load open(File.dirname(__FILE__) + '/config.yaml')<br /><br />
rescue<br /><br />
 STDERR.puts 'config.yaml load error'<br /><br />
 exit 1<br /><br />
end</p>
<p>tw = Twitter::Base.new(Twitter::HTTPAuth.new(conf['name'], conf['pass']))<br /><br />
w = Wikipedia.new('shokai')<br /><br />
desc = nil<br /><br />
5.times do<br /><br />
 data = w.random<br /><br />
 <br /><br />
 desc = data[:descriptions].first<br /><br />
 desc.gsub!(/\[\d+\]/, '')<br /><br />
 tmp = desc.split(/(と?は)/)<br /><br />
 left = tmp.shift<br /><br />
 while left =~ /（[^）]+$/ do<br /><br />
 tmp.shift<br /><br />
 left = tmp.shift<br /><br />
 end<br /><br />
 desc = "#{conf['your_name']}#{tmp.join('')}".toutf8<br /><br />
 puts '-'*10<br /><br />
 print data[:name] + ' =&gt; '<br /><br />
 puts desc<br /><br />
 break if desc != conf['your_name']<br /><br />
end<br /><br />
exit if desc == nil or desc == conf['your_name']</p>
<p>tw.update_profile({'description' =&gt; desc})<br /><br />
</pre><br />
</p>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/5322/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JRubyでglitch iconを作る(2)</title>
		<link>http://shokai.org/blog/archives/5291</link>
		<comments>http://shokai.org/blog/archives/5291#comments</comments>
		<pubDate>Thu, 05 Aug 2010 23:46:05 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[glitch]]></category>
		<category><![CDATA[glitchicon]]></category>
		<category><![CDATA[javax.imageio]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[画像処理]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=5291</guid>
		<description><![CDATA[プラグイン機構を採用し、ランダムにいろいろ作れるようにしてみた。 普通はjpegとかのバイナリを直接いじるみたいだけどよく分からないのでJRubyでjavax.imageioを使ってやっている。 ランダムに96個作ってみ [...]]]></description>
			<content:encoded><![CDATA[<p>
プラグイン機構を採用し、ランダムにいろいろ作れるようにしてみた。<br />
普通はjpegとかのバイナリを直接いじるみたいだけどよく分からないのでJRubyでjavax.imageioを使ってやっている。<br />
<br />
ランダムに96個作ってみて8&#215;12に敷き詰めてみたのがこれ。<br />
で、定期的にランダムに作って<a href="http://twitter.com/shokai">twitterのアイコンとしてアップロードしてる</a>。<br />
<a href="http://www.flickr.com/photos/shokai/4861585419/" title="montage96 by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4123/4861585419_d3310346ec_b.jpg" width="694" height="1024" alt="montage96" /></a><br />
敷き詰めるのはImageMagickと一緒にインストールされるmontageコマンドでできる <a href="http://d.hatena.ne.jp/shokai/20100803/1280785691">montageコマンド &#8211; 橋本詳解</a><br />
<br />
ソースコードは全て<a href="http://github.com/shokai/glitchicon">githubに置いた</a>。<br />
<br />
<br />
■仕組み<br />
単機能モジュールをランダムに連結する事である程度ランダムな画像を生成できる。<br />
javax.imageio.BufferedImageのインスタンスを受け取り、少し加工して返すというJRubyのmoduleをプラグインとし、それらを<a href="http://github.com/shokai/glitchicon/blob/master/glitch.rb">Glitch</a>というclassがランダムに呼び出す。<br />
<br />
<br />
今のところプラグインは23種類ある。単体だとそれほど派手にはならない。<br />
<a href="http://www.flickr.com/photos/shokai/4862180974/" title="glitchicon montage by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4118/4862180974_296b734bd0.jpg" width="500" height="492" alt="glitchicon montage" /></a><br />
<br />
<br />
<br />
■プラグイン<br />
<a href="http://github.com/shokai/glitchicon/tree/master/plugins/">http://github.com/shokai/glitchicon/tree/master/plugins/</a>にある。<br />
pluginが動くルールはこれ。<br />
<ul>
  <li><a href="http://github.com/shokai/glitchicon/tree/master/plugins/">pluginsディレクトリ</a>の中に置いておく</li>
  <li>ファイル名末尾が.rbである</li>
  <li>JRubyのmoduleである</li>
  <li>ファイル名の先頭1文字を大文字にしたmodule名である</li>
  <li>BufferedImageを受け取って、同じサイズのBufferedImageを返す glitch(BufferedImage) というstatic methodを持つ</li>
  <li>受け取ったBufferedImageに対しては破壊的に処理しても、そうでなくてもいい</li>
</ul>
<br />
プラグインはBufferedImageの処理に集中できるように、他の事は<a href="http://github.com/shokai/glitchicon/blob/master/glitch.rb">glitch.rb</a>がやる。<br />
<br />
<br />
どのプラグインも簡単にできている。30行ぐらい。<br />
<br />
<a href="http://github.com/shokai/glitchicon/blob/master/plugins/drumroll_vertical.rb">drumroll_vertical</a>プラグインの場合（画像では一番左、下から2番目）<br />
<pre class="prettyprint">
#!/usr/bin/env&nbsp;jruby<br />
require&nbsp;'java'<br />
import&nbsp;'java.lang.System'<br />
import&nbsp;'javax.imageio.ImageIO'<br />
import&nbsp;'java.awt.image.BufferedImage'<br />
<br />
<br />
module&nbsp;Drumroll_vertical<br />
<br />
&nbsp;&nbsp;def&nbsp;Drumroll_vertical.glitch(img)<br />
&nbsp;&nbsp;&nbsp;&nbsp;img_result&nbsp;=&nbsp;BufferedImage.new(img.width,&nbsp;img.height,&nbsp;img.type)<br />
&nbsp;&nbsp;&nbsp;&nbsp;roll&nbsp;=&nbsp;0<br />
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;x&nbsp;in&nbsp;0...img.width&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;roll&nbsp;=&nbsp;rand(img.height)&nbsp;if&nbsp;rand&nbsp;&gt;&nbsp;0.95<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;roll&nbsp;=&nbsp;0&nbsp;if&nbsp;rand&nbsp;&gt;&nbsp;0.95<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;y&nbsp;in&nbsp;0...img.height&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;img.get_rgb(x,&nbsp;y)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y2&nbsp;=&nbsp;y+roll<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y2&nbsp;-=&nbsp;img.height&nbsp;if&nbsp;y2&nbsp;&gt;&nbsp;img.height-1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img_result.set_rgb(x,&nbsp;y2,&nbsp;pix)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;img_result<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
</pre>
ランダムに縦に区切って、ランダムにスロットのドラムみたいにずらす。<br />
<br />
<br />
色を反転させる<a href="http://github.com/shokai/glitchicon/blob/master/plugins/color_reverse.rb">color_reverse</a>プラグイン<br />
<pre class="prettyprint">
#!/usr/bin/env&nbsp;jruby<br />
require&nbsp;'java'<br />
import&nbsp;'java.lang.System'<br />
import&nbsp;'javax.imageio.ImageIO'<br />
import&nbsp;'java.awt.image.BufferedImage'<br />
<br />
<br />
module&nbsp;Color_reverse<br />
<br />
&nbsp;&nbsp;def&nbsp;Color_reverse.glitch(img)<br />
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;y&nbsp;in&nbsp;0...img.height&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;x&nbsp;in&nbsp;0...img.width&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;img.get_rgb(x,&nbsp;y)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;=&nbsp;pix&nbsp;&gt;&gt;&nbsp;16&nbsp;&amp;&nbsp;0xFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g&nbsp;=&nbsp;pix&nbsp;&gt;&gt;&nbsp;8&nbsp;&amp;&nbsp;0xFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;pix&nbsp;&amp;&nbsp;0xFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;=&nbsp;256-r<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g&nbsp;=&nbsp;256-g<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;256-b<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;((r&nbsp;&lt;&lt;&nbsp;16)&amp;0xFF0000&nbsp;|&nbsp;(g&nbsp;&lt;&lt;&nbsp;8)&amp;0xFF00&nbsp;|&nbsp;b)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img.set_rgb(x,y,&nbsp;pix)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;img<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
</pre>
<br />
<br />
量子化した後に輪郭抽出する<a href="http://github.com/shokai/glitchicon/blob/master/plugins/quantize_contour.rb">quantize_contour</a><br />
<pre class="prettyprint">
#!/usr/bin/env&nbsp;jruby<br />
require&nbsp;'java'<br />
import&nbsp;'java.lang.System'<br />
import&nbsp;'javax.imageio.ImageIO'<br />
import&nbsp;'java.awt.image.BufferedImage'<br />
<br />
<br />
module&nbsp;Quantize_contour<br />
<br />
&nbsp;&nbsp;def&nbsp;Quantize_contour.glitch(img)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;y&nbsp;in&nbsp;0...img.height&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;x&nbsp;in&nbsp;0...img.width&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;img.get_rgb(x,&nbsp;y)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;=&nbsp;pix&nbsp;&gt;&gt;&nbsp;16&nbsp;&amp;&nbsp;0xFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g&nbsp;=&nbsp;pix&nbsp;&gt;&gt;&nbsp;8&nbsp;&amp;&nbsp;0xFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;pix&nbsp;&amp;&nbsp;0xFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gray&nbsp;=&nbsp;(r+g+b)/3<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;quant&nbsp;=&nbsp;gray&nbsp;&amp;&nbsp;0xC0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;((quant&nbsp;&lt;&lt;&nbsp;16)&amp;0xFF0000&nbsp;|&nbsp;(quant&nbsp;&lt;&lt;&nbsp;8)&amp;0xFF00&nbsp;|&nbsp;quant)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img.set_rgb(x,&nbsp;y,&nbsp;pix)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;img_result&nbsp;=&nbsp;BufferedImage.new(img.width,&nbsp;img.height,&nbsp;img.type)<br />
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;y&nbsp;in&nbsp;1...img.height-1&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;x&nbsp;in&nbsp;1...img.width-1&nbsp;do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;img.get_rgb(x,&nbsp;y)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;around&nbsp;=&nbsp;(img.get_rgb(x-1,y)+img.get_rgb(x+1,y)+img.get_rgb(x,y-1)+img.get_rgb(x,y+1))/4<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;around&nbsp;&lt;&nbsp;pix<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pix&nbsp;=&nbsp;0xFFFFFF<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img_result.set_rgb(x,&nbsp;y,&nbsp;pix)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;img_result<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
</pre>
<br />
<br />
そんなかんじ。画像をいじるけど、元の画像を知っている人なら元画像を思い浮かべられる程度にglitchしたい。<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/5291/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mbedにEthernetを接続しtwitterにpostする</title>
		<link>http://shokai.org/blog/archives/5122</link>
		<comments>http://shokai.org/blog/archives/5122#comments</comments>
		<pubDate>Wed, 21 Apr 2010 15:04:49 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Ethernet]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[mbed]]></category>
		<category><![CDATA[NXP LPC1768]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=5122</guid>
		<description><![CDATA[@1VQ9の助力を得てmbedがethernetにつながった。1VQ9はパルストランスも通さず、分解したLANケーブルをmbedに直接差し込んで動かしてたけど、俺はmbed Ethernet Testingに従ってパルス [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://twitter.com/1VQ9/status/12349635733">@1VQ9の助力</a>を得てmbedがethernetにつながった。1VQ9はパルストランスも通さず、分解したLANケーブルをmbedに直接差し込んで動かしてたけど、俺は<a href="http://mbed.org/users/no2chem/notebook/ethernet-testing/">mbed Ethernet Testing</a>に従ってパルストランス入りのEthernet jackを使った。<br />
<ul><li><a href="http://www.switch-science.com/products/detail.php?product_id=265">スイッチサイエンス/商品詳細 イーサネット用RJ45ジャック(トランス入り)</a></li></ul>
<br />
<br />
ethernetにつないだところ<br />
<a href="http://www.flickr.com/photos/shokai/4530984658/" title="mbed + ethernet by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4017/4530984658_51c07a8036.jpg" width="500" height="375" alt="mbed + ethernet" /></a><br />
mbedとethernet jackは<br />
<ul>
<li>mbed p1 = Ethernet RD+</li>
<li>p2 = RD-</li>
<li>p7 = TD-</li>
<li>p8 = TD+</li>
</ul>
という風に接続した。<a href="http://mbed.org/projects/cookbook/wiki/EthernetTest">こっちでは別のつなぎ方</a>をしているが、この配置だと動かなかったのでjack毎に違うのかもしれない。よくわからない。<br />
<br />
<br />
配線はこっちの方が見やすいかも<br />
<a href="http://www.flickr.com/photos/shokai/4530348779/" title="mbed + ethernet by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4065/4530348779_7b860c0cf2.jpg" width="500" height="375" alt="mbed + ethernet" /></a><br />
<br />
<br />
裏のピン配置がブレッドボードに刺せるピッチ幅ではなかったので、秋月で100円で売ってる両面ガラススルーホール基盤の切れ端とピンヘッダを駆使してピン配置を変更した。<br />
<a href="http://www.flickr.com/photos/shokai/4525012639/" title="ethernet jack for breadboard by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4037/4525012639_f15605d969.jpg" width="500" height="375" alt="ethernet jack for breadboard" /></a><br />
<a href="http://www.flickr.com/photos/shokai/4525012453/" title="ethernet jack for breadboard by shokai, on Flickr"><img src="http://farm5.static.flickr.com/4072/4525012453_d3cb5668ee.jpg" width="375" height="500" alt="ethernet jack for breadboard" /></a><br />
<br />
<br />
mbedにはHTTPClientというDNSやDHCPやHTTPを適当に解決してくれるモジュールがある。<br />
ほぼ<a href="http://mbed.org/projects/cookbook/wiki/EMAC/HTTPClient">mbed EMAC/HTTPClient</a>のまま動いた。<br />
HTTPClientを使うために、<br />
<pre>http://mbed.org/projects/cookbook/svn/EMAC/lwip/trunk</pre>
をprojectにimportする必要があった。mbedのエディタのGUIからimportできた。<br />
<br />
<a href="http://mbed.org/users/shokai/programs/tweet_test/60e2s/">tweet_test | mbed</a><br />
<pre class="prettyprint">
#include&nbsp;"mbed.h"<br />
#include&nbsp;"HTTPClient.h"<br />
using&nbsp;namespace&nbsp;std;<br />
<br />
DigitalOut&nbsp;led(LED1);<br />
<br />
HTTPClient&nbsp;http;&nbsp;//&nbsp;use&nbsp;DHCP<br />
<br />
/*&nbsp;//&nbsp;use&nbsp;static&nbsp;IP<br />
HTTPClient&nbsp;http("mbed",&nbsp;//&nbsp;hostname.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPv4(192,168,1,39),&nbsp;//&nbsp;IPv4&nbsp;address<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPv4(255,255,255,0),&nbsp;//&nbsp;netmask<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPv4(192,168,1,1),&nbsp;//&nbsp;default&nbsp;gateway<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPv4(192,168,1,1));&nbsp;//&nbsp;dns&nbsp;server<br />
/**/<br />
<br />
const&nbsp;char&nbsp;msg[]&nbsp;=&nbsp;"status=mbed&nbsp;test";<br />
<br />
int&nbsp;main(void)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;http.auth("username",&nbsp;"password");<br />
&nbsp;&nbsp;&nbsp;&nbsp;http.post("http://twitter.com/statuses/update.xml",&nbsp;msg);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;while(1)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led&nbsp;=&nbsp;!led;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wait(0.2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</pre>
twitter APIにbasic認証を通って<a href="http://twitter.com/shokai/status/12496686942">http-postし</a>、成功するとLED点滅のループに入る。<br />
<br />
twitter APIは同じtweetを連続で受け取らないようになっているので、このプログラムだと一度tweetした後はmsgを別の文字列に変えないと再確認できない。後ろに乱数とか時刻とかをつける必要がある。<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/5122/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>最近作ったYahooPipes</title>
		<link>http://shokai.org/blog/archives/5034</link>
		<comments>http://shokai.org/blog/archives/5034#comments</comments>
		<pubDate>Wed, 27 Jan 2010 07:22:50 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[YahooPipes]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=5034</guid>
		<description><![CDATA[Pipes: 秋月電子 新製品FullFeed 秋月のRSSが無くなったので、新製品ページから取り出した。 Pipes: ストロベリー・リナックス FullFeed strawberry-linux.comのnews f [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://pipes.yahoo.com/shokai/akizukidenshi">Pipes: 秋月電子 新製品FullFeed</a><br />
秋月のRSSが無くなったので、新製品ページから取り出した。<br />
<br />
<br />
<a href="http://pipes.yahoo.com/shokai/strawberry_linux">Pipes: ストロベリー・リナックス FullFeed</a><br />
strawberry-linux.comのnews feedがタイトルのみ配信だったので<br />
<br />
どちらも商品イメージとデータシートへのリンクと価格を入れてある。<br />
<br />
千石は元気の良いblogで新製品を教えてくれる。spark funと液晶工房もblogがある。スイッチサイエンスもフィード作ろうかと思ったけど新製品ページが半年ぐらい更新されてなかったからやめた。マルツもblogあるけど勉強会情報しかなくて、新製品情報はwebで一覧できない。電子工作系はいまだに新製品情報をネットで効率的に収集する手段が乏しいな。<br />
<br />
<br />
<a href="http://pipes.yahoo.com/pipes/pipe.info?_id=a814d8184634fbd81ac7c3263ec2b752">Pipes: twitter list timeline</a><br />
twitterのlist機能にrssが無いので。list出た時に作ったんだけど、twitterのHTMLが変わっていつのまにか動かなくなってたのを修理した。<br />
ユーザ名とlist名を入れるとRSSを出す。他人の作ったlistをいろいろ購読してみてる。<br />
<br />
<br />
pipesってソースのHTMLが変わっていつのまにかエラーになってるんだけど、RSSリーダに登録してるだけだと配信されなくなるだけで、「動かなくなった」事に気づけないんだよなあ<br />
なんとかならないものか。1件も出力できなかったら一番上にエラー文を入れるようにすればいいのか？<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/5034/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>opencv-haartrainingの進行状況をtwitterに流すbot</title>
		<link>http://shokai.org/blog/archives/4872</link>
		<comments>http://shokai.org/blog/archives/4872#comments</comments>
		<pubDate>Sun, 15 Nov 2009 13:32:04 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[haarlike-feature]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=4872</guid>
		<description><![CDATA[OpenCVをソースからビルドするとhaarlike分類器（顔認識などに使われているやつ）の学習ツールが手に入るんだけど、たくさんのマシンでたくさん学習させているとそれぞれの進行状況をチェックするのが面倒になってくる。  [...]]]></description>
			<content:encoded><![CDATA[<p>
OpenCVをソースからビルドするとhaarlike分類器（顔認識などに使われているやつ）の学習ツールが手に入るんだけど、たくさんのマシンでたくさん学習させているとそれぞれの進行状況をチェックするのが面倒になってくる。<br />
<br />
でも、入力した画像ファイルが壊れていると学習が強制終了してしまったり、データがばらつきすぎてて収束しなくてあきらめて終了されたりするので、プロセスが死んでいたらパラメータを直してすぐやり直しをさせたい。学習中は予断を許さない状況が続く。<br />
<br />
なので、進行状況を監視してtwitterアカウント<a href="http://twitter.com/shokai_log">shokai_log</a>にpostするbotを作った。<br />
5分間隔でopencv-haartrainingの作業ディレクトリとプロセスが生きているかをチェックする。<br />
学習stageが進む毎に適当に通知し、プロセスが強制終了していた場合は激しくreplyしてくれる。これで安心して寝れる。OpenCV1.0/2.0両方対応。<br />
<ul>
<li><a href="http://shokai.org/archive/ruby/tweet-haartraining.rb">tweet-haartraining.rb</a></li>
</ul>
プロセスが落ちていると<a href="http://twitter.com/shokai_log/status/5682866701">教えてくれたり</a>、段階が進む毎にtwitterに投稿したりする。<br />
一見何言ってるのかわかりにくいpostもあるが、「ドドドド」だったらstage4が終わったという意味。<br />
<a href="http://www.flickr.com/photos/shokai/4104968309/" title="tweet-haartraining.rb by shokai, on Flickr"><img src="http://farm3.static.flickr.com/2509/4104968309_dbe6db02b5_o.png" width="578" height="1010" alt="tweet-haartraining.rb" /></a><br />
辞書はコード内にある。<br />
<br />
<br />
第2引数にopencv-haartrainingの-dataオプションで渡した「結果の書き出し先ディレクトリ名」を指定する。第3引数は無しでもいいが、twitter投稿の末尾にメモを付けられる。複数のマシンで実行していてどれの進行状況かわからなくなる時は、マシンの名前を入れておけばいい。<br />
<pre>
ruby tweet-haartraining.rb /Users/sho/path/to/training/dir/ "Macbook黒"<br />
</pre>
<br />
<a href="http://shokai.org/archive/ruby/tweet-haartraining.rb">tweet-haartraining.rb</a><br />
<pre class="prettyprint">
#!/usr/bin/env&nbsp;ruby<br />
#&nbsp;-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-<br />
require&nbsp;'rubygems'<br />
require&nbsp;'twitter'<br />
<br />
#&nbsp;setting<br />
USER&nbsp;=&nbsp;'your-account'<br />
PASS&nbsp;=&nbsp;'your-password'<br />
INTERVAL&nbsp;=&nbsp;300&nbsp;#&nbsp;sleep&nbsp;sec<br />
YOU&nbsp;=&nbsp;'shokai'&nbsp;#&nbsp;時々replyしてくる&nbsp;nilでreplyなし<br />
NOPOST&nbsp;=&nbsp;false&nbsp;#&nbsp;debug用<br />
<br />
def&nbsp;post(message)<br />
&nbsp;&nbsp;return&nbsp;if&nbsp;!message<br />
&nbsp;&nbsp;message&nbsp;=&nbsp;"@#{YOU}&nbsp;#{message}"&nbsp;if&nbsp;rand(3)&lt;1&nbsp;if&nbsp;!(message&nbsp;=~&nbsp;/@#{YOU}/)&nbsp;&amp;&amp;&nbsp;rand(2)&lt;1<br />
&nbsp;&nbsp;puts&nbsp;message&nbsp;+&nbsp;"\t"&nbsp;+&nbsp;Time.now.to_s<br />
&nbsp;&nbsp;return&nbsp;if&nbsp;NOPOST<br />
&nbsp;&nbsp;httpAuth&nbsp;=&nbsp;Twitter::HTTPAuth.new(USER,&nbsp;PASS)<br />
&nbsp;&nbsp;tw&nbsp;=&nbsp;Twitter::Base.new(httpAuth)<br />
&nbsp;&nbsp;tw.update(message)<br />
end<br />
<br />
if&nbsp;ARGV.size&nbsp;&lt;&nbsp;1<br />
&nbsp;&nbsp;puts&nbsp;'結果が出力されるディレクトリへのパスが必要です。メモも付けられます(オプション)'<br />
&nbsp;&nbsp;puts&nbsp;'e.g.&nbsp;ruby&nbsp;tweet-haartraining.rb&nbsp;/path/to/haar/training/dir/&nbsp;"研究室の学習用パソコン"'<br />
&nbsp;&nbsp;exit&nbsp;1<br />
end<br />
<br />
puts&nbsp;path&nbsp;=&nbsp;ARGV.shift<br />
memo&nbsp;=&nbsp;ARGV.shift&nbsp;||&nbsp;""<br />
dir_path&nbsp;=&nbsp;path<br />
if&nbsp;path&nbsp;=~&nbsp;/\/$/<br />
&nbsp;&nbsp;dir_path&nbsp;=&nbsp;path<br />
&nbsp;&nbsp;xml_path&nbsp;=&nbsp;path[0...path.size-1]+'.xml'<br />
else<br />
&nbsp;&nbsp;dir_path&nbsp;=&nbsp;path+'/'<br />
&nbsp;&nbsp;xml_path&nbsp;=&nbsp;path+'.xml'<br />
end<br />
<br />
<br />
if&nbsp;stage_p&nbsp;=&nbsp;Dir.glob(dir_path+'*').delete_if{|i|&nbsp;File::ftype(i)&nbsp;!=&nbsp;'directory'}.map{|i|&nbsp;i.split(/\//).last.to_i}.max<br />
&nbsp;&nbsp;post&nbsp;"ステージ#{stage_p}から開始"&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;memo<br />
else<br />
&nbsp;&nbsp;messages&nbsp;=&nbsp;["開始。",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"はじめ",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"起床",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"おきた",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"start",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"スタートしました",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"hello&nbsp;world",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"hello&nbsp;work",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"はじめますわっ",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"スタンバイレディ&nbsp;セタップ"]<br />
&nbsp;&nbsp;post&nbsp;messages[rand(messages.size)]&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;memo<br />
end<br />
<br />
<br />
while&nbsp;true&nbsp;do<br />
&nbsp;&nbsp;sleep&nbsp;INTERVAL<br />
&nbsp;&nbsp;stage&nbsp;=&nbsp;Dir.glob(dir_path+'*').delete_if{|i|&nbsp;File::ftype(i)&nbsp;!=&nbsp;'directory'}.map{|i|&nbsp;i.split(/\//).last.to_i}.max<br />
&nbsp;&nbsp;if&nbsp;File.exists?&nbsp;xml_path<br />
&nbsp;&nbsp;&nbsp;&nbsp;messages&nbsp;=&nbsp;["全行程完了(ステージ#{stage})。お疲れ様でした。",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"全部オワタ(#{stage})",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"修了しました",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"寝る。#{stage}時に起きる。",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"終わったので、#{stage}時に帰ります",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"全段階完了しました。データを回収し、電源を落としてください(#{xml_path.split(/\//).last})",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"全ステージ完了しました(#{xml_path.split(/\//).last})",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ⓢⓤⓨⓐⓡⓘ"]<br />
&nbsp;&nbsp;&nbsp;&nbsp;post&nbsp;"@#{YOU}&nbsp;"&nbsp;+&nbsp;messages[rand(messages.size)]&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;memo<br />
&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;0<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;if&nbsp;nil&nbsp;==&nbsp;`ps&nbsp;aux&nbsp;|&nbsp;grep&nbsp;opencv-haartraining`.split(/[\r\n]/).delete_if{|m|m=~/grep&nbsp;opencv-haartraining/}.first<br />
&nbsp;&nbsp;&nbsp;&nbsp;messages&nbsp;=&nbsp;["#{stage}段階目まで来たけど異常終了したかも",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"落ちてる",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ERROR!&nbsp;haartraining&nbsp;is&nbsp;not&nbsp;working.&nbsp;please&nbsp;restart&nbsp;\(^o^)/",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"異常終了",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"異常です",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"動いてないっぽい・・・",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"死んだかも",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"だめっぽい・・",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"おい、異常終了してるぞ",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"冒&nbsp;険&nbsp;の&nbsp;書&nbsp;(#{stage})&nbsp;は&nbsp;消&nbsp;え&nbsp;ま&nbsp;し&nbsp;た",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"おお、死んでしまうとは情けない",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\(^o^)/"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ピッコロの気が消えた",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"なん・・だと・・",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"#{stage}面でピチュった"]<br />
&nbsp;&nbsp;&nbsp;&nbsp;post&nbsp;"@#{YOU}&nbsp;"&nbsp;+&nbsp;messages[rand(messages.size)]&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;memo<br />
&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;INTERVAL*2<br />
&nbsp;&nbsp;&nbsp;&nbsp;next<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;next&nbsp;if&nbsp;stage&nbsp;==&nbsp;stage_p&nbsp;or&nbsp;stage&nbsp;==&nbsp;nil<br />
&nbsp;&nbsp;stage_p&nbsp;=&nbsp;stage<br />
&nbsp;&nbsp;messages&nbsp;=&nbsp;["#{stage}段階目まで進みました",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"バリバリです(stage#{stage})",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ばっちりですわっ",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"------ここまで読んだ(#{stage})------",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"がんばってます(#{stage})",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"stage&nbsp;#{stage}",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ステージ#{stage}なう",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"now&nbsp;finished&nbsp;stage#{stage}.",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"よし！ステージ#{stage}まで終わった！！！",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"うわ"+"あ"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ド"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ゴ"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ゴ"+"ー"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"もりもり",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ふむふむなるほど"+"・"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"頭が"*stage+"おかしくなりそうだ",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"もういや",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"無理"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ズザ"+"ー"*stage,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"帰りたい",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"まだ#{stage}段階目だ",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"もうstage#{stage}まで終わった。超はやい",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"もうstage#{stage}まで終わった",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"stage#{stage}まで終わった",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"stage#{stage}まで終わったし",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ククク・・遂に#{stage}界までまで昇ってきたか・・・",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ⓢⓤⓨⓐ"*stage]<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;post&nbsp;messages[rand(messages.size)]&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;memo<br />
end<br />
</pre>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/4872/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitterの地名なうbotを全blockするOAuthアプリ</title>
		<link>http://shokai.org/blog/archives/4698</link>
		<comments>http://shokai.org/blog/archives/4698#comments</comments>
		<pubDate>Thu, 13 Aug 2009 00:32:05 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sinatra]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=4698</guid>
		<description><![CDATA[http://shokai.mag.keio.ac.jp/block_nowbots/から使える。 （8月15日：URL変更しました） とりあえずSinatraとOAuthの組み合わせを試してみたかったので、DBは使わな [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://shokai.mag.keio.ac.jp/block_nowbots/">http://shokai.mag.keio.ac.jp/block_nowbots/</a>から使える。<br />
（8月15日：<a href="http://shokai.org/blog/archives/4717">URL変更しました</a>）<br />
<br />
とりあえずSinatraとOAuthの組み合わせを試してみたかったので、DBは使わないものを作りたかった。取得したOAuthのtokenなどはその場で捨てている。blockコマンドを送る権限だけを一時的に委譲してもらう。<br />
<br />
<br />
以下技術的なことのメモ。<br />
■OAuthアプリの登録<br />
まず<a href="http://twitter.com/oauth_clients">http://twitter.com/oauth_clients</a>でアプリを登録し、consumer keyとconsumer secretを取得する。<br />
で、下のコード中のCONSUMER_KEY, CONSUMER_SECRETを書き換える。<br />
<br />
<br />
■必要なライブラリ<br />
必要なgemをインストールする。最新版にした。<br />
<pre>
sudo gem install oauth twitter sinatra<br />
</pre>
それぞれ0.3.5, 0.6.13, 0.9.4がインストールされた。<br />
twitterは内部でoauthに依存していて、oauthはバージョン毎に関数がけっこう変わっている。このバージョンの組み合わせなら動く。<br />
<br />
<br />
■動かす<br />
そして起動。<br />
<pre>
ruby block-nowbots.rb -p 2692 -s mongrel<br />
</pre>
thinだと複数クライアントから同時にアクセスした時1クライアントずつしか対応してくれなかったんだけど、mongrelは全クライアントに同時に応答してくれた。mongrelにいつのまにかそういう機能がついたのか、sinatraのバグでthinがthread処理されないのかはよくわからない。<br />
sinatraもrailsと同じくデプロイまわりを工夫した方がよさそう。passenger使うのがいいのかな？<br />
<br />
<br />
参考：<br />
<ul>
  <li>OAuth関連<ul>
      <li><a href="http://d.hatena.ne.jp/shibason/20090802/1249204953">TwitterのbotをOAuthに対応させる &#8211; しばそんノート</a></li>
      <li><a href="http://tech.lampetty.net/tech/index.php/archives/323">RailsでTwitterのOAuthを試す | おいぬま日報</a></li>
      <li><a href="http://ukstudio.jp/2009/07/rails_oauth_twitter/">UK STUDIO &#8211; RailsからOAuthを利用してTwitterにポストする</a></li>
      <li><a href="http://d.hatena.ne.jp/shokai/20090812/1250075000">twitterのOAuthでaccess tokenとaccess secretを手に入れる &#8211; 橋本詳解</a></li>
      <li><a href="http://d.hatena.ne.jp/shokai/20090813/1250118116">twitter APIをOAuthから使う &#8211; 橋本詳解</a></li>
  </ul></li>
  <li>Sinatra関連<ul>
      <li><a href="http://gihyo.jp/dev/serial/01/ruby/0007">Ruby Freaks Lounge：第7回　小規模Webアプリのためのフレームワーク，Sinatra｜gihyo.jp … 技術評論社</a></li>
      <li><a href="http://d.hatena.ne.jp/shokai/20090601/1243835094">sinatraインストール、動かしてみる &#8211; 橋本詳解</a></li>
      <li><a href="http://d.hatena.ne.jp/shokai/20090812/1250107072">コード自動リロードを有効にする &#8211; 橋本詳解</a></li>
      <li><a href="http://d.hatena.ne.jp/shokai/20090812/1250109292">sessionの読み書き &#8211; 橋本詳解</a></li>
  </ul></li>
</ul>
<br />
<br />
block-nowbots.rb<br />
<pre class="prettyprint">
#!/usr/bin/env&nbsp;ruby<br />
require&nbsp;'rubygems'<br />
require&nbsp;'sinatra'<br />
require&nbsp;'oauth'<br />
require&nbsp;'twitter'<br />
<br />
HOST_AND_PORT&nbsp;=&nbsp;"localhost:2692"<br />
<br />
CONSUMER_KEY&nbsp;=&nbsp;"your-consumer-key"<br />
CONSUMER_SECRET&nbsp;=&nbsp;"your-consumer-secret"<br />
<br />
BOTS&nbsp;=&nbsp;'nishinipporinow,nippori_now,kanda_now,tabata_now,sugamo_now,komagome_now,shinokubo_now,mejiro_now,takadanobabanow,okachimachi_now,uguisudani_now,ikebukuro_now,otsuka_now,akiba_now,tokyo_now,harajuku_now,shibuya_now,shibuya_now,yoyogi_now,shinjuku_now,ebisu_now'<br />
<br />
set&nbsp;:sessions,&nbsp;true<br />
def&nbsp;consumer<br />
&nbsp;&nbsp;OAuth::Consumer.new(CONSUMER_KEY,&nbsp;CONSUMER_SECRET,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:site&nbsp;=&gt;&nbsp;"http://twitter.com")<br />
end<br />
<br />
template&nbsp;:layout&nbsp;do<br />
&nbsp;&nbsp;'&lt;html&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&gt;地名なうbotを全blockするOAuthアプリ&lt;/h1&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;%=&nbsp;yield&nbsp;%&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;hr&nbsp;style="margin-top:&nbsp;100px"&nbsp;/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a&nbsp;href="http://shokai.org"&gt;http://shokai.org&lt;/a&gt;&lt;br&nbsp;/&gt;&lt;a&nbsp;href="http://shokai.org/blog/archives/4698"&gt;解説&lt;/a&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/html&gt;'<br />
end<br />
<br />
get&nbsp;'/'&nbsp;do<br />
&nbsp;&nbsp;@request_token&nbsp;=&nbsp;consumer.get_request_token(:oauth_callback&nbsp;=&gt;&nbsp;"http://#{HOST_AND_PORT}/auth")<br />
&nbsp;&nbsp;session[:request_token]&nbsp;=&nbsp;@request_token.token<br />
&nbsp;&nbsp;session[:request_token_secret]&nbsp;=&nbsp;@request_token.secret<br />
&nbsp;&nbsp;erb&nbsp;%{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;&lt;%=&nbsp;BOTS&nbsp;%&gt;&lt;br&nbsp;/&gt;をblock設定します&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;OAuth認証してください&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;a&nbsp;href="&lt;%=&nbsp;@request_token.authorize_url&nbsp;%&gt;"&gt;認証する！&lt;/a&gt;<br />
&nbsp;&nbsp;}<br />
end<br />
<br />
get&nbsp;'/auth'&nbsp;do<br />
<br />
&nbsp;&nbsp;@request_token&nbsp;=&nbsp;OAuth::RequestToken.new(consumer,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:request_token],<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:request_token_secret])<br />
&nbsp;&nbsp;@access_token&nbsp;=&nbsp;@request_token.get_access_token({},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:oauth_token&nbsp;=&gt;&nbsp;params[:oauth_token],<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:oauth_verifier&nbsp;=&gt;&nbsp;params[:oauth_verifier])<br />
&nbsp;&nbsp;session[:access_token]&nbsp;=&nbsp;@access_token.token<br />
&nbsp;&nbsp;session[:access_token_secret]&nbsp;=&nbsp;@access_token.secret<br />
<br />
&nbsp;&nbsp;erb&nbsp;%{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;認証成功&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;&lt;a&nbsp;href="/block_now_bots"&gt;地名なうbotをblockする&lt;/a&gt;(全部で&lt;%=&nbsp;BOTS.split(",").size*3&nbsp;%&gt;秒くらいかかる)&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;a&nbsp;href='/'&gt;戻る&lt;/a&gt;<br />
&nbsp;&nbsp;}<br />
end<br />
<br />
get&nbsp;'/block_now_bots'&nbsp;do<br />
&nbsp;&nbsp;oauth&nbsp;=&nbsp;Twitter::OAuth.new(CONSUMER_KEY,&nbsp;CONSUMER_SECRET)<br />
&nbsp;&nbsp;oauth.authorize_from_access(session[:access_token],&nbsp;session[:access_token_secret])<br />
&nbsp;&nbsp;twit&nbsp;=&nbsp;Twitter::Base.new(oauth)<br />
&nbsp;&nbsp;BOTS.split(",").each{|bot|<br />
&nbsp;&nbsp;&nbsp;&nbsp;twit.block(bot)<br />
&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;"block&nbsp;#{bot}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;3<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;erb&nbsp;%{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;たぶんblockしました&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;&lt;a&nbsp;href="http://twitter.com/yamanote_now/following"&gt;確認&lt;/a&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;}<br />
end<br />
</pre>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/4698/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>buzztterでtimelineを作るYahoo Pipes</title>
		<link>http://shokai.org/blog/archives/4606</link>
		<comments>http://shokai.org/blog/archives/4606#comments</comments>
		<pubDate>Mon, 13 Jul 2009 03:06:51 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[YahooPipes]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=4606</guid>
		<description><![CDATA[buzztter.comでtwitter上の最近の頻出単語の統計を出してくれている。 頻出語の上位5単語で検索してタイムラインを作るYahoo Pipesを作った。 → Pipes: buzztter timeline  [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://buzztter.com/ja">buzztter.com</a>でtwitter上の最近の頻出単語の統計を出してくれている。<br />
頻出語の上位5単語で検索してタイムラインを作るYahoo Pipesを作った。<br />
<br />
→ <a href="http://pipes.yahoo.com/shokai/buzztter_timeline">Pipes: buzztter timeline</a><br />
<br />
1週間ぐらい見ているが、だいたいみんなテレビとかゲームとか選挙とか芸能人の話題、眠気や月曜日出勤したくないなどの体調の問題を喋っている。ワイドショー的。<br />
上位3語や10語も試したけど、5語ぐらいが話題がバラけすぎもせず偏りすぎもせずちょうどよかった。<br />
<br />
<br />
前作「<a href="http://shokai.org/blog/archives/4572">twitter上で親しい人のタイムラインを動的に生成するYahoo Pipes</a>」は自分に近い人がでてくるけど、今度のはtwitterの中心近くで騒いでいる人たちが見える。<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/4606/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>twitter上で親しい人のタイムラインを動的に生成するYahoo Pipes</title>
		<link>http://shokai.org/blog/archives/4572</link>
		<comments>http://shokai.org/blog/archives/4572#comments</comments>
		<pubDate>Fri, 03 Jul 2009 15:58:40 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[YahooPipes]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=4572</guid>
		<description><![CDATA[修論を出した後のテンションでまたYahooPipesを作った。 → Pipes: twitter dynamic timeline 親しい人で動的にタイムラインを作るpipes。 しくみは単純で、最近favを付けたり付け [...]]]></description>
			<content:encoded><![CDATA[<p>
修論を出した後のテンションでまたYahooPipesを作った。<br />
<br />
→ <a href="http://pipes.yahoo.com/shokai/twitter_dynamic_timeline">Pipes: twitter dynamic timeline</a><br />
<br />
<br />
親しい人で動的にタイムラインを作るpipes。<br />
しくみは単純で、最近favを付けたり付けられたり、replyしたりされたりした相手でタイムラインを作る。<br />
自分の発言内容やそれに対する相手の反応によってメンバーが動的に入れ替わる。<br />
<br />
これの面白いのは、キーワードでの振り分けと異なりごく普通にtwitterを使っているだけでタイムラインが親しいメンツに変わっていく。<br />
一見流動性が無いように見えるが、自分をふぁぼったりreplyしてきた人は入ってくるし、その人にreplyしたりfavし返せばしばらくはdynamic timelineに入り続ける。相手をfollowする必要すらない。<br />
<br />
忙しくてtwitter見れない時は、これだけ見ておけば親しい人のpostはだいたいチェックできるかもしれない。<br />
<br />
<br />
RSSには<a href="http://usericons.relucks.org/">usericons.relucks.org</a>を使ってアイコンを表示した。ユーザ名やURLもリンクになるようにしてある。<br />
<a href="http://www.flickr.com/photos/shokai/3683566701/" title="twitter dynamic timeline by shokai, on Flickr"><img src="http://farm4.static.flickr.com/3657/3683566701_53ba45782e.jpg" width="500" height="364" alt="twitter dynamic timeline" /></a><br />
<br />
<br />
pipes全体図<br />
<a href="http://www.flickr.com/photos/shokai/3683566979/" title="twitter dynamic timeline by shokai, on Flickr"><img src="http://farm4.static.flickr.com/3622/3683566979_ca3f20f568.jpg" width="447" height="500" alt="twitter dynamic timeline" /></a><br />
<br />
<br />
一番上ですぐ分岐させて、左から順に<br />
<ul>
  <li>favをもらった相手：favotterの<a href="http://favotter.matope.com/user.php?user=shokai">ユーザページ</a>からHTMLスクレイピングしてる</li>
  <li>最近replyを受けた相手：オフィシャルtwitter検索で<a href="http://search.twitter.com/search?q=@shokai">ユーザ名検索</a>してatom feedから取得</li>
  <li>favをつけた相手：<a href="http://twitter.com/shokai/favorites">ユーザのfavページ</a>からatom feedで取得</li>
  <li>最近自分がreplyした人：<a href="http://twitter.com/shokai">自分のpost</a>からatom feedで取得</li>
</ul>
という具合。<br />
<br />
YahooPipesは処理時間が長くなりすぎるか、pipesから相手へのアクセスが多くなりすぎるとエラーが出てしまう。<br />
<br />
処理時間が長くならないようにするには並列化。pipeを縦につなげないようにする。<br />
重要なのはpipesから外部サイトへのHTTPリクエストからレスポンスまでの時間だと思う。米yahooの強力なサーバーなので正規表現でページ解析する処理時間はたぶん無視していい。<br />
<br />
今回上の方で4つに分けているように、早めにsplitモジュールで分けてそれぞれでHTTPリクエストを発行させてレスポンス待ちにすると速い。splitで分けられたそれぞれと、Loopモジュール内でFetch PageやFetch Feedモジュールは自動的にpipes内で非同期処理になってそうな気がする。<br />
※この時どれかで取得した結果を他のsplit先に使おうとすると、結局縦に1本につなげているのと変わらなくなってしまうので注意しましょう<br />
<br />
pipesから他のサイトへのアクセスについては、twitterとyahooが地理的に遠くないからなのか制限が緩くなっているのかよくわからないが、3秒で100アクセスぐらいしてるのにエラーはでない。<br />
<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/4572/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

