<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>We Ain&apos;t Seen Nothin&apos; Yet.</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/" />
    <link rel="self" type="application/atom+xml" href="http://blog.fulltext-search.biz/xml/atom/feed.xml" />
    <id>tag:blog.fulltext-search.biz,2009-03-10://1</id>
    <updated>2010-05-06T00:28:13Z</updated>
    <subtitle>(X)HTML, CSS, Ruby, Rails, JavaScript, Web, 新しいものやおもしろいものを</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Commercial 4.261</generator>

<entry>
    <title>ブラウザベースでは無いアプリケーションからtwitterのOAuth認証するシンプルな方法(Ruby)</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2010/05/twitter-oauth-ruby.html" />
    <id>tag:blog.fulltext-search.biz,2010://1.77</id>

    <published>2010-05-06T00:00:00Z</published>
    <updated>2010-05-06T00:28:13Z</updated>

    <summary>2010/06/30でtwitter APIのBasic認証が廃止され、以降はOAuth認証を利用してAPIを利用するようにtwitter関連のアプリケーション開発者は対応が必要な状況です。しかし、デスクトップアプリケーションやbotなど、ユーザがブラウザで利用することを想定していないアプリケーションで、twitter APIのOAuth認証を利用するための情報はまだ少ない状況なので、rubyのブラウザベースではないアプリケーションからOAuth認証を利用するシンプルな方法をご紹介します。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="oauth" label="oauth" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="twitter" label="twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2010y05m06d_084050953.jpg"><img alt="2010y05m06d_084050953.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2010/05/2010y05m06d_084050953-thumb-400x160-74.jpg" width="400" height="160" class="mt-image-none" style="" /></a></span></p>

<p><a href="http://www.itmedia.co.jp/enterprise/articles/1004/28/news012.html">2010/06/30でtwitter APIのBasic認証が廃止</a>されます。
<a href="http://www.countdowntooauth.com/">Basic認証からOAuth認証へのカウントダウンサイト</a>もできていて、twitter関連のアプリケーション開発者は対応が必要な状況ですね。</p>

<p>ブラウザベースのアプリケーション(WebService)では、各種ライブラリや<a href="http://dev.twitter.com/anywhere">twitter @anywhere</a>を利用して比較的簡単にOAuth認証へ移行できるかと思いますが、デスクトップアプリケーションやbotなど、ユーザがブラウザで利用することを想定していないアプリケーションで、twitter APIのOAuth認証を利用するための情報はまだ少ない状況です。</p>

<p>そこで、rubyの（一般的な）twitterライブラリ<a href="http://twitter.rubyforge.org/">twitter gem</a>を使って、ブラウザベースではないアプリケーションからOAuth認証を利用するシンプルな方法をご紹介します。</p>

<p>クライアントアプリケーションとして対話型のrubyクライアントであるirbを利用します。rubyがインストールされている環境であれば標準で利用できるものです。</p>

<p>以下に、実際のソースコードも含めてご紹介します。</p>
]]>
        <![CDATA[<h3>事前に用意するもの</h3>

<ul>
<li>ruby</li>
<li>twitter gem（<var>sudo gem install twitter</var>でインストールしておく）</li>
<li>OAuthのアプリケーション登録</li>
<li>twitterに登録したアプリケーションの「Consumer key」と「Consumer secret」</li>
</ul>

<h4>OAuthのアプリケーション登録</h4>

<p><a href="http://twitter.com/oauth_clients">twitterアプリケーションページ</a>から<a href="http://twitter.com/apps/new">登録</a>してください。</p>

<p>今回は、ブラウザベースではないアプリケーションからOAuth認証を利用するので、「Application Type」は<var>Client</var>を選択します。</p>

<p>このときのアプリケーション名やWebSiteなどは後からでも変更できるので、とりあえずさくっと登録してみるのが良いと思います。</p>

<h4>「Consumer key」と「Consumer secret」</h4>

<p>上記で登録した（または登録してあった）アプリケーションを、<a href="http://twitter.com/oauth_clients">twitterアプリケーションページ</a>から選択し、<var>Consumer key</var>と<var>Consumer secret</var>を控えておいてください。</p>

<h3>準備が整ったらさっそく試してみましょう</h3>

<h4>irbを起動します</h4>

<p>まずは、irbを起動します。この起動したirbはずっと使いますので、途中で終了しないようにしてください。</p>

<pre name="code" class="brush: bash">
$ irb -rrubygems -rtwitter
</pre>

<p><var>rubygems</var>と<var>twitter</var>をrequireしています。</p>

<h4>認証番号(PIN)の発行</h4>

<p>ブラウザベースではないアプリケーションでも一度だけブラウザでtwitterにアクセスして、ログインのための認証番号(PIN)を発行する必要があります。</p>

<pre name="code" class="brush: ruby">
consumer_token = "XXXXXXX" # ここに「Consumer key」
consumer_secret = "YYYYYYYY" # ここに「Consumer secret」
tauth = Twitter::OAuth.new(consumer_token, consumer_secret)
request = tauth.consumer.get_request_token
puts request.authorize_url
# => http://twitter.com/oauth/authorize?oauth_token=ZZZZZZZZZZ
</pre>

<p>ここでは、<var>Consumer key</var>と<var>Consumer secret</var>を使って認証番号(PIN)発行ページのURLを作成します。</p>

<p>表示されたURLにブラウザでアクセスすると、アプリケーションからアカウントへのアクセスを許可するかどうかの画面がでますので、登録したアプリケーションへのアクセスを「許可(Allow)」します。</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2010y05m06d_092324343.jpg"><img alt="2010y05m06d_092324343.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2010/05/2010y05m06d_092324343-thumb-400x178-76.jpg" width="400" height="178" class="mt-image-none" style="" /></a></span></p>

<p>すると、上の画像のように「暗証番号(PIN)」が発行されるので控えておきます。</p>

<h4>「Access token」と「Access secret」の生成</h4>

<p>先ほどのirbに戻り、認証番号(PIN)を利用して<var>Access token</var>と<var>Access secret</var>を生成します。これがアプリケーションにおけるパスワード代わりになります。</p>

<pre name="code" class="brush: ruby">
pin = "DDDDDDD" # ここに「暗証番号(PIN)」
atoken, asecret = tauth.authorize_from_request(request.token, request.secret, pin)
twitter_client = Twitter::Base.new(tauth)
</pre>

<p>これで、<var>twitter_client</var>がOAuthで認証されたので、</p>

<pre name="code" class="brush: ruby">
p twitter_client.home_timeline
# => .... 自分のタイムライン取得 ....
</pre>

<p>などとしてtwitter APIを利用できます。</p>

<h4>2回目以降の利用</h4>

<p>毎回ブラウザを開いて暗証番号(PIN)を取得していてはブラウザベースではないアプリケーションとして成り立ちません。2回目以降に暗証番号(PIN)無しで認証するためには、先ほどの<var>Access token</var>と<var>Access secret</var>を保存しておきます。</p>

<pre name="code" class="brush: ruby">
tauth = Twitter::OAuth.new(consumer_token, consumer_secret)
tauth.authorize_from_access(atoken, asecret) # 保存しておいたAccess token, Access secret
twitter_client = Twitter::Base.new(tauth)
p twitter_client.home_timeline
# => .... 自分のタイムライン取得 ....
</pre>

<p>上記のようにすれば、暗証番号(PIN)無しで認証されます。</p>

<h3>ご注意</h3>

<p>平文でアカウントとパスワードは見えませんが、atoken, asecret はそれと等しいので保管には注意しましょう。</p>

<p><var>Access token</var>と<var>Access secret</var>の有効期限については、言及を見つけられませんでした。永続利用できないかもしれませんので、アプリケーション側でexpireするなどが必要かもしれません。（ご存じの方がいらっしゃれば教えてください）</p>

<h3>最後に</h3>

<p>Basic認証からOAuth認証への移行ができないと、あなたのbotが6/30で動かなくなります。本記事が移行の手助けになれば幸いです。</p>

<p>なお、本記事上のソースコードは<a href="http://www.opensource.org/licenses/mit-license.php">The MIT License</a>です。（たいしたコードではありませんが）</p>

<p>最後までお読みいただきありがとうございます。</p>
]]>
    </content>
