<?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>ARTS NET</title>
	<atom:link href="http://www.artsnet.jp/feed" rel="self" type="application/rss+xml" />
	<link>http://www.artsnet.jp</link>
	<description>Total Web development</description>
	<lastBuildDate>Sun, 16 Jan 2011 14:54:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TwitterボットアプリとTwitterアカウントをつなぐためだけの簡単なOAuth認証</title>
		<link>http://www.artsnet.jp/archives/940</link>
		<comments>http://www.artsnet.jp/archives/940#comments</comments>
		<pubDate>Sun, 16 Jan 2011 14:51:39 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[BigTable]]></category>
		<category><![CDATA[Google App Engine for Java]]></category>
		<category><![CDATA[Low Level API]]></category>
		<category><![CDATA[Twitter4j]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=940</guid>
		<description><![CDATA[一昨年のTwitter4jとGAE/jでTwitterボット作成がだいぶ古くなってて「このソース今でも使えますか？」とメールで質問をいただきましたのでフォロー記事を書いておきます。あれからTwitter4jも結構バージョンアップされてますが最新バージョンでもビルドパス通せばとりあえずコンパイルは通りますね。基本的に一昨年から変わった点と言えばやはりBasic認証からOAuthに切り替えることだけです。]]></description>
			<content:encoded><![CDATA[<p>一昨年の<a href="http://www.artsnet.jp/archives/870" target="_blank">Twitter4jとGAE/jでTwitterボット作成</a>がだいぶ古くなってて「このソース今でも使えますか？」とメールで質問をいただきましたのでフォロー記事を書いておきます。</p>
<p>あれからTwitter4jも結構バージョンアップされてますが最新バージョンでもビルドパス通せばとりあえずコンパイルは通りますね。基本的に一昨年から変わった点と言えばやはりBasic認証からOAuthに切り替えることだけです。</p>
<p>ちなみにあの時作ったボットは今は存在してません。ついっこ的なボットにあんまり需要がないと感じたのとコミュニティとして一切成り立たなかったので停止しました。まあ非コミュな僕がコミュニティとは笑い話にもなりませんが。<br />
<span id="more-940"></span><br />
で、とりあえずOAuth対応する最低限の修正は以下の通り。</p>
<pre class="prettyprint">package daibentter;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.http.*;

import com.google.appengine.api.datastore.*;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.SortDirection;

@SuppressWarnings("serial")
public class AtsumatterServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		//各キー情報
		String consumerKey = "ここにアプリケーション登録で取得したconsumerKeyを書く";
		String consumerSecret = "ここにアプリケーション登録で取得したconsumerSecretを書く";
		String token = "ここにEclipseのコンソールで取得したtokenを書く";
		String tokenSecret = "ここにEclipseのコンソールで取得したtokenSecretを書く";

		try {

			//ここがBasic認証なのでここを書き直します。
			//Twitter twitter = new Twitter("username", "password");

			// Twitterオブジェクトを生成
			TwitterFactory factory = new TwitterFactory();
			AccessToken accessToken = new AccessToken(token, tokenSecret);
			Twitter twitter = factory.getOAuthAuthorizedInstance(consumerKey, consumerSecret, accessToken);

			//リプライを取得
			List&lt;Status&gt; replies = twitter.getMentions();

			for (Status reply : replies) {

                                //リプライしたユーザーがフォロワーなら処理する
				if(twitter.existsFriendship(reply.getUser().getScreenName(), "daibentter")) {

                                        //Low Level APIを使用
					DatastoreService service = DatastoreServiceFactory.getDatastoreService();
					Transaction transaction = service.beginTransaction();

					try {

                                                //リプライが既に投稿されたデータに存在するか検索
						Query query = new Query("Post");
						query.addFilter("postUser", FilterOperator.EQUAL, reply.getUser().getScreenName());
						query.addFilter("postText", FilterOperator.EQUAL, reply.getText());
						query.addSort("postDate", SortDirection.DESCENDING);
						PreparedQuery pq = service.prepare(query);
						FetchOptions limit = FetchOptions.Builder.withOffset(0).limit(1);
						List&lt;Entity&gt; results = pq.asList(limit);

						if(results.isEmpty()) {

                                                        //存在しなければポスト
							String postUser = "[@" + reply.getUser().getScreenName() + " #daibentter]";
							String postText = reply.getText().replaceFirst("@daibentter", "");
							twitter.updateStatus(postText + postUser);

                                                        //ポスト内容をBigTableへ登録
							Entity post = new Entity("Post");
							post.setProperty("postUser", reply.getUser().getScreenName());
							post.setProperty("postText", reply.getText());
							post.setProperty("postDate", new Date());
							service.put(transaction, post);
							transaction.commit();
						}
					} finally {
						if (transaction.isActive()) {
							transaction.rollback();
						}
					}
				}
                        }
		} catch (TwitterException e) {
			e.printStackTrace();
		}
	}
}</pre>
<p>※コード中の&#8221;daibentter&#8221;はご自分のボットアカウントに変更してください。</p>
<p>&#8220;各キー情報&#8221;と&#8221;Twitterオブジェクトを生成&#8221;のとこ以外はほぼ前回と同じです。<a href="http://twitter.com/#!/daibentter" target="_blank">@daibentter</a>で実際動いています。&#8221;Eclipseのコンソールで取得&#8221;ってなんやねんって感じですが次のサイトを参考にしました。<a href="http://www.nilab.info/zurazure2/001125.html" target="_blank">Twitter4Jを使ったTwitterのOAuth認可サンプル</a></p>
<p>OAuthって言うと一旦Twitterにリダイレクトされて「許可しますか？」的な画面でユーザーが許可するとアプリからそのユーザーの情報にアクセスできるといったイメージが強いですがこのボットの場合はそれ要らないんですよ。</p>
<p>このボットの仕様はボットをフォローしてリプライ飛ばせばボットが代わりにつぶやいてくれる仕様です。利用したいユーザーはボットをフォローすればいいだけだから。他にもリダイレクト云々なOAuthする必要のない仕様のボットってたくさんあります。あるキーワード拾ってリツィートするボットだってリダイレクト云々いらないですよね。</p>
<p>つまり&#8221;ボット作者がTwitterボットアプリとTwitterアカウントをつなぐためだけの認証&#8221;はもっと簡単で良いんですよね。<a href="http://www.nilab.info/zurazure2/001125.html" target="_blank">Twitter4Jを使ったTwitterのOAuth認可サンプル</a>のTwitterOAuthAccessTokenGetterのmainメソッドをEclipseで実行すればEclipseのコンソールとブラウザで認証作業ができます。そこで得たキーを先ほどのコードに書くと言うわけです。</p>
<p>※Twitterアプリを登録するには<a href="http://blog.mudaimemo.com/2010/03/google-app-engine-twitteroauth.html" target="_blank">TwitterボットをOAuthに対応させてみた &#8211; Google App Engine(Python)</a>など参考にしてください。また、アプリケーションの種類は必ず&#8221;クライアントアプリケーション&#8221;にしてください。</p>
<p>Twitterのトークンの有効期限は良く知らないですが僕の古い記憶だと特になかった気がします。だから最初に1回TwitterボットアプリとTwitterアカウントをつなぐためだけの簡単なお仕事をすれば良いだけです。</p>
<p>※有効期限あったらごめんなさい、その時は期限が切れたらこの作業を手動で繰り返すか期限切れは再認証処理を自動で行うコードを書いたら良いと思います）</p>
<p>Javaで標準入出力とかよくわからんけどGAE/jでWebアプリケーションなら解るから<a href="http://www.nilab.info/zurazure2/001125.html" target="_blank">Twitter4Jを使ったTwitterのOAuth認可サンプル</a>のTwitterOAuthAccessTokenGetterのmainメソッドをどう書いたらええのん？ってゆー方は以下のコードを別で書いてください。</p>
<pre class="prettyprint">package daibentter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

@SuppressWarnings("serial")
public class SignInServlet extends HttpServlet {

	@SuppressWarnings("deprecation")
	protected void doGet(HttpServletRequest req, HttpServletResponse res)
		throws ServletException, IOException {

		//各キー情報
		String consumerKey = "ここにアプリケーション登録で取得したconsumerKeyを書く";
		String consumerSecret = "ここにアプリケーション登録で取得したconsumerSecretを書く";

		try {
			// 認証用URLを取得
			TwitterFactory factory = new TwitterFactory();
			Twitter twitter = factory.getOAuthAuthorizedInstance(consumerKey, consumerSecret);
			RequestToken requestToken = twitter.getOAuthRequestToken();
			String authorizationURL = requestToken.getAuthorizationURL();

			System.out.println(authorizationURL + " にウェブブラウザでアクセスして認証を許可してください。");
			System.out.println("認証を許可したらウェブブラウザにPINコードが表示されます。");
			System.out.println("PINコードを入力して[Enter]キーを押してください。");

			// 入力待ち
			BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
			String pin = r.readLine();

			// AccessTokenオブジェクトを生成
			AccessToken accessToken;
			if(pin.length() &gt; 0){
				accessToken = twitter.getOAuthAccessToken(requestToken, pin);
			}else{
				accessToken = twitter.getOAuthAccessToken();
			}

			// 認証情報を表示
			int userId = twitter.verifyCredentials().getId();
			String token = accessToken.getToken();
			String tokenSecret = accessToken.getTokenSecret();
			System.out.println("UserId=" + userId);
			System.out.println("Token=" + token);
			System.out.println("TokenSecret=" + tokenSecret);
		} catch (TwitterException e) {
			e.printStackTrace();
		}
	}
}</pre>
<p>これでweb.xmlに以下を足せばローカルでhttp://localhost:8888/signinとやるだけで起動できます。</p>
<pre class="prettyprint">&lt;servlet&gt;
	&lt;servlet-name&gt;SignIn&lt;/servlet-name&gt;
	&lt;servlet-class&gt;anonymoustter.SignInServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
	&lt;servlet-name&gt;SignIn&lt;/servlet-name&gt;
	&lt;url-pattern&gt;/signin&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
<p>その後はあくまで&#8221;Eclipseコンソール上&#8221;で操作しますので間違えないように。ブラウザ上ではレスポンス待ってる状態っぽくグルングルン回ってますがそれはEclipseコンソール上で入力を待ってるんです。</p>
<p>あとこの認証作業はデプロイする必要ありません。アクセストークンもらったらGAE上では用無しなんでweb.xmlは元に戻してデプロイしましょう。アクセストークンもらうまではローカルで充分ってゆーことです。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/bigtable" title="BigTable" rel="tag">BigTable</a>, <a href="http://www.artsnet.jp/archives/tag/gae" title="GAE" rel="tag">GAE</a>, <a href="http://www.artsnet.jp/archives/tag/google-app-engine-for-java" title="Google App Engine for Java" rel="tag">Google App Engine for Java</a>, <a href="http://www.artsnet.jp/archives/tag/low-level-api" title="Low Level API" rel="tag">Low Level API</a>, <a href="http://www.artsnet.jp/archives/tag/oauth" title="OAuth" rel="tag">OAuth</a>, <a href="http://www.artsnet.jp/archives/tag/twitter4j" title="Twitter4j" rel="tag">Twitter4j</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/870" title="Twitter4jとGAE/jでTwitterボット作成 (2009 年 10 月 18 日)">Twitter4jとGAE/jでTwitterボット作成</a> (3)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/940/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OS X 10.5(Leopard)のPHPでZend Debugger</title>
		<link>http://www.artsnet.jp/archives/935</link>
		<comments>http://www.artsnet.jp/archives/935#comments</comments>
		<pubDate>Sun, 14 Nov 2010 15:30:34 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Leopard]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ZendDebugger]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=935</guid>
		<description><![CDATA[そういえば持ち運んでいるMacbook Air（旧式だよ！）にPHP環境がないなぁとふと気づきました。今更PHP環境が必要な場面もないので忘れようとも思ったんですが、MacでのPHP環境構築も1回くらいやっておくか！ということでやってみました]]></description>
			<content:encoded><![CDATA[<p>そういえば持ち運んでいるMacbook Air（旧式だよ！）にPHP環境がないなぁとふと気づきました。今更PHP環境が必要な場面もないので忘れようとも思ったんですが、MacでのPHP環境構築も1回くらいやっておくか！ということでやってみました。</p>
<p>なんも書くことありません。全部<a href="http://www.futomi.com/lecture/macosx/index.html">Max OS X LeopardでAMP環境を構築しよう &#8211; Apache, MySQL, PHP, Perlで作る開発環境</a>に書いてました。ここ見たらLAMP環境構築可能です。しかもネイティブ？（もともとOSXに入ってるやつだけ）で！感謝です。</p>
<p>というか他の情報はXAMPP入れたりとか別にApacheやPHPコンパイルしたりとか、そんな情報ばっかりなのはどうしてなんでしょうかね〜？今回自分はもともと入ってる環境に慣れてみることが目的だったので逃げるわけにはいかんかったんですたい！（なんのこだわりかよーわからん）<br />
<span id="more-935"></span><br />
で、最大ハマりはZend Debuggerかな？だってPydev触ってからLLと言えどデバッガ使えない開発なんてもうやってられないんですわ。でZend Debugger 入れようとしたんだけども落としたやつphp.iniのextension_dirに置いてphpinfo吐いても読み込まれていない模様。</p>
<p><a href="http://stackoverflow.com/questions/240725/php-w-zend-debugger-on-os-x-10-5">PHP w/ Zend Debugger on OS X 10.5</a> ここ見たら何やら32ビットがどーじゃーこーじゃー言ってますがよくわかりません。とりあえず書いてるとおりAppleScriptなるものを実行させるとアラ不思議！phpinfo吐かせるとちゃんとZend Debugger読み込まれてる。うっしっしっ＾皿＾</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/leopard" title="Leopard" rel="tag">Leopard</a>, <a href="http://www.artsnet.jp/archives/tag/mac" title="Mac" rel="tag">Mac</a>, <a href="http://www.artsnet.jp/archives/tag/osx" title="OSX" rel="tag">OSX</a>, <a href="http://www.artsnet.jp/archives/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.artsnet.jp/archives/tag/zenddebugger" title="ZendDebugger" rel="tag">ZendDebugger</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/923" title="さくらのVPS（CentOS5）使ってみました (2010 年 9 月 21 日)">さくらのVPS（CentOS5）使ってみました</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/72" title="PHP Simple HTML DOM Parser (2009 年 1 月 29 日)">PHP Simple HTML DOM Parser</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/95" title="Apache,PHP,MySQL,PHPMyAdmin (2009 年 2 月 1 日)">Apache,PHP,MySQL,PHPMyAdmin</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/935/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSクリーンインストール後にやること</title>
		<link>http://www.artsnet.jp/archives/928</link>
		<comments>http://www.artsnet.jp/archives/928#comments</comments>
		<pubDate>Sun, 03 Oct 2010 16:44:44 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=928</guid>
		<description><![CDATA[WindowsだろうがMacだろうがLinuxだろうがインストール後はChrome, Dropbox, Skype, VLC, Keepassしか入れません。開発環境とか除いた一般的な話ならこれで充分。メールやオフィス文書はGoogleでOK。Dropbox+Keepassでパスワード管理ちゃんとして、VLCありゃだいたいの動画見れます。もう最近は殆どないけどCD焼いたり音楽聴いたりするソフトはどんなOSだって標準で入ってますよね。]]></description>
			<content:encoded><![CDATA[<p>WindowsだろうがMacだろうがLinuxだろうがインストール後はChrome, Dropbox, Skype, VLC, Keepassしか入れません。一般的な話ならこれで充分。メールやオフィス文書はGoogleでOK。もう最近は殆どないけどCD焼いたり音楽聴いたりするソフトはどんなOSだって標準で入ってますよね。</p>
<p>仕事柄これまで飽きるほどいろんなOSをインストールしてきましたが、どんなOSを入れようが基本的にその環境は1〜2年くらいしか持ちません。ウィルスにやられたり、ハードが壊れちゃったり、買い替えたり。そんな刹那的な環境にこだわってデスクトップやテーマを変えたって再インストール後はどうせやり直すんですよ。<br />
<span id="more-928"></span><br />
メールクライアントやブラウザの設定とデータ移行（imap同期含む）の手間や時間だってバカらしい。その後に続く各アプリケーションの再インストールなんてホント時間の無駄。だからオーサリングソフトベンダーもクラウド化の速度を上げてくれないと困るんですよ。オフィス系ソフトはだいぶ進化してるのにね。</p>
<p>自分は仕事柄主流OSは常に触っておきたいので会社ではWindows XP、持ち歩くものは格好つけたいのでモバイルはMac OS X、個人的にはかなり貧乏性なので自宅ではUbuntu Linuxです。ただしそれぞれの環境はOSが異なりますが冒頭のような環境でほぼ統一されてます。今後更にクラウド化が進めばこの「超ノーマル主義」が完全なるものになることでしょう。</p>
この投稿にタグはありません。
	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li>関連する投稿はありません。</li>
	</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/928/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>さくらのVPS（CentOS5）使ってみました</title>
		<link>http://www.artsnet.jp/archives/923</link>
		<comments>http://www.artsnet.jp/archives/923#comments</comments>
		<pubDate>Mon, 20 Sep 2010 15:48:38 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[VPS]]></category>
		<category><![CDATA[さくら]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=923</guid>
		<description><![CDATA[サーバ全体っていっても自動的にサブドメインが増えていくようなサービスなだけなんで基本さくらでもLAMP環境を構築するだけです。あとはブログをその片隅にWordPressでちょこんと置いとく感じです。Apache, PHP, MySQLをyumでホイホイホイっと入れていきphpinfoあたり出してロクに内容も確認しないまま「よし動いた。順調順調」]]></description>
			<content:encoded><![CDATA[<p>とりあえず自宅サーバが今年の夏を超えられそうになかったのでさくらのVPS（CentOS5）使ってみました。うちでは個人的にサーバ全体の設定で動く小さいWebサービスを運営してるので基本的に制約の多いクラウド系サービス（force.com, GAE）は無理でEC2でやっていこうと準備してた矢先さくらのVPSが出てきたので急遽そっちにしました。なんたって安いから。</p>
<p>サーバ全体っていっても自動的にサブドメインが増えていくようなサービスなだけなんで基本さくらでもLAMP環境を構築するだけです。あとはブログをその片隅にWordPressでちょこんと置いとく感じです。Apache, PHP, MySQLをyumでホイホイホイっと入れていきphpinfo出してロクに内容も確認しないまま「よし動いた」順調順調。<br />
<span id="more-923"></span><br />
更に横着して古いサーバからhttpd.conf, php.ini, my.cnfとMySQLのデータベースをdumpしたSQLファイルをSCPでさくらに突っ込んで開始から1時間もしないで「これで動いたら新記録だな」とアクセスしてみると「お使いのサーバーの PHP では MySQL 拡張を利用できないようです」とWordPressから怒られた。あら？さっき動いてなかったっけ？</p>
<p>もう1回phpinfo良く見るとMySQLの項がない。あれ？php-mysql入れたよねってrpm -qしてもちゃんと出てくる。なんやねんってphp.iniの中見たらextension=mysql.soがない。あーこれね。今度こそっ、あれ？また変わらず・・・もういいよ、新記録は良いからじっくり見ないとダメだ。そもそも超横着してphp.ini丸コピしてんのがダメだろ。よく見ろ。</p>
<p>で、よく見るとextension=mysql.soは/etc/php.d/mysql.iniに書かれてるからやっぱphp.iniに記述はいらん。だったら尚のことなんで動かんねん。phpinfo見ると/etc/php.d/以下のファイルはちゃんと読み込まれてるっぽい。ああ、そっかextension_dirのパスがおかしいのかなって確認してみたけどextension_dir=/usr/lib/php/moduleと一見普通。でも実際そこ見に行くとモジュールどころか/usr/lib/phpディレクトリ自体ない？</p>
<p>もうよくわかんないんでPHPを再インストール。またphp.iniをコピペする（懲りないやつ）前に素のphp.iniを見てみたらなぁ〜〜んだ、extension_dir=/usr/lib64/php/moduleになってんじゃねーか。そっかVPSだもんね。64ビットなので動かしてて当然だわw・・・で、書き直したらあっさり全部動いた。これでも自己新記録。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/apache" title="Apache" rel="tag">Apache</a>, <a href="http://www.artsnet.jp/archives/tag/centos" title="CentOS" rel="tag">CentOS</a>, <a href="http://www.artsnet.jp/archives/tag/mysql" title="MySQL" rel="tag">MySQL</a>, <a href="http://www.artsnet.jp/archives/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.artsnet.jp/archives/tag/vps" title="VPS" rel="tag">VPS</a>, <a href="http://www.artsnet.jp/archives/tag/%e3%81%95%e3%81%8f%e3%82%89" title="さくら" rel="tag">さくら</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/95" title="Apache,PHP,MySQL,PHPMyAdmin (2009 年 2 月 1 日)">Apache,PHP,MySQL,PHPMyAdmin</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/233" title="VirtualHostの設定の確認方法 (2009 年 2 月 11 日)">VirtualHostの設定の確認方法</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/72" title="PHP Simple HTML DOM Parser (2009 年 1 月 29 日)">PHP Simple HTML DOM Parser</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/935" title="OS X 10.5(Leopard)のPHPでZend Debugger (2010 年 11 月 15 日)">OS X 10.5(Leopard)のPHPでZend Debugger</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/261" title="OpenSSLでcrtとcsrとkeyファイルを生成 (2009 年 2 月 14 日)">OpenSSLでcrtとcsrとkeyファイルを生成</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/619" title="mod_vhost_aliasとmod_rewriteの併用 (2009 年 3 月 16 日)">mod_vhost_aliasとmod_rewriteの併用</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/32" title="mod_vhost_aliasでサブドメイン動的生成 (2009 年 1 月 24 日)">mod_vhost_aliasでサブドメイン動的生成</a> (3)</li>
	<li><a href="http://www.artsnet.jp/archives/724" title="mod_rewriteでRewriteCond %{REQUEST_FILENAME} (2009 年 3 月 25 日)">mod_rewriteでRewriteCond %{REQUEST_FILENAME}</a> (2)</li>
	<li><a href="http://www.artsnet.jp/archives/661" title="Asteriskのインストール (2009 年 3 月 21 日)">Asteriskのインストール</a> (1)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/923/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google信者などいない</title>
		<link>http://www.artsnet.jp/archives/906</link>
		<comments>http://www.artsnet.jp/archives/906#comments</comments>
		<pubDate>Sat, 06 Feb 2010 15:19:33 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=906</guid>
		<description><![CDATA[確かに僕もGoogleが何かサービスを出す度にとりあえず使ってみますね。それはこの記事の言う通り無料だから敷居が低いというのも確かにありますが、大半はGoogleのやることの向こう側に隠れたものを妄想するのが楽しいからです]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.itmedia.co.jp/assioma/2010/02/nexus-onegoogle.html">Nexus Oneの不振から見えてくる、Googleビジネスの限界</a>を読んで。</p>
<p>確かに僕もGoogleが何かサービスを出す度にとりあえず使ってみますね。それはこの記事の言う通り無料だから敷居が低いというのもありますが、大半はGoogleのやることの向こう側に隠れたものを妄想するのが楽しいからです。</p>
<p>2005年頃、ブロガーの間でGoogleへの妄想が加熱しました。「Googleの言語やOSが出るんじゃないのか？」両方とも実際に出ましたが、この頃からGoogleのやることを深読みする人たちがどんどん増えていった記憶があります。Google Baseに対する行き過ぎた妄想なども今思えば微笑ましく思えます。</p>
<p>では、それを楽しむ人たちはGoogle信者なのだろうか？<br />
<span id="more-906"></span><br />
僕は全然違うと思います。例えば最近Googleが本当のカレンダーを配ったなんて話を聞きましたけど全く興味がありません。Google Gearsの墓標が建てられても何も悲しくはありません。多分Googleより本当に優れたサービスが現れたら何も迷うことなく乗り換えることでしょう。</p>
<p>GoogleはCoolだけど利用者もCoolです。Androidの話題が出るたびに必死にiPhoneを擁護するApple信者のようにGoogleを妄信してません。だから記事の中に出るような「Google信者」などいないと思います。「会社のパソコンがWindowsだからWindowsを使ってるだけ」というのと同じ感覚で「Googleのサービスが便利だからGoogleを使ってるだけ」なのです。</p>
<p>あとGoogleのビジネスモデルがどう変わっていくかについてですが、広告収入頼みのままが危険なことくらい解っていると思いますよ。コンシューマへの無料サービスは所詮パフォーマンスや広告の類いであって、Googleは今後エンタープライズな方向へどんどん進んでいくのは間違いないと思います。その時にGoogleがどれだけ泥臭いことができるのかは甚だ疑問ですが。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/google" title="Google" rel="tag">Google</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li>関連する投稿はありません。</li>
	</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/906/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery.UI.dialogの中身をAjaxでloadする</title>
		<link>http://www.artsnet.jp/archives/896</link>
		<comments>http://www.artsnet.jp/archives/896#comments</comments>
		<pubDate>Thu, 17 Dec 2009 03:08:08 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[dialog]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=896</guid>
		<description><![CDATA[jQuery.UI.dialogの中身をAjaxでloadしたくて$().load().dialog('open')とか色々やってみたけど思うような動作にならない。しょうがないのでググってたら$().ajaxDialog: jQuery UI – dialog をajaxでというのを見つけました。ただ使おうとしたら「このままだとloading中の表示を出せないし、画像だっけを出すようなこともできません」と書いてある。思うような動作とは正にローディングなので結局jQuery.UI.dialogのOpenイベントで実装することにしました]]></description>
			<content:encoded><![CDATA[<p>jQuery.UI.dialogの中身をAjaxでloadしたくて$().load().dialog(&#8216;open&#8217;)とか色々やってみたけど思うような動作にならない。しょうがないのでググってたら<a href="http://zudolab.net/blog/?p=121" target="_blank">$().ajaxDialog: jQuery UI – dialog をajaxで</a>というのを見つけました。ただ、使おうとしたら「このままだとloading中の表示を出せないし、画像だっけを出すようなこともできません」と書いてある。思うような動作とは正にローディングなので結局jQuery.UI.dialogのOpenイベントで実装することにしました。</p>
<p>書いたのはこんな感じ。</p>
<pre class="prettyprint">
$("#disp").dialog({
        autoOpen: false,
        buttons: {
            'close': function(){
                $(this).dialog('close');
                $("#disp").children().remove();
            }
        },
        open: function(){
            $("#disp").load($(this).dialog("option", "url"), null, function() {
                $("#loading").hide();
            });
        }
});
$(".link").click(function(){
        $("#loading").show();
        $("#disp").dialog("option", "url", "/get_page?url=" + $(this).attr('href'));
        $("#disp").dialog('open');
        return false;
});
</pre>
<p><span id="more-896"></span><br />
class=&#8221;link&#8221;なアンカー（複数ある）をクリックしたらクリックされたアンカーのhrefを取得してdialogに「url」というオプション値として登録しdialogをopenする。dialogのopenイベントで実行されるメソッドopen: function()にローディング開始とload処理を書き、更にload完了時のコールバックでローディング終了する。dialogを閉じる際のbuttons: {&#8216;close&#8217;: function()でダイアログを閉じると共に$(&#8220;#disp&#8221;)の中身をremoveする。</p>
<p>ちなみに今回は別ドメインのページをloadする要件だったので/get_page?url=&#8221; + $(this).attr(&#8216;href&#8217;)というようにサーバサイドを噛ませて取得しています。同一ドメインのページなら普通にurlを入れれば大丈夫です。このようにjQuery.UI.dialogにはopenに限らずイベントが多数用意されていますので応用すれば思い通りに動かせると思います。詳細は<a href="http://jqueryui.com/demos/dialog/" target="_blank">jQuery.UI.dialog</a>のページ下部にあるEventsをご覧ください。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/dialog" title="dialog" rel="tag">dialog</a>, <a href="http://www.artsnet.jp/archives/tag/jquery" title="jQuery" rel="tag">jQuery</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/643" title="prototype.jsでウィンドウを表現 (2009 年 3 月 19 日)">prototype.jsでウィンドウを表現</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/896/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Salesforce(force.com)とmixiアプリ(OpenSocial)連携</title>
		<link>http://www.artsnet.jp/archives/886</link>
		<comments>http://www.artsnet.jp/archives/886#comments</comments>
		<pubDate>Sun, 15 Nov 2009 16:14:40 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[force.com]]></category>
		<category><![CDATA[mixiアプリ]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=886</guid>
		<description><![CDATA[巷ではmixiアプリ(OpenSocial)をGAE(Google App Engine)にホスティングする方法が流行っているそうですが、私のほうでは日本の技術者の間ではあまり有名でないSalesforce(force.com)とmixiアプリ(OpenSocial)連携させる方法をご紹介します]]></description>
			<content:encoded><![CDATA[<p>巷ではmixiアプリ(OpenSocial)をGAE(Google App Engine)にホスティングする方法が流行っているそうですが、私のほうでは日本の技術者の間ではあまり有名でないSalesforce(force.com)とmixiアプリ(OpenSocial)連携させる方法をご紹介します。</p>
<p>Salesforce(force.com)はMicrosoftやOracleのようにエンタープライズ向け=有料（高額）というイメージがありますが、結構Googleのようなスタンスへの憧れを感じられるような部分があります。技術者向けに<a href="https://www.salesforce.com/jp/form/signup/freeforce-platform.jsp?d=70130000000Eu56&#038;internal=true" target="_blank">free force.com</a>というエディションもあり登録は必要ですが登録後はエンタープライズ系とほぼ同等の機能を試すことができます。<br />
<span id="more-886"></span><br />
さてmixiアプリ(OpenSocial)はその実体であるガジェットXMLファイルをどこかにホスティングしてmixi側に読み込んでもらわないといけないわけですが、Salesforce側でホスティングする方法としては二つ考えられます。それは静的ファイルとしてホスティングする方法とVisualforceページを作成してForce.com Sites機能を利用する方法です。</p>
<p>Salesforceにログインしていただくと解りますが上部メニューの「設定」→左メニューの「開発」→「静的リソース」で静的なファイルをアップロードできます。ここにアップロードしたファイルは任意のアドレスが振られ外部サーバからもアクセスできます。これを利用してガジェットXMLファイルをアップロードしてmixiから読み込んでもらうのがひとつ目の方法です。</p>
<p>もうひとつの方法は上部メニューの「設定」→左メニューの「開発」→「ページ」で作成できるVisualforceページを作成し上部メニューの「設定」→左メニューの「開発」→「サイト」で設定できるForce.com Sites機能を使って作成したVisualforceページを外部に公開しmixiから読み込んでもらう方法です。</p>
<p>お勧めはふたつめのVisualforceページを作成してForce.com Sites機能を利用する方法です。ガジェットXMLファイルだけで考えればどちらでも良いのですが、恐らくほとんどのSocialアプリはコンテナ側（mixiなど）の機能だけで完結することはないと思います。サーバ側と連携してXMLやJSONなどのデータ形式でデータを出し入れする必要が出てきます。</p>
<p>そういった場合にガジェットXMLファイルもデータ連携されるXMLやJSONファイルも同じVisualforceページで作成されていた方が開発も管理もしやすいと思います。もちろんガジェットXMLファイル用Visualforceページとデータ出し入れ用Visualforceページは別ページとして作成します。コンテナ側（mixiなど）と連携するデータの種類が増えれば自ずとその入り口となるVisualforceページも増えていく格好になります。</p>
<p>したがって静的リソースだけで動的なデータ連携まで行うことは不可能だということです。Salesforceでは「オブジェクト」と言われるデータベースのテーブルのようなものを中心にアプリケーションを構築するのですが、よりロジック的な動きをつけたい場合はApexと言われるSalesforce特有のJavaに似た言語を使ってApexクラスを作成し一般的に言われるビジネスロジック層やデータアクセス層の役割を担うことができます。</p>
<p>つまりオブジェクト（データ・エンティティレイヤー）をApexクラス（ビジネスロジック・データアクセスレイヤー）で扱いVisualforceページ（プレゼンテーションレイヤー）で表示部分の処理を書きForce.com Sites機能で外部に公開するわけです。そうすればガジェットXMLファイルをホスティングする役割だけでなくWebAPIのインターフェイスのような役割も担うことができます。つまりGAE(Google App Engine)等と同等の役割を担うことが可能なのです。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/force-com" title="force.com" rel="tag">force.com</a>, <a href="http://www.artsnet.jp/archives/tag/mixi%e3%82%a2%e3%83%97%e3%83%aa" title="mixiアプリ" rel="tag">mixiアプリ</a>, <a href="http://www.artsnet.jp/archives/tag/opensocial" title="OpenSocial" rel="tag">OpenSocial</a>, <a href="http://www.artsnet.jp/archives/tag/salesforce" title="Salesforce" rel="tag">Salesforce</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li>関連する投稿はありません。</li>
	</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/886/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter4jとGAE/jでTwitterボット作成</title>
		<link>http://www.artsnet.jp/archives/870</link>
		<comments>http://www.artsnet.jp/archives/870#comments</comments>
		<pubDate>Sat, 17 Oct 2009 17:32:03 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[BigTable]]></category>
		<category><![CDATA[Google App Engine for Java]]></category>
		<category><![CDATA[Low Level API]]></category>
		<category><![CDATA[Twitter4j]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=870</guid>
		<description><![CDATA[Twitter4jとGAE/j（Google App Engine for Java）でTwitterボットを作成します。事の発端は趣味のスノボーのコミュニティをTwitterで作りたくて、最初「ついっこ」で作ろうとしたんですが、どういうわけか認証が通らないとかなんかで申請が拒否られて、問い合わせても音沙汰が無いので、じゃあ同じもの自分で作りますか、ということで作ることになりました]]></description>
			<content:encoded><![CDATA[<p>※こちらはTwitterのBasic認証の記事になります。OAuthを利用した記事は<a href="http://www.artsnet.jp/archives/940">TwitterボットアプリとTwitterアカウントをつなぐためだけの簡単なOAuth認証</a>になります。</p>
<p>だいぶご無沙汰ですが、個人的なバタバタもだいぶ落ち着きましたので、またブログ更新もぼちぼちやっていきたいと思います。最近はSocialWeb、クラウド系の開発が多く、いろんな技術の連携、マッシュアップ的な開発手法が身につきました。ネタ的にもそろそろ充実してきましたので積極的にアウトプットしていきたいと思ってます。</p>
<p>今回はTwitter4jとGAE/j（Google App Engine for Java）でTwitterボットを作成します。事の発端は趣味のスノボーのコミュニティをTwitterで作りたくて、最初「ついっこ」で作ろうとしたんですが、どういうわけか認証が通らないとかなんかで申請が拒否られて、問い合わせても音沙汰が無いので、じゃあ同じもの自分で作りますか、ということで作ることになりました。<br />
<span id="more-870"></span><br />
だから仕様はついっこの真似です。以下のような仕様を実装します。</p>
<ul>
<li>フォロワーがボットにリプライすると、それと同じ内容をポストする</li>
<li>その際、発言者のユーザーIDとコミュニティのハッシュタグを付与する</li>
<li>ポストした内容は一応BigTableに永続化しておく（これはやりたかっただけ）</li>
</ul>
<p>まあ、思いつきで作るならこれくらいの仕様がちょうど良いでしょう。</p>
<p>では早速コードを紹介。ちなみにJava屋ではありません。ほぼ学習目的です。</p>
<pre class="prettyprint">
package atsumatter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.*;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.User;

import com.google.appengine.api.datastore.*;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.SortDirection;

@SuppressWarnings("serial")
public class AtsumatterServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		try {

                        //リプライを取得
			Twitter twitter = new Twitter("username", "password");
			List&lt;Status&gt; replies = twitter.getMentions();

			for (Status reply : replies) {

                                //リプライしたユーザーがフォロワーなら処理する
				if(twitter.existsFriendship(reply.getUser().getScreenName(), "username")) {

                                        //Low Level APIを使用
					DatastoreService service = DatastoreServiceFactory.getDatastoreService();
					Transaction transaction = service.beginTransaction();

					try {

                                                //リプライが既に投稿されたデータに存在するか検索
						Query query = new Query("Post");
						query.addFilter("postUser", FilterOperator.EQUAL, reply.getUser().getScreenName());
						query.addFilter("postText", FilterOperator.EQUAL, reply.getText());
						query.addSort("postDate", SortDirection.DESCENDING);
						PreparedQuery pq = service.prepare(query);
						FetchOptions limit = FetchOptions.Builder.withOffset(0).limit(1);
						List&lt;Entity&gt; results = pq.asList(limit);

						if(results.isEmpty()) {

                                                        //存在しなければポスト
							String postUser = "[@" + reply.getUser().getScreenName() + " #username]";
							String postText = reply.getText().replaceFirst("@username", "");
							twitter.updateStatus(postText + postUser);

                                                        //ポスト内容をBigTableへ登録
							Entity post = new Entity("Post");
							post.setProperty("postUser", reply.getUser().getScreenName());
							post.setProperty("postText", reply.getText());
							post.setProperty("postDate", new Date());
							service.put(transaction, post);
							transaction.commit();
						}
					} finally {
						if (transaction.isActive()) {
							transaction.rollback();
						}
					}
				}
                        }
		} catch (TwitterException e) {
			e.printStackTrace();
		}
	}
}
</pre>
<p>はい、ホント一気に書いちゃった感の強いコードなので突っ込み歓迎です。参考になればどうぞ。</p>
<p>一応解説しますと、まずJavaでTwitter APIを扱うのに便利な<a href="http://yusuke.homeip.net/twitter4j/ja/index.html#introduction" target="_blank">Twitter4j</a>というライブラリがありましたので、これを含めてGAE開発環境を整えます。この辺は<a href="http://sites.google.com/site/bot2uku/2009-08-15_j1" target="_blank">GAEでTwitterのbotを作る のまとめページ</a>が詳しいです。ていうか半分はここの手順どおりやるだけでできちゃいますね。</p>
<p>やってることはこんな感じ。</p>
<ul>
<li>リプライ内容を取得する</li>
<li>リプライ内容を回しフォロワーのリプライなら処理を続ける</li>
<li>Low level APIでフィルタをかけてBigTableからポスト内容と合致するデータを取得</li>
<li>合致するデータが存在しなければリプライ内容をポストすると同時にBigTableに登録する</li>
</ul>
<p>多分、重複チェック的ロジックでポスト済みデータかどうか判断している部分はBigTableなんか使わなくても他にも良い方法がたくさんあると思いますが、今回は単純にLow level APIを学習目的で使いたかっただけです。Low level APIに関しては<a href="http://shin1o.blogspot.com/2009/08/appengine-javalow-level-apiapi.html" target="_blank">#appengine JavaのLow-Level API(低レベルAPI)入門 </a>が詳しいです。</p>
<p>あとはTwitter APIについて理解が薄いとよくわかりません。私みたいに勢いで始めるとFriendとFollowerとかReplyとMentionsとか言葉に惑わされる部分が多々ありました。事前に<a href="http://watcher.moe-nifty.com/memo/2007/04/twitter_api.html" target="_blank">Twitter API 仕様書 (勝手に日本語訳シリーズ</a>とか<a href="http://yusuke.homeip.net/twitter4j/ja/api-support.html" target="_blank">Twitter4jサポートAPI</a>などは目を通しておいた方が良いでしょう。</p>
<p>で、これをcronの設定をしてGAEにデプロイすれば完成です。cronの設定方法は<a href="http://sites.google.com/site/bot2uku/2009-08-15_j1#TOC-cron-" target="_blank">cron(定期的にプログラムを起動する)を設定してみよう</a>が詳しいでしょう。ちなみにコード中の「username」と「password」はそれぞれ自分のアカウントのやつですよ。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/bigtable" title="BigTable" rel="tag">BigTable</a>, <a href="http://www.artsnet.jp/archives/tag/gae" title="GAE" rel="tag">GAE</a>, <a href="http://www.artsnet.jp/archives/tag/google-app-engine-for-java" title="Google App Engine for Java" rel="tag">Google App Engine for Java</a>, <a href="http://www.artsnet.jp/archives/tag/low-level-api" title="Low Level API" rel="tag">Low Level API</a>, <a href="http://www.artsnet.jp/archives/tag/twitter4j" title="Twitter4j" rel="tag">Twitter4j</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/940" title="TwitterボットアプリとTwitterアカウントをつなぐためだけの簡単なOAuth認証 (2011 年 1 月 16 日)">TwitterボットアプリとTwitterアカウントをつなぐためだけの簡単なOAuth認証</a> (1)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/870/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FriendFeedの便利な使い方</title>
		<link>http://www.artsnet.jp/archives/850</link>
		<comments>http://www.artsnet.jp/archives/850#comments</comments>
		<pubDate>Wed, 10 Jun 2009 01:11:30 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[FriendFeed]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=850</guid>
		<description><![CDATA[Twitterはあのクライアント、アレはこれ、それはどれといった忙しさはなくなります。友達の使っているサービスは全てFriendFeedの「仮想の友達」として登録してFriendFeedさえ確認していれば全て確認できるわけです]]></description>
			<content:encoded><![CDATA[<p>この記事を読んで</p>
<p><a title="Friendfeedの使い方が見えてきた" href="http://ochikun.blogspot.com/2009/06/friendfeed.html" target="_blank">Friendfeedの使い方が見えてきた</a></p>
<p><a href="http://ochikun.blogspot.com/2009/06/friendfeed.html"></a><a href="http://ochikun.blogspot.com/2009/06/friendfeed.html" target="_blank">http://ochikun.blogspot.com/2009/06/friendfeed.html</a></p>
<p>そうですね。自分のライフストリーミング（活動記録）を集約して自分に興味のある人に見てもらう。これがFriendFeedの使い方の基本であることは間違いないかと思います。</p>
<p>ただ、ここで止まると自分がFriendFeedにアクセス（直接orツールなどで間接）することがほとんどなくなります。私もこの状態が結構長く続きましたが「ある使い方」を知ることでFriendFeedを「自分の便利なツール」としても使えるようになりました。<br />
<span id="more-850"></span><br />
その使い方とは「仮想の友達」です。手順は以下の通り。</p>
<ol>
<li>FriendFeedの「友達」をクリック</li>
<li>下のほうに現れる「Imaginary friends」というリンクをクリック</li>
<li>「仮想の友達を作成」ボタンをクリック</li>
<li>「仮想の友達」の名前を入力して「作成」をクリック</li>
<li>サービス登録画面になるので「仮想の友達」が利用中のサービスを登録</li>
<li>お好みで「仮想の友達」のアイコンも変えてあげる</li>
</ol>
<p>これはいったい何なのかと言いますとFriendFeedユーザでない人をあたかもFriendFeedユーザのように扱うことができる方法です。たとえばFriendFeedはやっていないけどTwitterとはてなをやっている「AntiFF」さんという友達がいたとします。この友達を上記手順でFriendFeedの「仮想の友達」として作成します。</p>
<p>作成すると自分のFriendFeedの設定と同じように作成した「仮想の友達」のアイコンを変更したりサービスを追加できるようになります。アイコンをわかりやすくAntiFFさんのTwitterのアイコンの画像に変更し、Twitterとはてなをサービスとして登録します。どちらもサービスのアイコンをクリックすると表示されるユーザ名入力欄にユーザ名を入力すればそのサービスのフィードが読み込まれます。</p>
<p>結果的にAntiFFさんがFriendFeedを始めたかのように自分のFriendFeed上にAntiFFさんの活動履歴が流れだします。そいつをFriendFeed用のクライアントなどで随時追うというわけです。もちろん当のAntiFFさんはFriendFeedに登録していませんし、そんな風に自分の活動を一元的に追跡されていることは（教えなければ）知りません。</p>
<p>このようにFriendFeedは「ライフストーキングツール」（笑）としても使えます。いや本気のネットストーキングには悪用しないでくださいね。</p>
<p>最後に蛇足ですが私のFriendFeedの活用方法を一例として記しておきます。</p>
<p>FriendFeedはTwitterと違ってページ自体が自動更新されます。ブラウザで「ホーム」を開いたままにしていると友達のフィードがプッシュされてきます（されたように見えます）ので特にクライアントを使うほどでもないのですが、私は基本ブラウザでiGoogleをホームページとして開きっぱなしにして使ってますのでiGoogle用のFriendFeedガジェットを使っています。ただ、これが自動更新なしのただのフィードリーダ的なツールで物足りないのですが&#8230;（いずれ自分で作ります）</p>
<p>ツール類はFriendFeedサイト一番下のコピーライト部分のメニュー項目「ツール＆ウィジェット」をクリックすると出てきます。私はこの中の「iGoogle」と「FriendFeed Notifier」を利用しています。FriendFeed Notifierは誰かが何か活動するとデスクトップにポップアップで表示されるツールです。FriendFeed Notifierのポップアップで一瞬見て興味があればiGoogleのガジェットを更新して詳細を確認という感じです。</p>
<p>こうすることでTwitterはあのクライアント、アレはこれ、それはどれといった忙しさはなくなります。友達の使っているサービスは全てFriendFeedの「仮想の友達」として登録してFriendFeedさえ確認していれば全て確認できるわけです。</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/friendfeed" title="FriendFeed" rel="tag">FriendFeed</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/243" title="FriendFeedウィジットのCSSデザイン変更 (2009 年 2 月 12 日)">FriendFeedウィジットのCSSデザイン変更</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/252" title="Footprintsの設置とCSSデザイン変更 (2009 年 2 月 13 日)">Footprintsの設置とCSSデザイン変更</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/850/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ubuntuにeclipse+PDTでCakePHPデバッグ環境</title>
		<link>http://www.artsnet.jp/archives/832</link>
		<comments>http://www.artsnet.jp/archives/832#comments</comments>
		<pubDate>Thu, 30 Apr 2009 02:26:15 +0000</pubDate>
		<dc:creator>arts</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[PDT]]></category>

		<guid isPermaLink="false">http://www.artsnet.jp/?p=832</guid>
		<description><![CDATA[ubuntuにeclipse on PDTでCakePHPプロジェクトをデバッグする環境を構築します。eclipseはホームディレクトリに、xamppは/optにダウンロード&#038;展開しました。]]></description>
			<content:encoded><![CDATA[<p>ubuntuにeclipse on PDTでCakePHPプロジェクトをデバッグする環境を構築します。</p>
<ul>
<li>ubuntu 8系</li>
<li>xampp for Linux 1.7.1</li>
<li>eclipse 3.4</li>
<li>CakePHP 1.2</li>
</ul>
<p>eclipseはホームディレクトリに、xamppは/optにダウンロード&amp;展開しました。パッケージ管理(apt及びそのフロントエンドのSynaptic)でもインストールできますが、eclipseはパッケージ管理で入れるとプラグイン追加時にエラーでまくりでいちいち対処するのが面倒でした。</p>
<p>まずはxampp for Linuxから。<br />
<span id="more-832"></span><br />
<a title="XAMPP for Linux" href="http://www.apachefriends.org/jp/xampp-linux.html" target="_blank">XAMPP for Linux</a>からtarボールをダウンロード。/optに展開。xamppを起動。</p>
<pre class="prettyprint">sudo tar zxvf xampp-linux-1.7.1.tar.gz -C /opt
sudo /opt/lampp/lampp start</pre>
<p>僕の環境ではMySQLがすんなり起動しませんでした。<a title="XAMPP for LinuxでMySQLが起動しない場合" href="http://blog.raxus.co.jp/article/101887253.html" target="_blank">XAMPP for LinuxでMySQLが起動しない場合</a>の修正→xamppを再起動で解決。</p>
<pre class="prettyprint">sudo vim /opt/lampp/bin/mysql.server
$bindir/mysqld_safe --datadir=$datadir --pid-file=$server_pid_file $other_args &gt;/dev/null 2&gt;&amp;1 &amp;
↓
$bindir/mysqld_safe <span style="color: #ff0000;">--user=root</span> --datadir=$datadir --pid-file=$server_pid_file $other_args &gt;/dev/null 2&gt;&amp;1 &amp;</pre>
<p>PHPの文字化け対策。</p>
<pre class="prettyprint">sudo vim /opt/lampp/etc/php.ini
#[mbstring]の下に以下を追加
mbstring.internal_encoding = auto
mbstring.http_input = auto
mbstring.http_output = auto</pre>
<p>MySQLの文字化け対策。</p>
<pre class="prettyprint">sudo vim /opt/lampp/etc/my.cnf
#[mysqld]の下に以下を追加
default-character-set=utf8
skip-character-set-client-handshake</pre>
<p>utf-8に統一してxamppを再起動。</p>
<p>続いてPHPにZendデバッガーを設定。<a title="ZendDebugger" href="http://downloads.zend.com/pdt/server-debugger/" target="_blank">ZendDebugger</a>から最新のものをダウンロードして展開。xampp1.7.1のPHPは5.2系なので展開した中から「5_2_x_comp」ディレクトリを使います。xamppのlibディレクトリに専用のディレクトリを作成しコピー。</p>
<pre class="prettyprint">sudo mkdir /opt/lampp/lib/zend
sudo mkdir /opt/lampp/lib/zend/5_2_x
cd デスクトップ/ZendDebugger-5.2.15RC1-linux-glibc23-i386/5_2_x_comp
sudo cp ZendDebugger.so /opt/lampp/lib/zend/5_2_x/ZendDebugger.so</pre>
<p>php.iniにコピーしたファイルを読み込む設定。</p>
<pre class="prettyprint">sudo vim /opt/lampp/etc/php.ini
#最終行に以下を追加
[Zend]
zend_extension=/opt/lampp/lib/zend/5_2_x/ZendDebugger.so
zend_debugger.allow_hosts=127.0.0.1
zend_debugger.expose_remotely=always</pre>
<p>phpinfoでZend debuggerが表示されれば設定完了。</p>
<p>あと、そのままではmod_rewriteが効かなかった。mod_rewriteは有効だったがAllowOverride Noneになってて.htaccessが効かない状態でした。<a title="Ubuntuでapacheのmod_rewriteを有効にする" href="http://d.hatena.ne.jp/kasahi/20090202/1233598591" target="_blank">Ubuntuでapacheのmod_rewriteを有効にする</a>を見て修正してxamppを再起動。</p>
<pre class="prettyprint">sudo vim /opt/lampp/etc/httpd.conf
&lt;Directory /var/www/&gt;
...
# AllowOverride None コメントアウトして以下を追加
AllowOverride All
...
&lt;/Directory&gt;e</pre>
<p>最後にマシン起動時、自動的にxamppが起動するように設定。</p>
<pre class="prettyprint">sudo vim /etc/rc.local
#exit 0の上に以下を追加
/opt/lampp/lampp start</pre>
<p>次にeclipse。</p>
<p>Synapticでsun-java6-jdkをインストール。</p>
<p><a title="All-In-One PDT 2.0 (Linux x86/GTK 2)" href="http://www.eclipse.org/pdt/downloads/" target="_blank">eclipse PDT </a>からAll-In-One PDT x.x (Linux x86/GTK 2)をダウンロードしてホームディレクトリに展開してPleiadesで日本語化。<a title="ubuntuにeclipse+PDTでCakePHPデバッグ環境" href="http://blogs.yahoo.co.jp/muiminamoji/16441222.html" target="_blank">Eclipse + PDTのインストール</a>が解りやすい。</p>
<p>CakePHPプロジェクト毎にサブドメインを設定。まずはhttpd.confにhttpd-vhosts.confを読み込む設定。</p>
<pre class="prettyprint">sudo vim  /opt/lampp/etc/httpd.conf
Include etc/extra/httpd-vhosts.conf #コメントアウト解除</pre>
<p>バーチャルホストの設定。xampleはホスト名。project1, project2はそれぞれのプロジェクト名。</p>
<pre class="prettyprint">sudo vim  /opt/lampp/etc/extra/httpd-vhosts.conf
NameVirtualHost *:80 #コメントアウト解除

&lt;VirtualHost *:80&gt;
    ServerAdmin info@example.com
    DocumentRoot /opt/lampp/htdocs/xampp
    ServerName xampp.example
&lt;/VirtualHost&gt;

&lt;VirtualHost *:80&gt;
    ServerAdmin info@example.com
    DocumentRoot /home/user1/workspace/project1
    ServerName project1.example
    ErrorLog logs/project1.example-error_log
    CustomLog logs/project1.example-access_log common
&lt;/VirtualHost&gt;

&lt;VirtualHost *:80&gt;
    ServerAdmin info@example.com
    DocumentRoot /home/user1/workspace/project2
    ServerName project2.example
    ErrorLog logs/project2.example-error_log
    CustomLog logs/project2.example-access_log common
&lt;/VirtualHost&gt;</pre>
<p>最後にhostsファイルをいじる。</p>
<pre class="prettyprint">sudo vim  /etc/hosts
#127.0.0.1       localhost の下に以下を追加
127.0.0.1       example xampp.example project1.example project2.example</pre>
<p>PHPデバッグ構成の設定。</p>
<ul>
<li>eclipseを起動してメニュー「ウィンドウ」→「パースペクティブを開く」→「PHP」</li>
<li>メニューが切り替わって「実行」→「デバッグの構成」</li>
<li>左リストの「PHP Web ページ」を右クリックで「新規」</li>
<li>名前「project1」（任意）、サーバ・デバッガ「Zend デバッガー」</li>
<li>PHP サーバーで「新規」→名前「project1」、URL「http://project1.example」</li>
<li>ファイル「/project1/index.php」、「最初の行でブレーク」のチェックを外す</li>
<li>最後のURLは「自動生成」のチェックを外し右側の欄に「/」だけ入力</li>
<li>project2も別の設定で同じように入力する</li>
</ul>
<p>画像付きで解りやすいのは<a title="【CakePHP】Eclipse＋PDT＋Xdebugを使ったデバッグ方法について、画面付でまとめみる" rel="bookmark" href="http://blog.ne2ma2.com/archives/121" target="_blank">【CakePHP】Eclipse＋PDT＋Xdebugを使ったデバッグ方法について、画面付でまとめみる</a>。デバッガがXdebugなのとサブディレクトリ運用な点がこちらの記事とは違います。（僕の環境ではサブディレクトリ運用はブレークポイントで止まりませんでした）</p>

	<br /><h4>タグ</h4><a href="http://www.artsnet.jp/archives/tag/cakephp" title="CakePHP" rel="tag">CakePHP</a>, <a href="http://www.artsnet.jp/archives/tag/eclipse" title="eclipse" rel="tag">eclipse</a>, <a href="http://www.artsnet.jp/archives/tag/pdt" title="PDT" rel="tag">PDT</a>, <a href="http://www.artsnet.jp/archives/tag/ubuntu" title="ubuntu" rel="tag">ubuntu</a><br /><br />

	<h4>関連する投稿</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.artsnet.jp/archives/830" title="VMware上のubuntuでマウス設定 (2009 年 4 月 9 日)">VMware上のubuntuでマウス設定</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/16" title="ubuntuをUSBメモリからインストール (2009 年 1 月 22 日)">ubuntuをUSBメモリからインストール</a> (6)</li>
	<li><a href="http://www.artsnet.jp/archives/103" title="PHPでリダイレクトしたら画面が真っ白 (2009 年 2 月 2 日)">PHPでリダイレクトしたら画面が真っ白</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/774" title="CakePHPのfolder.phpでディレクトリ操作 (2009 年 3 月 30 日)">CakePHPのfolder.phpでディレクトリ操作</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/328" title="CakePHPでレンダリング結果をファイル出力 (2009 年 2 月 17 日)">CakePHPでレンダリング結果をファイル出力</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/605" title="CakePHPでモデル名変更への対処 (2009 年 3 月 15 日)">CakePHPでモデル名変更への対処</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/541" title="CakePHPでDBデータからセレクトボックス作成 (2009 年 3 月 14 日)">CakePHPでDBデータからセレクトボックス作成</a> (0)</li>
	<li><a href="http://www.artsnet.jp/archives/171" title="CakePHPでAmazon Web Service (2009 年 2 月 8 日)">CakePHPでAmazon Web Service</a> (1)</li>
	<li><a href="http://www.artsnet.jp/archives/528" title="CakePHPで3つ以上の複数テーブルを結合 (2009 年 3 月 13 日)">CakePHPで3つ以上の複数テーブルを結合</a> (1)</li>
	<li><a href="http://www.artsnet.jp/archives/711" title="CakePHP1.1でFCKEditorヘルパー作成 (2009 年 3 月 23 日)">CakePHP1.1でFCKEditorヘルパー作成</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.artsnet.jp/archives/832/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

