<?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/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>lab.naoki.sato.name &#187; programming</title>
	<atom:link href="http://naoki.sato.name/lab/archives/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://naoki.sato.name/lab</link>
	<description>lab for naoki.sato</description>
	<lastBuildDate>Sun, 20 Mar 2011 06:02:24 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/category/programming/feed" />
		<item>
		<title>EvernoteのノートのタイトルをAppleScriptで一括変更する</title>
		<link>http://naoki.sato.name/lab/archives/261</link>
		<comments>http://naoki.sato.name/lab/archives/261#comments</comments>
		<pubDate>Sun, 20 Mar 2011 06:02:24 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[applescript]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[evernote]]></category>
		<category><![CDATA[webservice]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/?p=261</guid>
		<description><![CDATA[Brogtrottrというサービスがあります。
RSSの記事をメールとして送信してくれるサービスです。
個人的に、このサービスをGoogle Readerと組み合わせて利用しています。
具体的には、Google Read [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogtrottr.com/">Brogtrottr</a>というサービスがあります。<br />
RSSの記事をメールとして送信してくれるサービスです。</p>
<p>個人的に、このサービスをGoogle Readerと組み合わせて利用しています。<br />
具体的には、Google Readerで気になった記事は共有するようにして、 共有アイテムのRSSをBrogtrottrでEvernoteに送信し、気になった記事がEvernoteに自動的にクリッピングされるようにしています。</p>
<p>ただ1点、Brogtrottrが残念なのが、メールのタイトルが変更できないという点。<br />
Brogtrottrからのメールのタイトルは&#8221;サイト名: タイトル&#8221;のようになり、Google Readerの共有アイテムのようにサイト名が長いと、Evernoteに登録した際非常に冗長になってしまいます。</p>
<p>幸い、Mac版のEvernoteではAppleScriptでノートのタイトルが変更できます。</p>
<p>ということで、冗長なタイトルになっているノートを一括して変更するAppleScriptをさっくり書いたので、メモとしてあげておきます。</p>
<p>なお、AppleScript中の&#8221;switchText&#8221;は<a href="http://macscripter.net/viewtopic.php?id=13008">こちら</a>から引用させていただきました。<br />
感謝です。</p>
<p><span id="more-261"></span>※実際に使う際は、最初のpropertyの値を変更のこと。</p>
<blockquote>
<pre>property nb : "_inbox" -- ノートブック名
property str_G_orig : "naoki's shared items in Google Reader" -- 置換え対象文字列
property str_G_sub : "G" -- 置換え後文字列

tell application "Evernote"
	-- repeat with var_note in (get selection) -- 選択しているノート
	repeat with var_note in (get notes in notebook nb) -- ノートブック内の全ノート
		set var_title to (get title of var_note)
		if var_title contains str_G_orig then
			set var_title_new to (switchText from var_title to str_G_sub instead of str_G_orig) of me
			set title of var_note to var_title_new
		end if
	end repeat
end tell

to switchText from t to r instead of s
	set d to text item delimiters
	set text item delimiters to s
	set t to t's text items
	set text item delimiters to r
	tell t to set t to item 1 &amp; ({""} &amp; rest)
	set text item delimiters to d
	t
end switchText</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/261/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/261" />
	</item>
		<item>
		<title>PythonでTwitter BOTを作る</title>
		<link>http://naoki.sato.name/lab/archives/210</link>
		<comments>http://naoki.sato.name/lab/archives/210#comments</comments>
		<pubDate>Sat, 11 Sep 2010 13:18:19 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[webservice]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/?p=210</guid>
		<description><![CDATA[とあるツイートにインスパイアされて、Flickrから写真を取得してTwitterに投稿するBOTを作ってみました(ネコ、イヌ、ペンギン、ウサギ、ハムスター、赤ちゃん、とリスト)。
TwitterのBOTくらいなら簡単に作 [...]]]></description>
			<content:encoded><![CDATA[<p>とあるツイートにインスパイアされて、<a href="http://flickr.com/">Flickr</a>から写真を取得してTwitterに投稿するBOTを作ってみました(<a href="http://twitter.com/nyancopot">ネコ</a>、<a href="http://twitter.com/wancopot">イヌ</a>、<a href="http://twitter.com/penpenpot">ペンギン</a>、<a href="http://twitter.com/usapot">ウサギ</a>、<a href="http://twitter.com/hamupot">ハムスター</a>、<a href="http://twitter.com/baboopot">赤ちゃん</a>、と<a href="http://twitter.com/naokisatoname/pot">リスト</a>)。</p>
<p>TwitterのBOTくらいなら簡単に作成できる…と思っていたのですが、先日のBASIC認証廃止で、OAuthによる認証が必須となり、簡単なBOTでも結構ややこしい手順をふむ必要が出てきました。<br />
そこで、少しでも楽をするために、今回はPythonを使って構築しています。<br />
適当なライブラリを活用することで、認証の処理がかなり容易になります。</p>
<p>以下、一連の作業と作成したソースコードの記録です。</p>
<p><span id="more-210"></span></p>
<h3>BOTアカウントの登録</h3>
<p>なにはともあれ、BOT用のアカウントを登録します。<br />
<a href="https://twitter.com/signup"> こちらのページ</a>から、通常通りアカウントを作成します。</p>
<p>後々、このアカウントに紐づいたアクセストークンが必要となります。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot01.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot01-300x206.png" title="pot01" width="300" height="206" class="alignnone size-medium wp-image-213" /></a></p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot02.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot02-300x206.png" title="pot02" width="300" height="206" class="alignnone size-medium wp-image-214" /></a></p>
<p>登録を終えたら通常通りログオンし、Bio等をセッティングします。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot03.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot03-300x206.png" title="pot03" width="300" height="206" class="alignnone size-medium wp-image-215" /></a></p>
<h3>アプリケーションの登録</h3>
<p>次に、BOT用アカウントでログインした状態で <a href="http://dev.twitter.com/">http://dev.twitter.com/</a> へアクセスします。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot11.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot11-300x235.png" title="pot11" width="300" height="235" class="alignnone size-medium wp-image-216" /></a></p>
<p>この画面から、新しく作成するBOTをアプリケーションとして登録します。<br />
右上の &#8220;<a href="http://dev.twitter.com/apps">Your apps</a>&#8221;  をクリックします。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot12.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot12-300x235.png" title="pot12" width="300" height="235" class="alignnone size-medium wp-image-217" /></a></p>
<p>既に登録しているアプリケーションの一覧が表示されます。<br />
何も登録していない場合は、登録画面へのリンクだけが表示されるはずです。</p>
<p>新しく登録する場合は、右の &#8220;<a href="http://dev.twitter.com/apps/new">Register a new app</a>&#8221; をクリックします。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot13.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot13-300x235.png" title="pot13" width="300" height="235" class="alignnone size-medium wp-image-218" /></a></p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot14.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot14-300x235.png" title="pot14" width="300" height="235" class="alignnone size-medium wp-image-219" /></a></p>
<p>基本的に、入力項目はすべて入力する必要があります。</p>
<p>BOT用アプリケーション登録の際のポイントは、<strong> &#8220;Application Type&#8221; を &#8220;Client&#8221; に変更すること</strong>と、 <strong>&#8220;Default Access type&#8221; を &#8220;Read &amp; Write&#8221; に変更する</strong>こと。<br />
ちなみに、 &#8220;Callback URL&#8221; の入力欄は、 &#8220;Application Type&#8221; を &#8220;Client&#8221; に変更すると消えます。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot15.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot15-300x235.png" title="pot15" width="300" height="235" class="alignnone size-medium wp-image-220" /></a></p>
<p>登録が完了すると、このような画面に移ります。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot16.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot16-300x235.png" title="pot16" width="300" height="235" class="alignnone size-medium wp-image-221" /></a></p>
<p>この画面で必要な情報は、 <strong>&#8220;OAuth 1.0a Settings&#8221; の &#8220;Consumer key&#8221; と &#8220;Consumer secret&#8221; の2つ</strong>。<br />
これらの情報が、このBOTを更新するためのアプリケーションである、ということを証明するのに使われるものです。<br />
これらの情報を記録します。</p>
<p>次に、画面の上に戻って &#8220;My Access Token&#8221; をクリックします。</p>
<p><a href="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot17.png"><img src="http://naoki.sato.name/lab/wp-content/uploads/2010/09/pot17-300x235.png" title="pot17" width="300" height="235" class="alignnone size-medium wp-image-222" /></a></p>
<p>すると、このように <strong>&#8220;Access Token (oauth_token)&#8221; と &#8220;Access Token Secret (oauth_token_secret)&#8221;</strong> の情報が表示されます。<br />
これは、このアプリケーションの作成者(=BOTアカウント)の認証に使われる情報です。</p>
<p>先の &#8220;Consumer key&#8221; 、 &#8220;Consumer secret&#8221; とあわせて、初めてBOTを更新するためのアプリケーションで、BOTアカウントのツイートを更新できるようになります。<br />
&#8220;Access Token (oauth_token)&#8221; と &#8220;Access Token Secret (oauth_token_secret)&#8221; の情報も記録しておきます。</p>
<p><strong>これで、BOTに必要な &#8220;Consumer key&#8221;、 &#8220;Consumer secret&#8221;、&#8221;Access Token (oauth_token)&#8221;、 &#8221;Access Token Secret (oauth_token_secret)&#8221; という4つの鍵が手に入りました。</strong></p>
<h3>スクリプトの作成</h3>
<p>上述のように、今回BOTを更新するアプリケーションは、Pythonによるスクリプトを作成しました。</p>
<p>PythonでのTwitterの操作は <a href="http://code.google.com/p/tweepy/">tweepy</a> というライブラリを利用しています。<br />
また、Flickrからの写真の取得は、<a href="http://www.degraeve.com/flickr-rss/">Flickrのタグをキーに写真を検索してRSSを作成してくれる Flickr RSS Feed Generator</a> というサービスを利用し、この結果取得したRSSを <a href="http://code.google.com/p/feedparser/">feedparser</a> というライブラリを使ってパースしています。<br />
更に、 今回はFlickrの写真をツイートするということで、 <a href="http://stuvel.eu/flickrapi/documentation/">flickrapi.shorturl</a> というライブラリでURLを短縮しています。</p>
<p>各ライブラリのインストールは環境により異なるので、他を参照いただきたいのですが、このBlogを置いている<a href="http://www.coreserver.jp/">Coreserver</a>やXREAの場合は基本的に次のような手順でインストールできると思います。</p>
<ol>
<li>管理画面からホスト情報を登録する。</li>
<li>SSHでサーバへアクセスする。</li>
<li>次の環境変数を設定しておく。</li>
<pre>$ export PYTHONPATH=$HOME/lib/python2.4:$HOME/lib/python2.4/site-packages</pre>
<li> 各ソースコードをダウンロードし、以下のコマンドでインストール先を指定してインストールする。</li>
<pre>$ python setup.py install --prefix=~/</pre>
</ol>
<p>次に、実際にBOTを更新するスクリプトのソースコードです。ここで、&#8221;Consumer key&#8221;, &#8220;Consumer secret&#8221;, &#8220;Access Token (oauth_token)&#8221;, &#8221;Access Token Secret (oauth_token_secret)&#8221;にはそれぞれ植えで入手した情報を入れて下さい。</p>
<blockquote>
<pre>#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import string
import random

import feedparser
import tweepy
import flickrapi.shorturl

CONSUMER_KEY        = 'Consumer key'
CONSUMER_SECRET     = 'Consumer secret'
ACCESS_TOKEN        = 'Access Token (oauth_token)'
ACCESS_TOKEN_SECRET = 'Access Token Secret (oauth_token_secret)'

num = 100    # 100枚の写真から1枚選ぶ
tag = 'cat+kitty+kitten'    # 検索するタグを + で繋げる
id = random.randint(0, num)
if random.randrange(0, 10, 1) &gt; 5:
  sort = 'interestingness-desc'
else:
  sort = 'date-posted-desc'

url  = 'http://www.degraeve.com/flickr-rss/rss.php?tags=' + tag + '&amp;tagmode=any&amp;sort=' + sort + '&amp;num=' + str(num)
data = feedparser.parse(url)

prefix = u'ミ^・.・^彡'
title  = data['entries'][id]['title']
link = data['entries'][id]['link']
link = flickrapi.shorturl.url(link[link.rfind(u'/')+1:])

if len(title) + len(link) + len(prefix) &gt; 110:
  title = title[0:110 - len(link) - len(prefix)] + '...'

tweet = prefix + ' ' + title + '  ' + link

# ここからTwitter
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
api = tweepy.API(auth)
api.update_status(tweet)</pre>
</blockquote>
<p>最後に、このスクリプトをcronで動かすためのshスクリプトを作成します。ここで、上のPythonスクリプトは /virtual/user/bin/nyancopot.py に保存されているものとします。</p>
<blockquote>
<pre>#!/bin/sh

export PYTHONPATH=$HOME/lib/python2.4:$HOME/lib/python2.4/site-packages
export LD_LIBRALY=$HOME/lib

/usr/local/bin/python /virtual/user/bin/nyancopot.py</pre>
</blockquote>
<p>あとは、このshスクリプトをcronに登録すれば完了です。<br />
指定された時間にBOTがつぶやきます。</p>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/210/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/210" />
	</item>
		<item>
		<title>gitとDropboxでお手軽・無料のSource Hostingを実現する</title>
		<link>http://naoki.sato.name/lab/archives/38</link>
		<comments>http://naoki.sato.name/lab/archives/38#comments</comments>
		<pubDate>Sat, 16 Jan 2010 10:17:13 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[webservice]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/?p=38</guid>
		<description><![CDATA[以前から興味があった、バージョン管理システムの一つである git を導入しました。
目的としては、もちろん開発しているソースのバージョンを管理する、というのもありますが、それ以上にHostingサービスを使って、複数台の [...]]]></description>
			<content:encoded><![CDATA[<p>以前から興味があった、バージョン管理システムの一つである git を導入しました。</p>
<p>目的としては、もちろん開発しているソースのバージョンを管理する、というのもありますが、それ以上にHostingサービスを使って、複数台のPCから最新のコードにアクセスできるようにしたい、というものがあります。</p>
<p>ただ、調べてみたところ、有名な github を含め、基本的に Hostingサービスではプライベート用途で使う場合はお金がかかる模様 (ソースコードを公開するOSSの場合は基本的に無料です)。</p>
<p>それでは、ということで、<a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">複数PC間のデータをバックグラウンドで意識せずに同期してくれる無料ストレージサービス Dropbox</a> とgitを組み合わせて、手軽にプライベート用のSource Hostingを実現することにしました。要は、リモートgitサーバを使う方法で、その宛先を<a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a>内のローカルファイルにするだけです。</p>
<p>ここではプログラミングのソースを例に上げていますが、同じやり方でバージョン管理をしたい書類なども管理できると思いますので、お試し下さい。<br />
なお、<a href="http://www.dropbox.com/help/11" target="_blank">Dropbox自体の機能として、 30日以内であればファイルを以前のバージョンに戻す機能もあります</a>。</p>
<ol>
<li><a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a> をインストールします。</li>
<li>gitをインストールします (Macの場合は MacPorts からインストールできます）。</li>
<li><a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a> フォルダにgitのリポジトリを入れるフォルダを作成します。<br />
<blockquote><p><code>cd ~/Dropbox<br />
mkdir repo</code></p></blockquote>
</li>
<li>上で作成したフォルダに <em>{プロジェクトのフォルダ名}.git</em> というフォルダを作成し、&#8221;&#8211;bare&#8221;オプションを付けてinitします。<br />
<blockquote><p><code>cd repo<br />
mkdir test.git<br />
cd test.git<br />
git --bare init</code></p></blockquote>
</li>
<li>プロジェクトが新規の場合、上で作成した<a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a>上の <em>{プロジェクトのフォルダ名}.git</em> をcloneします。<br />
<blockquote><p><code>cd ~/dev<br />
git clone ~/Dropbox/repo/test.git</code></p></blockquote>
</li>
<li>既存のソースなどを追加する場合は、一度そのプロジェクト上でadd、commitした後、<a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a>上の <em>{プロジェクトのフォルダ名}.git</em> にpushします。その後のpush、pullを楽にするためにremoteでoriginを追加しておきます。<br />
<blockquote><p><code>cd ~/dev/old_prj<br />
git init<br />
git add .<br />
git commit<br />
git push ~/Dropbox/repo/test.git master<br />
git remote add origin ~/Dropbox/repo/test.git</code></p></blockquote>
</li>
<li>あとはgithub等リモートサーバを利用するときと同様です。変更を加えてpushすれば<a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a>内のリポジトリが更新され、その内容が他のPCにも自動的に同期されて、リポジトリが最新の状態に保たれます。<br />
<blockquote><p><code>git pull<br />
...<br />
git push</code></p></blockquote>
</li>
</ol>
<p>ちなみに、<a href="https://www.dropbox.com/referrals/NTIwNjU5NTk" target="_blank">Dropbox</a>が使えるのであれば、最初からそのフォルダ内で開発するのが最も楽で確実だと思いますが、その場合、開発時に自動的に作られるファイルや一時ファイル等も同期されてしまうことになります。<br />
それを気にするかは好みの問題ですが、もし気になるような方は上記の方法で必要なファイルのリポジトリだけを同期するというやり方を試していただければと思います。</p>
<p>(参考)</p>
<ul>
<li><a href="http://progit.org/book/ja/">Pro Git &#8211; Table of Contents</a></li>
<li><a href="http://kishi-r.com/2009/07/31/mac_git/">Macにgitをインストールしてそのままgithubにも登録 : kishi-r.com</a></li>
<li><a href="http://blog.champierre.com/archives/670">せっかちな人のための git 入門 &#8211; git をインストールし、共同で開発できる環境を整えるまで : 僕は発展途上技術者</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/38/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/38" />
	</item>
		<item>
		<title>MacでTwitterのタイムラインを読み上げさせる</title>
		<link>http://naoki.sato.name/lab/archives/27</link>
		<comments>http://naoki.sato.name/lab/archives/27#comments</comments>
		<pubDate>Tue, 22 Dec 2009 10:27:04 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[aquest]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/archives/27</guid>
		<description><![CDATA[Twitterは便利で楽しいものですが、タイムライン(TL)を追うのはなかなか大変です。
TLはすべて追えなくても気にするべきではない、とはよく言われるものの、他の作業をしていてもTLが気になったり&#8230;
そこで [...]]]></description>
			<content:encoded><![CDATA[<p>Twitterは便利で楽しいものですが、タイムライン(TL)を追うのはなかなか大変です。<br />
TLはすべて追えなくても気にするべきではない、とはよく言われるものの、他の作業をしていてもTLが気になったり&#8230;</p>
<p>そこで、他の作業をしながらTLも追いかけられるように、Macで自分のTLを読み上げる仕組みを作ってみました。</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/rnxqroTJJ-I&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/rnxqroTJJ-I&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object><br />
こんな感じで読み上げられます。<br />
動画では写していませんがGrowlを準備しておけばつぶやきも表示されます。</p>
<p>以下、今回作成した仕組みの詳細です。<br />
Perlやコマンドラインは使いますが、おそらく1時間-2時間で構築できると思いますので、よろしければ試してみてください。<br />
質問、コメント等は <a href="http://twitter.com/naokisatoname" target="_blank">@naokisatoname</a> まで。</p>
<p><span id="more-27"></span></p>
<h3>利用したツール等</h3>
<ul>
<li>Mac OSX 10.6 (Leopard)</li>
<li>Xcode (MacPortsインストール用)</li>
<li><a href="http://www.macports.org/" target="_blank">MacPorts</a></li>
<li>nkf (MacPortsからインストール)</li>
<li>kakasi (MacPortsからインストール)</li>
<li>Perl 5.10 (Mac標準)</li>
<li>Net::Twitterモジュール (CPANからインストール)</li>
<li>Lingua::JA::Regular::Unicodeモジュール (CPANからインストール)</li>
<li>sayコマンド (Mac標準)、<a href="http://www.a-quest.com/aquestalk/saykana/" target="_blank">AQUEST SayKana</a></li>
<li><a href="http://growl.info/" target="_blank">Growl</a> (※必要な場合)</li>
</ul>
<h3>手順詳細</h3>
<ol>
<li>Xcodeをインストールします。</li>
<li><a href="http://www.macports.org/" target="_blank">MacPorts</a>をダウンロード、インストールし、最新情報に更新します。<br />
(※MacPortsの使い方については <a href="http://blog.asial.co.jp/371">MacPortsの基本的な使い方とコマンド</a> 等に詳しく解説されています)</li>
<li><a href="http://www.macports.org/" target="_blank">MacPorts</a>からnkf、kakasiをインストールします。<br />
<code></p>
<pre>sudo port install nkf
sudo port install kakasi</pre>
<p></code></li>
<li>CPANを利用してPerl用のモジュール Net::Twitter と Lingua::JA::Regular::Unicode をインストールします。<br />
<code></p>
<pre>sudo perl -MCPAN -e shell
install Net::Twitter
install Lingua::JA::Regular::Unicode</pre>
<p></code><br />
すこし時間がかかります。</li>
<li><a href="http://growl.info/" target="_blank">Growl</a>を利用する場合、ダウンロード、インストールします。<br />
.dmgに同梱されているgrowlnotifyをインストールします (growlnotify/growlnotify を /usr/local/bin にコピーします)。</li>
<li><a href="http://www.a-quest.com/aquestalk/saykana/" target="_blank">SayKana</a>をダウンロード、インストールします。</li>
<li>次のような内容で、任意の名前のPerlスクリプトを作成します (ここでは <code>saytwitter.pl</code> とします)。<br />
<code>USERNAME</code>をユーザ名に、<code>PASSWORD</code>をパスワードに置き換えます。<br />
<code></p>
<pre>#!/usr/bin/perl

use strict;
use utf8;
use Encode;
use Net::Twitter;
use Lingua::JA::Regular::Unicode;

my $twitter = Net::Twitter-&gt;new (
	#USERNAME → ユーザ名に置き換え
	username =&gt; "USERNAME",
	#PASSWORD → パスワードに置き換え
	password =&gt; "PASSWORD"
);

#TLを取得
my $array_ref = $twitter-&gt;friends_timeline();

foreach my $ref( @$array_ref ) {
	my $username = $ref-&gt;{'user'}{'name'};
	my $line = $ref-&gt;{'text'};

	#Growlにつぶやきを表示させる場合、コメントを外す
	#qx{ growlnotify -m \"\@$username: $line\" };

	&amp;say($username);
	&amp;say($line);
}

sub say {
	my $line = $_[0];

	print encode('utf-8', $line) . "\n";

	#全角 → 半角
	$line = alnum_z2h($line);
	#シングルクォート、ダブルクォートを削除
	$line =~ s/[\"\']//g;
	#http, httpsから始まる単語を"URL"に変換 (うまく読み上げられないので)
	$line =~ s/(http:\/\/\S+)|(https:\/\/\S+)\s/URL/ig;
	#コロンを削除
	$line =~ s/[:]/,/g;
	#@ユーザ名を単に"at"に変換  (うまく読み上げられないので)
	$line =~ s/\s*[@＠][0-9a-zA-Z]+\s*/ at /g;
	#ハッシュタグを"hash"に変換  (うまく読み上げられないので)
	$line =~ s/\s*\#\w+\s*/ hash /g;
	#各種カッコを半角(に変換
	$line =~ s/[\(\[\{\&lt;（「｛【]/(/g;
	#各種カッコを半角)に変換
	$line =~ s/[\}\]\}\&gt;）」｝】]/)/g;

	#漢字をひらがなに変換し、分かち書きにする
	my $line_mod = qx{ echo \"$line\" | nkf -e | kakasi -w | kakasi -JH -KH | nkf -w };

	#半角英数字、ひらがな、および特定の記号のみ抽出する
	my $text = "";
	for(my $i = 0; $i &lt; length($line_mod); $i++) {
		if(substr($line_mod, $i, 1) =~ m/[0-9a-zA-Z@!?().,_ \/\n]
			|[、。ー！？・…　]
			|\p{Hiragana}/) {
			$text = $text . substr($line_mod, $i, 1);
		}
	}

	if($text =~ m/(\p{Hiragana}|\p{Katakana}|\p{Han})/){    #名前、つぶやきに日本語が含まれている場合
		#漢字からひらがなへの変換で"っ"が重なる場合があるので修正
		$text =~ s/っ+/っ/ig;

		#読み方の調整
		#SayKanaの仕様書を参考に、ご自由に調整してください
		$text =~ s/at/あっと、/g;
		$text =~ s/hash/はっしゅ。/g;
		$text =~ s/ ([,.、。!?！？ー])/$1/g;
		$text =~ s/([!！])/。/g;
		$text =~ s/([?？])/？/g;
		$text =~ s/ /\//g;
		$text =~ s/[・…]/、/g;
		$text =~ s/[\(\)]/,/g;
		$text =~ s/\/は\//\/わ\//g;
		$text =~ s/は\//わ\//ig;
		#英単語・固有名詞の読み方設定
		$text =~ s/Windows/うぃんどうず/ig;
		$text =~ s/Mac/まっく/ig;
		$text =~ s/Linux/りなっくす/ig;
		$text =~ s/Twitter/ついったー/ig;
		$text =~ s/Google/ぐーぐる/ig;
		#数字の読み方設定 (例えば、"10"を「いちまる」ではなく「じゅう」と読ませるようにしている)
		$text =~ s/([0-9]+)//ig;

		#SayKanaで読み上げ
		system("echo \"$text\" | SayKana");
	} else {    #名前、つぶやきに日本語が含まれている場合
		#sayで読み上げ
		system("say \"$text\"");
	}

	#1秒待機
	sleep(1);
	return;
}</pre>
<p></code></li>
<li>作成したPerlスクリプトに実行権限を与え、任意の場所にコピーします (ここでは<code>/usr/local/bin</code>にコピーします)。<br />
<code></p>
<pre>chmod a+x saytwitter.pl
sudo cp saytwitter.pl /usr/local/bin/</pre>
<p></code><br />
このPerlスクリプトを実行すれば、自分のTLから直近20件分のつぶやきが、ユーザ名・つぶやき内容の純に読み上げられるはずです。<br />
Growlを設定している場合は同時に表示されるはずです。</li>
<li>定期的に読み上げられるように、cronに登録します。<br />
cron登録用のShellスクリプトを作成します (ここでは saytwitter とします)。<br />
<code></p>
<pre>#!/bin/sh

export PATH=/usr/local/bin:/opt/local/bin:$PATH
/usr/local/bin/saytwitter.pl</pre>
<p></code></li>
<li>作成したShellスクリプトに実行権限を与え、任意の場所にコピーします (ここでは<code>/usr/local/bin</code>にコピーします)。<br />
<code></p>
<pre>chmod a+x saytwitter
sudo cp saytwitter /usr/local/bin/</pre>
<p></code></li>
<li>作成したShellスクリプトをcronに登録します。<br />
実行のタイミングはご自分の環境に応じて調整ください (<a href="http://twitter.com/naokisatoname" target="_blank">@naokisatoname</a> の場合、5分間隔に実行しています)。<br />
<code></p>
<pre>crontab -e</pre>
<p></code><br />
<code> </code></p>
<p><code></p>
<pre>*/5 * * * *  /usr/local/bin/saytwitter</pre>
<p></code></li>
<li>以上で定期的に自分のTLが読み上げられるようになります。<br />
読み上げを停止する場合は、登録したcronのJobを削除します。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/27/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/27" />
	</item>
		<item>
		<title>PerlからTwitterを簡単に利用するNet::Twitter</title>
		<link>http://naoki.sato.name/lab/archives/24</link>
		<comments>http://naoki.sato.name/lab/archives/24#comments</comments>
		<pubDate>Thu, 17 Dec 2009 13:18:48 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/archives/24</guid>
		<description><![CDATA[TwitterはAPIが公開されているので容易にそのデータを利用することができるが、PerlからTwitterにログインしてTL等の情報を利用するにはNet::Twitterモジュールを活用すると良い。
インストールはC [...]]]></description>
			<content:encoded><![CDATA[<p>TwitterはAPIが公開されているので容易にそのデータを利用することができるが、PerlからTwitterにログインしてTL等の情報を利用するにはNet::Twitterモジュールを活用すると良い。</p>
<p>インストールはCPANから可能。</p>
<p><code>sudo perl -MCPAN -e shell<br />install Net::Twitter</code></p>
<p>Snow Leopardの環境では、比較的時間はかかったものの、正常にインストールすることができた。</p>
<p>実際にPerlで利用するには、以下の様にコーディングする。</p>
<p><code>my $twitter = Net::Twitter-&gt;new (<br />username =&gt; "username", #ユーザ名<br />password =&gt; "password" #パスワード<br />)</p>
<p>my $ref = $twitter-&gt;friends_timeline();</code></p>
<p>この様にすると、<code>$ref</code>に自分のTLの情報が格納される。<br />格納されたTLの情報から、以下の様にしてユーザの名前やつぶやきの内容を取得できる。</p>
<p><code>$ref-&gt;{'user'}{'name'}; #ユーザの名前<br />$ref-&gt;{'text'}; #つぶやきの内容</code> </p>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/24/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/24" />
	</item>
		<item>
		<title>Mac OSX 10.6 (Snow Leopard)のPerlでImage::Magickを使う</title>
		<link>http://naoki.sato.name/lab/archives/23</link>
		<comments>http://naoki.sato.name/lab/archives/23#comments</comments>
		<pubDate>Sun, 13 Dec 2009 02:16:29 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[imagemagick]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/archives/23</guid>
		<description><![CDATA[Mac OSXにはImageMagickがインストールされていない。ImageMagick自体はmac portやfinkからインストールできるが、Snow Leopard用のPerlモジュール(PerlMagick)が [...]]]></description>
			<content:encoded><![CDATA[<p>Mac OSXにはImageMagickがインストールされていない。<br />ImageMagick自体はmac portやfinkからインストールできるが、Snow Leopard用のPerlモジュール(PerlMagick)が用意されておらず、CPANからのインストールもエラーが発生する(らしい)ため、PerlでImage::Magickを使うにはソースから &#8211;with-perl オプションをつけてコンパイルする必要がある。</p>
<p>コンパイル、インストール自体は</p>
<p><code>./configure --with-perl<br />make<br />sudo make install</code></p>
<p>で可能。<br />モジュールも自動的にインストールされる。</p></p>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/23/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/23" />
	</item>
		<item>
		<title>PHPでRSSを表示させるコード</title>
		<link>http://naoki.sato.name/lab/archives/14</link>
		<comments>http://naoki.sato.name/lab/archives/14#comments</comments>
		<pubDate>Tue, 01 Dec 2009 14:38:29 +0000</pubDate>
		<dc:creator>naoki</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://naoki.sato.name/lab/archives/14</guid>
		<description><![CDATA[PHPでRSSを表示するには、&#8221;XML/RSS.php&#8221;を使うらしい。XREAでは導入済みのようだから、CoreServerでも使えるだろう。
&#60;?php

mb_internal_enco [...]]]></description>
			<content:encoded><![CDATA[<p>PHPでRSSを表示するには、&#8221;XML/RSS.php&#8221;を使うらしい。<br />XREAでは導入済みのようだから、CoreServerでも使えるだろう。</p>
<blockquote><p><code>&lt;?php</code></p>
</blockquote>
<blockquote><p><code>mb_internal_encoding('sjis');</code></p>
</blockquote>
<blockquote>
</blockquote>
<blockquote><p><code>require_once 'XML/RSS.php';</code></p>
</blockquote>
<blockquote><p><code>$rss =&amp; new XML_RSS('【RSSファイル名】');</code></p>
</blockquote>
<blockquote><p><code>$rss-&gt;parse();</code></p>
</blockquote>
<blockquote>
</blockquote>
<blockquote><p><code>echo "&lt;h1&gt;&lt;a href=¥"【URL】¥"&gt;【タイトル】&lt;/a&gt;のヘッドライン&lt;/h1&gt;¥n";</code></p>
</blockquote>
<blockquote><p><code>echo "&lt;ul&gt;¥n";</code></p>
</blockquote>
<blockquote>
</blockquote>
<blockquote><p><code>$dsp_ct = 0;</code></p>
</blockquote>
<blockquote><p><code>foreach ($rss-&gt;getItems() as $item) {</code></p>
</blockquote>
<blockquote><p><code>if (++$dsp_ct &gt; 【表示件数】) {break; }</code></p>
</blockquote>
<blockquote><p><code>echo "&lt;li&gt;&lt;a href=¥"" . $item['link'] . "¥"&gt;" . mb_convert_encoding($item['title'], 'Shift_JIS', 'utf-8') ,"&lt;/a&gt;&lt;/li&gt;¥n";</code></p>
</blockquote>
<blockquote><p><code>}</code></p>
</blockquote>
<blockquote><p><code>echo "&lt;/ul&gt;¥n";</code></p>
</blockquote>
<blockquote><p><code>?&gt;</code></p>
</blockquote>
<p>参考にしたページ : <a href="http://sb.xrea.com/showthread.php?t=12204">PHPでRSSを取得するには。。。 &#8211; XREA&amp;CORE SUPPORT BOARD</a></p>
]]></content:encoded>
			<wfw:commentRss>http://naoki.sato.name/lab/archives/14/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://naoki.sato.name/lab/archives/14" />
	</item>
	</channel>
</rss>