</entry>

<entry>
    <title>RedisをCentOSにインストールして起動スクリプトを書いてみた</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2010/04/redis-server-initialize-script-for-centos.html" />
    <id>tag:blog.fulltext-search.biz,2010://1.76</id>

    <published>2010-04-24T12:00:00Z</published>
    <updated>2010-04-24T12:46:12Z</updated>

    <summary>Key-Value StorageのRedisを試すために起動・停止・再起動スクリプトを作成しました。また、CentOSの起動時のスクリプトに登録するところまでを自分用にメモとして残しています。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="centos" label="centos" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="redis" label="redis" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p>自分用にメモ。</p>

<p>Key-Value Storageの<a href="http://code.google.com/p/redis/">Redis</a>を試してみた。</p>

<p>インストールは簡単で起動も簡単だけど、サーバリブート時にどうしよう？と思って探してみたら
<a href="http://stbr.no-ip.org/daizu/2009/11/redis-tips.html">Redis 起動時 Tips</a>
というサイトがあったので、参考にさせていただきながらCentOSの起動時のスクリプトに登録するところまで書いてみた。</p>

<h3>インストール</h3>

<p>インストール（コンパイル）は<a href="http://code.google.com/p/redis/wiki/QuickStart">QuickStart</a>どおり。</p>

<p>私の環境の場合は、makeしたあとそのディレクトリを<var>/usr/local/lib/redis</var>に置いてみた。（あってるのかな？）</p>

<p>続きには、confファイルや起動スクリプト、CentOSの起動時スクリプトへの登録について書いてます。</p>
]]>
        <![CDATA[<h3>redis.conf</h3>

<p>起動時にデーモン化したり、ログファイルを作ったりするように、オリジナルに変更を加えています。</p>

<pre name="code" class="brush: bash">
% diff -u redis.conf.org redis.conf
--- redis.conf.org      2009-12-24 23:41:51.000000000 +0900
+++ redis.conf  2010-04-24 19:19:26.000000000 +0900
@@ -2,7 +2,7 @@

 # By default Redis does not run as a daemon. Use 'yes' if you need it.
 # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
-daemonize no
+daemonize yes

 # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
 # You can specify a custom pid file location here.
@@ -24,12 +24,12 @@
 # debug (a lot of information, useful for development/testing)
 # notice (moderately verbose, what you want in production probably)
 # warning (only very important / critical messages are logged)
-loglevel debug
+loglevel notice

 # Specify the log file name. Also 'stdout' can be used to force
 # the demon to log on the standard output. Note that if you use standard
 # output for logging but daemonize, logs will be sent to /dev/null
-logfile stdout
+logfile /var/log/radis

 # Set the number of databases. The default database is DB 0, you can select
 # a different one on a per-connection basis using SELECT <dbid> where
</pre>

<h3>起動・停止・再起動とかのスクリプト</h3>

<p><var>redis-server</var>や<var>redis.conf</var>の場所は環境によって違うと思うので適宜読み替えてください。</p>

<h4>radis という名前のファイルとして保存</h4>

<pre name="code" class="brush: bash">
#!/bin/sh
#
# redis
#
# chkconfig: 2345 90 35
# description: redis-server start/stop script

# Source function library.
. /etc/rc.d/init.d/functions

start() {
    # Start daemon
    if [ -f /var/run/redis.pid ]; then
        echo "redis-server is already started"
    else
        /usr/local/lib/redis/redis-server /usr/local/lib/redis/redis.conf
    fi
}

stop() {
    # Stop daemon
    if [ -f /var/run/redis.pid ]; then
        kill `cat /var/run/redis.pid`
        rm -f /var/run/redis.pid
    else
        echo "redis-server is not running"
    fi
}

status() {
    /usr/local/lib/redis/redis-stat
}

case $1 in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    status)
        status
        ;;
    *)
        echo "Usage: redis {start|stop|restart|status}"
        ;;
esac
</pre>

<h3>CentOSの起動時スクリプトとして登録</h3>

<ul>
<li><var>$ chmod +x redis</var>：上記の起動・停止・再起動スクリプトに実行権限を付与</li>
<li><var>$ sudo mv redis /etc/rc.d/init.d/redis</var>：起動時スクリプトとして設置</li>
<li><var>$ sudo /etc/rc.d/init.d/redis start</var>：起動する</li>
<li><var>$ sudo chkconfig --add redis</var>：起動時スクリプトに追加</li>
<li><var>$ sudo chkconfig redis on</var>：起動時スクリプトに登録</li>
<li><var>$ sudo chkconfig --list redis</var>：ランレベルを確認</li>
</ul>

<pre name="code" class="brush: bash">
redis           0:off   1:off   2:on    3:on    4:on    5:on    6:off
</pre>
]]>
    </content>
</entry>

<entry>
    <title>Tweet and order Amazon - Amazon.co.jp上でツイートできるGreasemonkeyを@Anywhereでつくってみた</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2010/04/greasemonkey-tweet-and-order-amazon.html" />
    <id>tag:blog.fulltext-search.biz,2010://1.75</id>

    <published>2010-04-18T03:00:00Z</published>
    <updated>2010-04-21T14:20:47Z</updated>

    <summary>Tweet and order Amazon - Amazon.co.jp上でツイートできるGreasemonkeyを@Anywhereでつくってみた</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="anywhere" label="anywhere" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="twitter" label="twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2010y04m18d_114112765.jpg"><img alt="2010y04m18d_114112765.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2010/04/2010y04m18d_114112765-thumb-400x211-70.jpg" width="400" height="211" class="mt-image-none" style="" /></a></span></p>

<p>Amazon.co.jp上で簡単にTwitterへツイートできるGreasemonkeyスクリプトを書いてみました。
今回は、最近公開された<a href="http://dev.twitter.com/anywhere">Twitter @anywhere</a>をGreasemonkeyスクリプトから使ってみる習作も兼ねてます。</p>

<p>下記の機能があります。</p>

<ul>
<li><a href="http://www.amazon.co.jp">Amazon.co.jp</a>の商品ページ上に<a href="http://twitter.com">Twitter</a>へ直接ツイートできるBoxを設置</li>
<li>商品名とリンクをツイート内に挿入</li>
<li>商品ページへのリンクへはアソシエイトIDを設定可能（デフォルトでは私のIDが設定されています）</li>
<li>Tweet and <em>order</em> Amazonという名前ですが、ツイートしても同時に購入するという機能は<strong>ありません</strong></li>
</ul>

<h3>インストール</h3>

<p>Greasemonkeyインストール済みのFirefoxで、下記リンクからインストールしてください。</p>

<p><strong><a href="http://github.com/noriaki/tweet_and_order_amazon/raw/master/tweet_and_order_amazon.user.js" title="Tweet and order Amazon(tweet_and_order_amazon.user.js"><img src="http://a3.twimg.com/client_application_images/46013/oauth_application.png" alt="Tweet and order Amazon app logo" width="48" height="48" style="width: 48px; height: 48px;" />Tweet and order Amazon(tweet_and_order_amazon.user.jsをインストール</a></strong></p>

<p>以下、詳細な使い方があります。</p>
]]>
        <![CDATA[<h3>使い方</h3>

<h4>Amazon.co.jpにアクセス</h4>

<p>インストール後、<a href="http://www.amazon.co.jp/">Amazon.co.jp</a>の商品ページにアクセスすると、商品名の上にツイート用のBoxが出てきます。</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2010y04m18d_115249484.jpg"><img alt="2010y04m18d_115249484.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2010/04/2010y04m18d_115249484-thumb-400x155-72.jpg" width="400" height="155" class="mt-image-none" style="" /></a></span></p>

<h4>ツイート</h4>

<p>Box内に好きなメッセージを追加してツイートできます。
このとき、最初に使用するときはtwitterの認証ページがポップアップ（または別タブ）に出てきますので「Connect」をクリックしてください。</p>

<h4>アソシエイトIDの設定</h4>

<p>右上のsettingsをクリックすると、商品ページへのリンクURLに含まれるAmazonアソシエイトIDを設定することができます。</p>

<h3>更新履歴</h3>

<dl>
<dt>0.1.1 (2010/04/21 23:00)</dt>
<dd><ul>
<li>アソシエイトIDを変更した後のツイートに失敗することがある不具合を修正</li>
</ul>
</dd>
<dt>0.1.0 (2010/04/18 11:00)</dt>
<dd>Initial Release!</dd>
<dd>
<ul>
<li>Amazon.co.jp上でtwitterへツイート出来る機能</li>
<li>商品へのリンクに独自のアソシエイトIDを設定可能</li>
</ul>
</dd>
</dl>
]]>
    </content>
</entry>

<entry>
    <title>Support tweeting - Twitterがなかなか機能追加してくれないので、RT(ReTweet)機能をGreasemonkeyスクリプトでつけてみた</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/11/added-to-retweet-greasemonkey-support-tweeting.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.74</id>

    <published>2009-10-31T18:00:00Z</published>
    <updated>2009-10-31T18:15:38Z</updated>

    <summary>Greasemonkeyスクリプト：Support tweetingにRT(ReTweet)機能を追加しました。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="twitter" label="twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2009y11m01d_024922970.jpg"><img alt="2009y11m01d_024922970.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/11/2009y11m01d_024922970-thumb-400x188-68.jpg" width="400" height="188" class="mt-image-none" style="" /></a></span></p>

<p><a href="http://twitter.com/">Twitter</a>がなかなか機能追加してくれないので、RT(ReTweet)機能を<a href="http://blog.fulltext-search.biz/archives/2009/10/greasemonkey-support-tweeting-on-twitter.html">拙作のGreasemonkeyスクリプト(Support tweeting)</a>で使えるようにしました。</p>

<p><a href="http://blog.fulltext-search.biz/archives/2009/10/greasemonkey-support-tweeting-on-twitter.html">Support tweeting - TwitterのWebページをちょっと使いやすくするGreasemonkeyスクリプト</a></p>

<p><a href="http://www.itmedia.co.jp/news/articles/0908/17/news028.html">本家の実装（予定）</a>を待てない方はどうぞ。</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Support tweeting - TwitterのWebページをちょっと使いやすくするGreasemonkeyスクリプト</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/10/greasemonkey-support-tweeting-on-twitter.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.73</id>

    <published>2009-10-25T06:00:00Z</published>
    <updated>2009-11-11T16:43:00Z</updated>

    <summary>TwitterのWebページをちょっと使いやすくするGreasemonkeyスクリプトを書いてみました。
リプライ(@)やDM(D)時にfriend名を自動補完できます。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="twitter" label="twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2009y10m24d_221134494.jpg"><img alt="2009y10m24d_221134494.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/10/2009y10m24d_221134494-thumb-400x170-64.jpg" width="400" height="170" class="mt-image-none" style="" /></a></span></p>

<p>TwitterのWebページをちょっと使いやすくするGreasemonkeyスクリプトを書いてみました。</p>

<p>下記の機能があります。</p>

<ul>
<li>リプライ(@)時にfriend名を自動補完</li>
<li>DM(D)時にfriend名を自動補完</li>
<li>ReTweet(RT)用リンクをtimelineの各ｔweetに追加（2009/11/01）</li>
</ul>

<p>まだまだ機能は少ないですが、ハッシュタグの管理とかいろいろプチ便利になりそうな機能を追加していこうと思います。追加される機能は自動でアップデートされていきますのでお楽しみにお待ちください。</p>

<h3>インストール</h3>

<p>Greasemonkeyインストール済みのFirefoxで、下記リンクからインストールしてください。</p>

<p><strong><a href="http://blog.fulltext-search.biz/files/twitter_support_tweeting.user.js">Support tweeting(twitter_support_tweeting.user.js)をインストール</a></strong></p>

<p>以下、詳細な使い方があります。</p>
]]>
        <![CDATA[<h3>使い方</h3>

<ul>
<li>インストール後、<a href="http://twitter.com/">twitter</a>にアクセスすると、Following listの読み込みがスタートします。完了するまで少しお待ちください。（Following数の多い人はちょっと時間がかかるかもしれません）</li>
</ul>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2009y10m25d_145002306.jpg"><img alt="2009y10m25d_145002306.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/10/2009y10m25d_145002306-thumb-400x170-66.jpg" width="400" height="170" class="mt-image-none" style="" /></a></span></p>

<ul>
<li>読み込みが完了すると、tweetの入力欄で自動補完機能が使えるようになります。（Following listは週1回最新のものに更新されます）</li>
</ul>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2009y10m24d_221134494.jpg"><img alt="2009y10m24d_221134494.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/10/2009y10m24d_221134494-thumb-400x170-64.jpg" width="400" height="170" class="mt-image-none" style="" /></a></span></p>

<ul>
<li>timelineの各tweetの右端にReTweetリンクが追加されます。クリックすると、StatusエリアにそのtweetをReTweetするテキストが挿入されます。</li>
</ul>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2009y11m01d_024922970.jpg"><img alt="2009y11m01d_024922970.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/11/2009y11m01d_024922970-thumb-400x188-68.jpg" width="400" height="188" class="mt-image-none" style="" /></a></span></p>

<h3>更新履歴</h3>

<dl>
<dt>0.1.5 (2009/11/12 01:40)</dt>
<dd>
<ul>
<li>twitterのページ追加(pagenation)の変更に対応</li>
</ul>
</dd>
<dt>0.1.4 (2009/11/08 16:45)</dt>
<dd>
<ul>
<li>friend名補完のリストを更新した際、同じ名前が重複して登録されてしまう不具合を修正</li>
</ul>
</dd>
<dt>0.1.3 (2009/11/03 17:30)</dt>
<dd>
<ul>
<li>ReTweetボタンを、twitterのページ追加(pagenation)と<a href="http://wescript.net/scripts/19">AutoPagerize</a>に対応</li>
</ul>
</dd>
<dt>0.1.2 (2009/11/01 14:30)</dt>
<dd>
<ul>
<li>ReTweet後、Statusエリアの先頭にフォーカスを移すように変更</li>
</ul>
</dd>
<dt>0.1.1 (2009/11/01 03:00)</dt>
<dd>
<ul>
<li>ReTweet機能を追加</li>
</ul>
</dd>
<dt>0.1.0 (2009/10/25 12:00)</dt>
<dd>Initial Release!</dd>
<dd>
<ul>
<li>リプライ(@)時にfriend名を自動補完</li>
<li>DM(D)時にfriend名を自動補完</li>
</ul>
</dd>
</dl>
]]>
    </content>
</entry>

<entry>
    <title>Greasemonkeyだけで実現する閲覧履歴の全文検索（まだ試作）</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/10/greasemonkey-search-on-the-history.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.72</id>

    <published>2009-10-12T17:00:00Z</published>
    <updated>2009-10-12T17:47:46Z</updated>

    <summary>まだまだ実用できるレベルではないですが、Greasemonkeyだけで実現する閲覧履歴の全文検索を作ってみました。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/ec834b7e7924147ed5b0e0b04eeca412.png"><img alt="ec834b7e7924147ed5b0e0b04eeca412.png" src="http://blog.fulltext-search.biz/archives/assets_c/2009/10/ec834b7e7924147ed5b0e0b04eeca412-thumb-400x386-62.png" width="400" height="386" class="mt-image-none" style="" /></a></span></p>

<p>まぁ、ブラウザの機能として付いてるかもしれないですが、試作・習作ということで作ってみました。
もちろんインストールが可能ですが、閲覧ページのキーワードインデックスを作るため、体感で分かるくらいFirefoxの動作が遅くなります。ご注意ください。</p>

<p><strong><a href="http://blog.fulltext-search.biz/files/search_on_the_history.user.js">Search on the History(SorH) - search_on_the_history.user.js</a></strong></p>

<h3>機能</h3>

<ul>
<li>about:blankページで履歴検索ができます</li>
<li>http://から始まるページだけ検索可能です</li>
</ul>

<h3>Greasemonkeyスクリプト中でやってること</h3>

<p>ページを閲覧すると、内蔵する<a href="http://hatena.g.hatena.ne.jp/hatenabookmark/20091007/1254885271">はてなの公開した本文抽出Javascriptライブラリ</a>を利用してページの本文を抽出します。</p>

<p><a href="http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html">Yahoo! JAPANの日本語形態素解析API</a>に本文を投げ、名詞だけを抽出します。</p>

<p>ページのURLをMD5でハッシュ化した値をキーに、タイトルや本文をGM_setValueで保存します。
併せて、上記形態素解析されたキーワードもMD5ハッシュ値をキーに、出現するページへのポインタやキーワードの出現回数と併せてGM_setValueで保存します。
この2つのキー・バリュー型のDBが検索用インデックスになります。</p>

<p>ちなみに、Greasemonkeyスクリプトから使える<a href="http://blog.fulltext-search.biz/files/gm/gm-config-helper.js">GM_setValueとGM_getValueをキー・バリュー型DBとして使いやすくするライブラリ</a>を自作して使ってます。</p>

<p><a href="about:blank">about:blank</a>ページでは、簡単なフォームを用意して、履歴検索のためのキーワード入力を受け付けます。</p>

<p>入力されたキーワードを先ほどの検索用インデックスに問い合わせ、得られたページのリストをスコア順にソートして表示します。</p>

<p>このときのページスコアは、キーワードDBとページDBを元に<a href="http://ja.wikipedia.org/wiki/Tf-idf">tf-idf</a>（文書内のキーワード種類数で正規化）を用いて計算しています。tf-idfはスクリプトの191行目くらいです。</p>

<h3>まとめ</h3>

<p>とりあえず、公開されているいろんなライブラリやWebAPIを利用すると、Greasemonkeyスクリプト(Javascript)だけでもおれおれ検索エンジンが作れてしまいました。</p>

<p>ただ、Gathering（ページをインデックス化する）時にブラウザが固まるほど処理が重たくなってしまっているので、パフォーマンスを改善することが次に必要かと思ってます。</p>

<p>また、Searching（検索）時も今は数十～数百ページからの検索なので比較的高速ですが、保持するページ数が増えたときにもパフォーマンスが悪化しそうな気がしています。</p>

<h3>最後に</h3>

<p>まとめの後になりましたが、このGreasemonkeyスクリプトでは下記のライブラリやWebAPIを利用させていただいています。本当にありがとうございます。</p>

<ul>
<li><a href="http://hatena.g.hatena.ne.jp/hatenabookmark/20091007/1254885271">はてな：ページ本文抽出Javascriptライブラリ</a></li>
<li><a href="http://www.onicos.com/staff/iz/amuse/javascript/expert/">MD5値計算Javascriptライブラリ</a></li>
<li><a href="http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html">Yahoo! JAPAN：日本語形態素解析API</a></li>
</ul>
]]>
        

    </content>
</entry>

<entry>
    <title>androidケータイ(HT-03A)のアクセス元IPとUA</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/07/android-mobile-ht-03a-ip-ua.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.66</id>

    <published>2009-07-18T15:20:00Z</published>
    <updated>2010-04-24T12:36:05Z</updated>

    <summary>AndroidケータイのHT03-AのブラウザUser-Agentとクセス元IPアドレスを調べました。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="android" label="android" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mobile" label="mobile" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/ht03a.jpg"><img alt="ht03a.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/07/ht03a-thumb-400x186-54.jpg" width="400" height="186" class="mt-image-none" style="" /></a></span></p>

<p><a href="http://blog.fulltext-search.biz/archives/2009/07/ht-03a.html">購入したAndroidケータイのHT03-A</a>のブラウザでサイトにアクセスしたときのアクセス元IPアドレスとUser-Agentを調べてみました。</p>

<pre name="code" class="brush: js; gutter: false">
110.163.147.98 - - [19/Jul/2009:00:00:35 +0900] "GET / HTTP/1.1" 200 47888 "-" "Mozilla/5.0 (Linux; U; Android 1.5; ja-jp; HT-03A Build/CDB72) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1"
</pre>

<p>ApacheのAccessログそのままですが、IPアドレスが<var>110.163.147.98</var>で、UAが<var>Mozilla/5.0 (Linux; U; Android 1.5; ja-jp; HT-03A Build/CDB72) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1</var>となっているようです。</p>

<p>ほかにもあるのかな？ご存じの方がいたら教えてください。</p>
]]>
        

    </content>
</entry>

<entry>
    <title>HT-03Aを購入したよ！</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/07/ht-03a.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.64</id>

    <published>2009-07-11T11:42:13Z</published>
    <updated>2009-07-11T11:51:28Z</updated>

    <summary>AndroidケータイのHT-03Aを購入しました。
ちょっと触ってみたけど、GMailは使いやすいし、Simejiというアプリを入れると文字入力もいい感じです。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="android" label="android" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mobile" label="mobile" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/200907111908000.jpg"><img alt="200907111908000.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/07/200907111908000-thumb-400x533-40.jpg" width="400" height="533" class="mt-image-none" style="" /></a></span></p>

<p>家の近くのドコモショップに行って、AndroidケータイのHT-03Aを購入しました！</p>

<p>メインで使ってるケータイもdocomoでN-02Aなのですが、HT-03Aはネットとかアプリとかのために2台目ということで。お店に在庫も白・黒両方あって、新規契約扱いになるのでいろいろとキャンペーンが適用されて思ったほど高くなかったです。</p>

<p>とりあえず、ちょっとだけ触ってみましたが感触として使いやすいです。GMailアプリなんてPCと同じくらいの使い勝手かも。文字入力もタッチパネルということで心配でしたが、Simejiという入力（キーボード）アプリを入れると思った以上に使いやすい。</p>

<p>いろいろアプリとかインストールしてみて楽しんでみます。</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Heat the Nicovideo Up-0.4.0（新プレーヤー対応）公開</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/06/release-heat-the-nicovideo-up-0-4-0.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.58</id>

    <published>2009-06-07T16:00:00Z</published>
    <updated>2009-06-07T16:13:54Z</updated>

    <summary>ニコニコ動画のコメント熱狂度を可視化するGreasemonkeyスクリプト(Heat the Nicovideo Up)の最新版を公開しました。最新バージョンは0.4.0で、ニコニコ動画（ββ）の新プレーヤーに対応です。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="nicovideo" label="nicovideo" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2009y06m07d_201655265.jpg"><img alt="2009y06m07d_201655265.jpg" src="http://blog.fulltext-search.biz/archives/assets_c/2009/06/2009y06m07d_201655265-thumb-400x122-30.jpg" width="400" height="122" class="mt-image-none" style="" /></a></span></p>

<p><a href="http://blog.fulltext-search.biz/pages/visualize-comments-upsurge-greasemonkey-script-for-nicovideo" title="ニコニコ動画のコメント熱狂度を可視化するGreasemonkeyスクリプト">Heat the Nicovideo Up</a>の最新版を公開しました。バージョンは0.4.0です。</p>

<p>お待たせしました。ニコニコ動画（ββ）の新プレーヤーに対応です。</p>

<p>すでにインストール済みの方は自動的に更新通知が出ますので、その案内にしたがってアップデートしてください。
（1日待っても自動更新されない場合や、対応が遅いからアンインストールしちゃったよという方は、お手数ですが再インストールをお願いします）</p>

<p>今までのHeat the Nicovideo Upは、旧Flashプレーヤーの内部変数を利用しており、新Flashプレーヤーではそれらの値を利用することができなかったため対応に時間がかかってしまいました。
最新版では、動画情報取得APIとコメント一覧取得APIを内部から呼び出し計算することで、コメントの多い時間帯をヒートマップで表示しています。</p>

<p>インストールや更新履歴などは以下のページからどうぞ。
（うまくインストールできない場合は、[ツール]→[プライバシー情報の消去]からブラウザキャッシュを削除した後、再度お試しください）</p>

<p><strong><a href="http://blog.fulltext-search.biz/pages/visualize-comments-upsurge-greasemonkey-script-for-nicovideo" title="ニコニコ動画のコメント熱狂度を可視化するGreasemonkeyスクリプト">ニコニコ動画のコメント熱狂度を可視化するGreasemonkeyスクリプト</a></strong></p>
]]>
        

    </content>
</entry>

<entry>
    <title>タイムラインをメニューに使ったサイト</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/06/post.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.57</id>

    <published>2009-06-04T23:20:00Z</published>
    <updated>2009-06-04T23:24:53Z</updated>

    <summary>Flashムービーでサイトを構成し、タイムラインをメニューっぽく使っているサイトを紹介しています</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<blockquote>
  <p>タイムラインをメニューに使う、という発想が新しいですね。
  <site><a href="http://www.ideaxidea.com/archives/2009/06/booneoakley.html">この発想はなかったわ・・・企業サイトがYouTubeの映像だけで出来ている『BooneOakley』</a></site></p>
</blockquote>

<p>全編をYoutubeという発想は確かになかったですが、タイムラインをメニューっぽく使っているサイトは以前からあるようです。日本でも。</p>

<p><a href="http://www.satoryoko.jp/">作家・佐藤遼子</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>SEO効果の高いURLをRailsのRoutingだけを使ってつくる</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2009/05/rails-routing-tips.html" />
    <id>tag:blog.fulltext-search.biz,2009://1.56</id>

    <published>2009-05-30T06:20:00Z</published>
    <updated>2010-04-24T12:38:20Z</updated>

    <summary>検索エンジンに親和性が高いURLとして&quot;/&quot;（スラッシュ）ではなく&quot;-&quot;（ハイフン）で区切るURLを、Apacheのmod_rewriteなどを使わずRuby on RailsのRouting機能だけを使って実現する方法を解説しています。</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="rails" label="rails" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p>検索エンジンに親和性が高いURLとして"/"（スラッシュ）ではなく"-"（ハイフン）で区切るURLがあるそうです。</p>

<p>例えば、</p>

<ul>
<li>「http://example.com/sample/target/12.html」</li>
</ul>

<p>ではなく</p>

<ul>
<li>「http://example.com/sample-taget-12.html」</li>
</ul>

<p>の方が検索エンジンに好まれるのだそうです。</p>

<p>そこで、今回は普通のRailsアプリを"/"（スラッシュ）ではなく"-"（ハイフン）で区切る形式のURLに対応させる方法をご紹介します。</p>

<p>ちなみに、Rails-2.2.2で試しました。</p>
]]>
        <![CDATA[<h2>今までは？</h2>

<p>Railsのデフォルトのroute.rb内で定義されているルーティングでは、controllerやaction、パラメータの区切りが"/"（スラッシュ）だったので、</p>

<ol>
<li>Apacheのmod_rewriteで"-"（ハイフン）を"/"（スラッシュ）に置換</li>
<li>Railsでは普通の<var>route.rb</var>でルーティング</li>
<li><var>link_to</var>によるリンク作成時にhelperで<var>url_for</var>を上書きして、URLの"/"（スラッシュ）を"-"（ハイフン）に置換</li>
</ol>

<p>とか、すごい大変なことをしていました。なぜなら、RailsのRoutingがカオスと言われていたためさわるのが恐かったのです。</p>

<h2>Railsのルーティングで同じことを実現</h2>

<p>Railsではコントローラとアクションなどの区切り文字を指定できます。</p>

<pre class="brush: rails">
ActionController::Routing::SEPARATORS
</pre>

<p><sample>script/console</sample>で入力すると、現在設定されている区切り文字が確認できます。</p>

<pre class="brush: rails">
% ruby script/console
>> ActionController::Routing::SEPARATORS
=> ["/", ".", "?"]
</pre>

<p>この区切り文字が<var>route.rb</var>のURLルールを書く部分で利用できるので、下記の1行を各環境のconfigファイル(<sample>config/environment/*.rb</sample>)に追加するか、適当な名前で<sample>config/initializers/</sample>の中にファイルを作ってそこに書きます。</p>

<p>私の場合は、開発でも本番でも利用したかったので、<sample>add_routing_separator.rb</sample>というファイルを作ってそこに書きました。</p>

<h3>config/initializers/add_routing_separator.rb</h3>

<pre class="brush: rails">
ActionController::Routing::SEPARATORS << "-"
</pre>

<h3>config/route.rb</h3>

<p>最後に、ルーティングを定義するおなじみ<var>route.rb</var>で追加した区切り文字を使って下記のように変更します。</p>

<pre class="brush: rails">
diff --git a/config/routes.rb b/config/routes.rb
index 8ca53fc..695ea5d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -43,9 +43,15 @@ ActionController::Routing::Routes.draw do |map|
   # Note: These default routes make all actions in every controller accessible
via GET requests. You should
   # consider removing the them or commenting them out if you're using named rou
tes and resources.

-  map.connect ':controller/:action/:id'
-  map.connect ':controller/:action/:id.:format'
+  map.connect ':controller-:action-:id'
+  map.connect ':controller-:action-:id.:format'
 end
</pre>

<p>"/"（スラッシュ）を"-"（ハイフン）に置き換えているだけですね。
これで、link_toやurl_for等でもなにも気にせずいつものとおりに書いているだけで、URLがスラッシュ区切りからハイフン区切りになります。
もちろん、デフォルトのルーティングだけでなく、独自の名前付きルーティングやその他のものでも"-"（ハイフン）を区切り文字として利用できるようになります。</p>

<p>よかったら試してみてくださいね。</p>

<p>SEO効果があるかどうかはうわさなのであしからずー</p>
]]>
    </content>
</entry>

<entry>
    <title>映画のエンドロール(Credit Title)をjQueryで再現してみた</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2008/09/jquery-credit-title-plugin.html" />
    <id>tag:blog.fulltext-search.biz,2008://1.52</id>

    <published>2008-09-28T19:30:00Z</published>
    <updated>2009-03-10T11:34:47Z</updated>

    <summary> 最近、映画を見ることにハマっているnoriakiです。そんな映画のエンドロール...</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jquery" label="jquery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2008y09m29d_042315234.jpg"><img alt="2008y09m29d_042315234.jpg" src="http://blog.fulltext-search.biz/archives/images/2008y09m29d_042315234-thumb-400x226.jpg" width="400" height="226" class="mt-image-none" style="" /></a></span></p>

<p>最近、映画を見ることにハマっている<a href="http://twitter.com/noriaki">noriaki</a>です。そんな映画のエンドロール（<a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AC%E3%82%B8%E3%83%83%E3%83%88%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB">クレジットタイトルと呼ぶそうです</a>）を見ていて、これってWebページの効果としても使えないかと思い、試しにjQuery pluginとして作ってみました。</p>

<p>デモページを用意してみましたので、よければご覧ください。</p>

<p><strong><a href="http://blog.fulltext-search.biz/jquery/credit-title.html">jQuery Credit Title - Demo</a></strong></p>

<p>「Start（End?)」ボタンをクリックするとスクリーンにエンドロールが流れます。</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Greasemonkeyスクリプトからニコニコ動画のFlashプレーヤーを操作するライブラリ（バージョンアップ）</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2008/08/nico-nico-player-wrapper-4-greasemonkey.html" />
    <id>tag:blog.fulltext-search.biz,2008://1.51</id>

    <published>2008-08-24T03:45:00Z</published>
    <updated>2010-04-24T12:40:14Z</updated>

    <summary> Greasemonkeyスクリプトから@requireで呼び出せるライブラリ第...</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="nicovideo" label="nicovideo" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2008y08m24d_124508304.jpg"><img alt="2008y08m24d_124508304.jpg" src="http://blog.fulltext-search.biz/archives/images/2008y08m24d_124508304-thumb-400x185.jpg" width="400" height="185" class="mt-image-none" style="" /></a></span></p>

<p><a href="http://coderepos.org/share/browser/lang/javascript/userscripts/GM_Libs" title="CodeRepos::Share - Trac">Greasemonkeyスクリプトから<var>@require</var>で呼び出せるライブラリ</a>第2弾。</p>

<h3>これは何？</h3>

<p>ニコニコ動画のFlashプレーヤーをGreasemonkeyスクリプトから操作するためのライブラリです。</p>

<p><var>@require</var>で読み込むだけで、以下のような各種操作が可能になります。</p>

<ul>
<li>動画情報の取得（再生時間、コメント取得用URL、フィルター情報、など）</li>
<li>動画読み込み完了後の関数実行</li>
<li>通常のFlashプレーヤーとProxomitron（オミトロン）を自動的に判別（違いを気にしないで済む）</li>
<li>再生操作（再生、一時停止、停止）</li>
<li>シーク操作</li>
<li>ボリューム調整（ミュート含む）</li>
<li>リピート ON/OFF</li>
<li>コメント表示 ON/OFF</li>
<li>全画面表示 ON/OFF</li>
</ul>
]]>
        <![CDATA[<h3>使い方（組み込み方）</h3>

<p>ライブラリの呼び出し方と、組み込まれるオブジェクト・メソッドを説明します。</p>

<h4>呼び出し方法</h4>

<p>以下の2ステップで、本ライブラリをあなたのニコニコ動画用Greasemonkeyスクリプトへを組み込むことができます。</p>

<h5>STEP1: <var>@require</var>による読み込み</h5>

<p>あなたのGreasemonkeyスクリプトの冒頭にあるメタデータ部分(// ==UserScript== 内)に以下の1行を追加します。</p>

<pre class="brush: js">// @require   http://svn.coderepos.org/share/lang/javascript/userscripts/GM_Libs/noriaki/NicoNicoPlayerWrapper/NNPW-20080824.1.js
</pre>

<h5>STEP2: <var>NicoNicoPlayer</var>オブジェクトの生成</h5>

<p>あなたのGreasemonkeyスクリプト内で<var>NicoNicoPlayer</var>オブジェクトを生成します。典型的な使い方は以下のとおりです。</p>

<pre class="brush: js">var player = new NicoNicoPlayer();
player.onReady(main);
</pre>

<p>上記の呼び出しでは、動画（Flashプレーヤー）の再生準備が整った時点で<var>main</var>関数が呼び出されます。</p>

<p>このとき、<var>main</var>関数の引数には、動画情報をオブジェクトとして渡し、<var>main</var>関数に<var>NicoNicoPlayer</var>オブジェクトをbindします。</p>

<p>同様に、無名関数を利用すると、以下のように書くことができます。</p>

<pre class="brush: js">var player = new NicoNicoPlayer();
player.onReady(function(video_info) {
  video_info.l;  // 動画の長さ（秒）
  video_info.ms; // 動画コメント取得用URL

  this.seek(40); // 動画の40秒付近へジャンプ
  this.fullscreen(true); // 全画面表示
});
</pre>

<p>サンプルのGreasemonkeyスクリプトを作りましたので、そちらも参考にしてください。</p>

<p><strong><a href="http://blog.fulltext-search.biz/files/nico_nico_player_controller_sample.user.js">nico_nico_player_controller_sample.user.js</a></strong></p>

<h4>使えるメソッド一覧</h4>

<p>基本的に各メソッドは、引数を与えて呼び出すとその値をSetし、引数を与えずに呼び出すとGetするという思想です。</p>

<dl>
<dt>onReady(<var>Function</var> callback)</dt>
<dd>引数に与えた関数を、動画の再生準備が整ってから実行する。</dd>
<dt>play()</dt>
<dd>動画の再生を開始する。</dd>
<dt>pause()</dt>
<dd>動画の再生を一時停止する。</dd>
<dt>togglePause()</dt>
<dd>再生中なら一時停止、一時停止中なら再生する。</dd>
<dt>status()</dt>
<dd>動画の再生状況を返す。以下の値のいずれかが返る。<ul>
<li>end</li>
<li>buffering</li>
<li>seeking</li>
<li>playing</li>
<li>load</li>
<li>connectionError</li>
<li>disconnected</li>
<li>stopped</li>
<li>paused</li>
</ul></dd>
<dt>val([<var>String or Object</var> key [, <var>Any</var> value]])</dt>
<dd>Flashプレーヤー内にセットされている変数を読み書きする。引数が一つの場合、その名前の引数の値を返し、引数が二つの場合、変数<var>key</var>に値<var>value</var>をセットする。<br />
引数を与えずに呼び出した場合は、利用できる変数一覧が返る。</dd>
<dt>seek([<var>Integer</var> pos])</dt>
<dd>動画のシークを操作する。引数なしの場合、呼び出されたときの再生経過時間（秒）を<var>Integer</var>で返す。引数付きで呼び出された場合、その秒数付近までジャンプする。（0未満、動画長より大きな数が与えられたときは範囲内の最も近い値が利用される）</dd>
<dt>mute([<var>Boolean</var> on])</dt>
<dd>ミュート状態をセットする。引数が<var>true</var>のときミュート。</dd>
<dt>toggleMute()</dt>
<dd>ミュートのON/OFFを切り替える。</dd>
<dt>volume([<var>Integer</var> no])</dt>
<dd>ボリュームを操作する。引数は0～100の整数で音量(%)を指定する。引数を指定せずに呼び出した場合は、現在の音量(%)を返す。</dd>
<dt>commentVisible([<var>Boolean</var> on])</dt>
<dd>コメントの表示状態をセットする。引数が<var>true</var>のときコメント表示状態。</dd>
<dt>toggleCommentVisible()</dt>
<dd>コメント表示状態のON/OFFを切り替える。</dd>
<dt>repeat([<var>Boolean</var> on])</dt>
<dd>リピートのON/OFFをセットする。引数が<var>true</var>のときリピートON</dd>
<dt>toggleRepeat()</dt>
<dd>リピートのON/OFFを切り替える。</dd>
<dt>fullscreen([<var>Boolean</var> on])</dt>
<dd>全画面表示の状態をセットする。引数が<var>true</var>のとき全画面表示。</dd>
<dt>toggleFullscreen()</dt>
<dd>全画面表示のON/OFFを切り替える。</dd>
<dt>size([<var>Float or String</var> size]) ※テスト実装</dt>
<dd>動画再生画面そのもののサイズを、<var>0.5</var>や<var>"400x300"</var>（横x縦）という形式で指定する。引数を指定せずに呼び出した場合、元の大きさに戻す。</dd>
<dt>getInfo()</dt>
<dd>動画情報を取得して返す。</dd>
</dl>

<p>ライブラリを使って、心地よいニコニコ動画用Greasemonkeyスクリプト開発を！</p>

<p>こんな機能が欲しい、ここの実装はこうした方が良い、などありましたらお気軽にコメント・トラックバック・ブックマークコメントにてお知らせください。</p>

<p>また、<a href="http://coderepos.org/share/browser/lang/javascript/userscripts/GM_Libs/noriaki/NicoNicoPlayerWrapper/NNPW-20080824.1.js">CodeRepos</a>で直接コミットしていただくのも大歓迎です。</p>
]]>
    </content>
</entry>

<entry>
    <title>Greasemonkeyスクリプトに自動更新機能をお手軽に付ける</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2008/08/update-checker-4-greasemonkey.html" />
    <id>tag:blog.fulltext-search.biz,2008://1.50</id>

    <published>2008-08-23T09:30:00Z</published>
    <updated>2010-04-24T12:39:28Z</updated>

    <summary> これはなに？ あなたの開発したGreasemonkeyスクリプト（ぐりもん）に...</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/2008y08m23d_170601562.jpg"><img alt="2008y08m23d_170601562.jpg" src="http://blog.fulltext-search.biz/archives/images/2008y08m23d_170601562-thumb-400x48.jpg" width="400" height="48" class="mt-image-none" style="" /></a></span></p>

<h3>これはなに？</h3>

<p>あなたの開発したGreasemonkeyスクリプト（ぐりもん）に、簡単に自動更新機能を付けるためのライブラリです。</p>

<p>Greasemonkey-0.8以降で使える<var>@require</var>で読み込んで、呼び出しスクリプトを記述するだけで冒頭のイメージのように自動更新機能を付けることができます。</p>

<h3>背景</h3>

<p>Greasemonkeyには、個別のスクリプトの更新を確認する手段がありませんでした。そのため、Greasemonkeyスクリプトの作者は自信のブログ等でアップデートしたことを広報して、再インストールを促すことでしか新しいものを広めることができませんでした。</p>

<p>そこで、各スクリプトが自分自身のバージョンをダウンロード元に確認しにいって、更新があれば利用ユーザに通知する機能を提供するライブラリを<a href="http://blog.fulltext-search.biz/articles/2007/10/06/upgrade-automatically-checking-for-available-updates-in-greasemonkey">作りました</a>。</p>

<p>さらに、Greasemonkey-0.8で実装された@require機能を利用して、もっと簡単に組み込むことができるように改良しています。</p>
]]>
        <![CDATA[<h3>組み込み方（使用法）</h3>

<p>以下の3ステップで、あなたが開発したGreasemonkeyスクリプトに自動更新機能を組み込むことができます。</p>

<h4>[STEP1]<var>@require</var>の追加</h4>

<p>Greasemonkeyスクリプトの冒頭にあるメタデータ部分(// ==UserScript== 内)に以下の1行を追加します。</p>

<pre class="brush: js">// @require   http://svn.coderepos.org/share/lang/javascript/userscripts/GM_Libs/noriaki/UpdateChecker/UC-20080823.js
</pre>

<p><strong>追記(2008/8/24 12:30):</strong><ins datetime="2008-08-24T12:30:00+09:00">読み込むライブラリのURIが間違っていました。現在は修正されています。</ins></p>

<p>※<var>UC-20080823.js</var>がファイル名になりますが、年月日(YYYYMMDD)の部分は、変わる可能性があります。
これは、Greasemonkeyスクリプトをアップデートしても<var>@require</var>で読み込まれたファイルは上書きされないためです。</p>

<p><strong>追記(2008-08-28T14:10:00+09:00):</strong><ins datetime="2008-08-28T14:10:00+09:00"><a href="http://blog.fulltext-search.biz/archives/2008/08/update-checker-4-greasemonkey.html#comment-802">通りすがりさんからのコメント</a>でご指摘いただいたように、CodeReposから直接読み込んだ場合では、悪意のあるスクリプトが埋め込まれてしまう可能性が無いとはいえません。<br />不安な方は、ご自身のサーバ等にコピーしてそこから読み込んだ方が安全かもしれません。</ins></p>

<h4>[STEP2]<var>@version</var>の追加</h4>

<p><var>@require</var>と同様にメタデータ部分に追加します。</p>

<pre class="brush: js">// @version   0.1.0
</pre>

<p>これはあなたのGreasemonkeyスクリプトのバージョンを表していますので、アップデート時にはカウントアップするようにしてください。</p>

<p>なお、形式は数字とドット(.)の組み合わせのみ可能です。大小関係を自動的に判別してアップデートの必要性を判断します。</p>

<h4>[STEP3]呼び出しスクリプトの追加</h4>

<p>あなたのスクリプトの最下行で以下のように呼び出します。<var>UpdateChecker</var>のコンストラクタに渡されるオプションの内容は、あなたのスクリプトの内容に合わせて書き換えてください。</p>

<pre class="js">new UpdateChecker({
    script_name: 'Your Script Name'                                 // required
    ,script_url: 'http://example.com/Path/To/YourScript.user.js'    // required
    ,current_version: '*.*.*'                                       // required
    ,more_info_url: 'http://example.com/Path/To/Update/DetailPage'  // optional
});
</pre>

<p>呼び出しオプションのそれぞれの意味は以下の通りです。</p>

<dl>
<dt>script_name</dt>
<dd>あなたのスクリプトの名前です。アップデートを促すメッセージ内に挿入されます。</dd>
<dt>script_url</dt>
<dd>あなたのスクリプトのダウンロードURLです。更新のチェックとアップデート実行時に利用されます。</dd>
<dt>current_version</dt>
<dd>現在のあなたのスクリプトのバージョンです。この値と、最新ファイルのバージョンが比較されます。</dd>
<dt>more_info_url</dt>
<dd>アップデート情報やスクリプトの説明が記述されているページのURLを指定します。必要なければ、この項目は無くてもかまいません。</dd>
</dl>

<h4>[組み込み後]あなたのスクリプトのアップデート時</h4>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.fulltext-search.biz/archives/images/update_check_image.jpg"><img alt="update_check_image.jpg" src="http://blog.fulltext-search.biz/archives/images/update_check_image-thumb-400x285.jpg" width="400" height="285" class="mt-image-none" style="" /></a></span></p>

<p>上のイメージのように利用者側ファイルの<var>current<em>version</var>と、リモートのファイル（<var>script</em>url</var>で指定した先）の<var>@version</var>を比較してアップデートの有無を自動判定しますので、あなたのGreasemonkeyスクリプトをアップデートした際には、<var>@version</var>と<var>current_version</var>をカウントアップしてください。</p>

<h3>注意点</h3>

<ul>
<li>アップデートは、再インストールすることによって行われるため、利用ユーザによる<var>@include</var>と<var>@exclude</var>の設定は初期化されてしまいます。</li>
</ul>

<h3>その他の情報</h3>

<p>ソースコードは<a href="http://coderepos.org/share/browser/lang/javascript/userscripts/GM_Libs/noriaki">CodeRepos</a>にあります。</p>

<p>また、その他のライブラリが追加されるときにもここに置かれます。</p>
]]>
    </content>
</entry>

<entry>
    <title>jQuery-1.2.6の気になるコード</title>
    <link rel="alternate" type="text/html" href="http://blog.fulltext-search.biz/archives/2008/08/jquery-126-worrisome-code.html" />
    <id>tag:blog.fulltext-search.biz,2008://1.49</id>

    <published>2008-08-09T05:40:00Z</published>
    <updated>2010-04-24T12:41:44Z</updated>

    <summary>jQuery 1.2.6が公開されから2ヶ月ほどたちましたが、使っていていくつか...</summary>
    <author>
        <name>noriaki</name>
        
    </author>
    
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jquery" label="jquery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://blog.fulltext-search.biz/">
        <![CDATA[<p>jQuery 1.2.6が公開されから2ヶ月ほどたちましたが、使っていていくつか気になった部分があるのでメモとして残しておきます。
原因とか対策とかご存じの方、教えてください。</p>

<h3>jQuery.makeArray</h3>

<p>1129-1143行目</p>

<pre class="brush: js; first-line: 1129">
  makeArray: function( array ) {
    var ret = [];

    if( array != null ){
      var i = array.length;
      //the window, strings and functions also have 'length'
      if( i == null || array.split || array.setInterval || array.call )
        ret[0] = array;
      else
        while( i )
          ret[--i] = array[i];
    }

    return ret;
  },
</pre>

<p>Arrayオブジェクトかどうかを判定するために、lengthプロパティの有無を調べているのですが、windowオブジェクトや、String、Functionにもlengthプロパティがあるということで、それぞれを判定しています。</p>

<p>その中で、「array.call」での判定が失敗することがあり、<a href="http://twitter.com/noriaki">twitter</a>でつぶやいてみると、</p>

<blockquote>
  <p>@noriaki なんか古いscriptaculousのeffect.jsだとArray.prototype.callを定義してるんだけど、関係無さげ？<a href="http://tinyurl.com/6de2mj">http://tinyurl.com/6de2mj</a></p>
  <cite><a href="http://twitter.com/monjudoh/statuses/836909894" title="Twitter / 文殊堂: @noriaki なんか古いscriptaculous...">@noriaki なんか古いscriptaculousのeffect.jsだとArray.prototype.callを定義してるんだけど、関係無さげ？http://tinyurl.com/6de2mj</a></cite>
</blockquote>

<p>という話が出てきて、まさしくその通りでした。</p>

<p>というわけで、以下のように暫定的に対応したものを独自に使ってます。</p>

<pre class="brush: js">
--- jquery-1.2.6.org.js  Sat Aug 09 15:40:15 2008
+++ jquery-1.2.6.js    Sat Aug 09 15:39:57 2008
@@ -1132,7 +1132,7 @@
     if( array != null ){
       var i = array.length;
       //the window, strings and functions also have 'length'
-      if( i == null || array.split || array.setInterval || array.call )
+      if( i == null || array.split || array.setInterval || array.apply )
         ret[0] = array;
       else
         while( i )
</pre>

<p>一応、他のところへの影響はなさそうですが、ご利用になる際は十分注意してください。</p>

<p>ってか、よく考えたら<sample>jQuery.isFunction(array)</sample>使ったらいいんじゃないのかな！(笑)</p>

<h3>jQuery.map</h3>

<p>よくつかう$.mapにも気になるコードがあります。</p>

<p>1205-1218行目</p>

<pre class="brush: js; first-line: 1205">
  map: function( elems, callback ) {
    var ret = [];

    // Go through the array, translating each of the items to their
    // new value (or values).
    for ( var i = 0, length = elems.length; i < length; i++ ) {
      var value = callback( elems[ i ], i );

      if ( value != null )
        ret[ ret.length ] = value;
    }

    return ret.concat.apply( [], ret );
  }
</pre>

<p>この最後にある、<sample>return ret.concat.apply( [], ret );</sample>はなにを意図してこうなっているんでしょうか。新しい配列にmapした結果の配列を連結して返しています。</p>

<p>でも、以下のコードを実行した場合、期待しているものとは違った結果が返ってきてしまいます。</p>

<pre class="brush: js">
$.map([1,2,3], function(value, index) {
  return [index, value];
}); //=> [1,1,2,2,3,3]
// [[1,1],[2,2],[3,3]]を期待していた
</pre>

<p>さてさて、どうしたものでしょうか。
単純に、<sample>return val;</sample>とかにしちゃっていいのかな・・</p>

<p><strong>追記(2008-08-17T14:30:00+09:00):</strong><ins datetime="2008-08-17T14:30:00+09:00">上記のように変更してみたところ、通常の<sample>$('p.myclass')</sample>といったセレクタ処理がうまくいかなくなってしまいました・・</ins></p>
]]>
        

    </content>
</entry>

</feed>
