<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="rss.css" type="text/css"?>
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="ja-JP">
	<channel rdf:about="http://www.pshared.net/diary/index.rdf">
	<title>Ussy Diary</title>
	<link>http://www.pshared.net/diary/</link>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/" />
	<description></description>
	<dc:creator>Ussy</dc:creator>
	<dc:rights>Copyright 2010 Ussy, copyright of comments by respective authors</dc:rights>
	<image rdf:resource="http://www.pshared.net/image/banner.png" />
<items><rdf:Seq>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100310.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100301.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100228.html#p02"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100228.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100224.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100216.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100210.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100127.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100123.html#p02"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100123.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100121.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100117.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100110.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100109.html#p01"/>
<rdf:li rdf:resource="http://www.pshared.net/diary/20100105.html#p01"/>
</rdf:Seq></items>
</channel>
<image rdf:about="http://www.pshared.net/image/banner.png">
	<title>Ussy Diary</title>
	<url>http://www.pshared.net/image/banner.png</url>
	<link>http://www.pshared.net/diary/</link>
	</image>
	<item rdf:about="http://www.pshared.net/diary/20100310.html#p01">
<link>http://www.pshared.net/diary/20100310.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100310.html#p01" />
<dc:date>2010-03-11T01:31:57+09:00</dc:date>
<title>Mac Thunderbird の「差出人情報を管理」ボタンをすべて出す userstyle</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Thunderbird</dc:subject>
<dc:subject>Mac</dc:subject>
<dc:subject>Stylish</dc:subject>
<description>Before  自分の環境の問題だけなのかもしれませんが、 Mac の Thunderbird の差出人情報の管理ボタンが半分ぐらいしか出ていません。最初まったく存在に気づかなくて、 Thunderbird は差出人情報が設定できないのかと思ってしまいました。 そこで管理ボタンをすべて出す userstyle を書きました。 userChrome.css を編集するか、 Stylish をインストールします。 Stylish :: Add-ons for Thunderbird 以下のコードを貼り付けます。 Stylish であればアドオンのタブに「ユーザースタイル」という項目が追加されていますので、そこから「新しいスタイルを書く」をクリックして貼り付けます。 @namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);  #accountManager {   height: 54em !important; } After  無事すべて出ました。</description>
<content:encoded><![CDATA[<h3>Mac Thunderbird の「差出人情報を管理」ボタンをすべて出す userstyle</h3><h4>Before</h4>
<p><a href="http://www.pshared.net/diary/images/20100310_0.png"><img class="left" src="http://www.pshared.net/diary/images/20100310_0.png" alt="隠れてる" title="隠れてる" width="250" height="165"></a></p>
<p>自分の環境の問題だけなのかもしれませんが、 Mac の Thunderbird の差出人情報の管理ボタンが半分ぐらいしか出ていません。最初まったく存在に気づかなくて、 Thunderbird は差出人情報が設定できないのかと思ってしまいました。</p>
<p>そこで管理ボタンをすべて出す userstyle を書きました。
userChrome.css を編集するか、 Stylish をインストールします。</p>
<p><a href="https://addons.mozilla.org/ja/thunderbird/addon/2108">Stylish :: Add-ons for Thunderbird</a></p>
<p>以下のコードを貼り付けます。</p>
<p>Stylish であればアドオンのタブに「ユーザースタイル」という項目が追加されていますので、そこから「新しいスタイルを書く」をクリックして貼り付けます。</p>
<pre>@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);

#accountManager {
  height: 54em !important;
}</pre>
<h4>After</h4>
<p><a href="http://www.pshared.net/diary/images/20100310_1.png"><img class="left" src="http://www.pshared.net/diary/images/20100310_1.png" alt="すべて出た" title="すべて出た" width="250" height="165"></a></p>
<p>無事すべて出ました。</p>
<p><a href="http://www.pshared.net/diary/20100310.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100301.html#p01">
<link>http://www.pshared.net/diary/20100301.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100301.html#p01" />
<dc:date>2010-03-02T02:10:51+09:00</dc:date>
<title>tDiary のはてなスターを AutoPagerize に対応する</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>tDiary</dc:subject>
<dc:subject>Hatena</dc:subject>
<description>ヘッダーに以下の JavaScript を埋め込みます。 script type=&quot;text/javascript&quot; !-- (function() {   var nodeInsert = function(evt) {     Hatena.Star.EntryLoader.loadNewEntries(evt.target);   };   window.addEventListener('AutoPagerize_DOMNodeInserted', nodeInsert, false);   window.addEventListener('AutoPatchWork.DOMNodeInserted', nodeInsert, false); })(); //-- /script AutoPagerize 0.40 以降対応のようです（未検証） 参考 http://rewish.org/javascript/hatena_star</description>
<content:encoded><![CDATA[<h3>tDiary のはてなスターを AutoPagerize に対応する</h3><p>ヘッダーに以下の JavaScript を埋め込みます。</p>
<pre>&lt;script type="text/javascript"&gt;
&lt;!--
(function() {
  var nodeInsert = function(evt) {
    Hatena.Star.EntryLoader.loadNewEntries(evt.target);
  };
  window.addEventListener('AutoPagerize_DOMNodeInserted', nodeInsert, false);
  window.addEventListener('AutoPatchWork.DOMNodeInserted', nodeInsert, false);
})();
//--&gt;
&lt;/script&gt;</pre>
<p>AutoPagerize 0.40 以降対応のようです（未検証）</p>
<h4>参考</h4>
<p><a href="http://rewish.org/javascript/hatena_star">http://rewish.org/javascript/hatena_star</a></p>
<p><a href="http://www.pshared.net/diary/20100301.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100228.html#p02">
<link>http://www.pshared.net/diary/20100228.html#p02</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100228.html#p02" />
<dc:date>2010-02-28T15:22:32+09:00</dc:date>
<title>KeySnail から SBM カウンタを操作する</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Firefox</dc:subject>
<dc:subject>KeySnail</dc:subject>
<description>書いていて SBM カウンタを操作する KeySnail のキー割り当てを思い出したので、貼っておきます。元々 Minibuffer でやっていたものを移植したものです。マウスを右下に持って行くことなくコメントをさらっとみることができます。 key.setGlobalKey(['C-c', 'c'], function (ev, arg) {     var document = window.content.document;     var comments = document.getElementById(&quot;SBMCounterComments&quot;);     var tab = document.getElementById(&quot;SBMCounterCommentsTab&quot;);     var area = document.getElementById(&quot;SBMCounterCommentsArea&quot;);     if (! (comments  tab  area)) {         return;     }     var visible = !(tab.styl..</description>
<content:encoded><![CDATA[<h3>KeySnail から SBM カウンタを操作する</h3><p>書いていて SBM カウンタを操作する KeySnail のキー割り当てを思い出したので、貼っておきます。元々 Minibuffer でやっていたものを移植したものです。マウスを右下に持って行くことなくコメントをさらっとみることができます。</p>
<pre>key.setGlobalKey(['C-c', 'c'], function (ev, arg) {
    var document = window.content.document;
    var comments = document.getElementById("SBMCounterComments");
    var tab = document.getElementById("SBMCounterCommentsTab");
    var area = document.getElementById("SBMCounterCommentsArea");
    if (! (comments &amp;&amp; tab &amp;&amp; area)) {
        return;
    }
    var visible = !(tab.style.display == "block");
    comments.style.width = visible ? "auto" : "30px";
    comments.style.height = visible ? "auto" : "30px";
    tab.style.display = visible ? "block" : "none";
    area.style.display = visible ? "block" : "none";
}, 'SBM カウンタコメント開閉');</pre>
<pre>key.setGlobalKey(['C-c', 'n'], function (ev, arg) {
    var document = window.content.document;
    var comments = document.getElementById("SBMCounterComments");
    var tab = document.getElementById("SBMCounterCommentsTab");
    var area = document.getElementById("SBMCounterCommentsArea");
    if (! (comments &amp;&amp; tab &amp;&amp; area)) {
        return;
    }
    var visible = tab.style.display == "block";
    if (!visible) {
        return;
    }
    area.scrollTop = area.scrollTop + area.clientHeight / 4;
}, 'SBM カウンタ下へスクロール');</pre>
<pre>key.setGlobalKey(['C-c', 'p'], function (ev, arg) {
    var document = window.content.document;
    var comments = document.getElementById("SBMCounterComments");
    var tab = document.getElementById("SBMCounterCommentsTab");
    var area = document.getElementById("SBMCounterCommentsArea");
    if (! (comments &amp;&amp; tab &amp;&amp; area)) {
        return;
    }
    var visible = tab.style.display == "block";
    if (!visible) {
        return;
    }
    area.scrollTop = area.scrollTop - area.clientHeight / 4;
}, 'SBM カウンタ上へスクロール');</pre>
<p><a href="http://www.pshared.net/diary/20100228.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100228.html#p01">
<link>http://www.pshared.net/diary/20100228.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100228.html#p01" />
<dc:date>2010-02-28T14:55:01+09:00</dc:date>
<title>SBM カウンタのフィルター設定</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Firefox</dc:subject>
<description>SBM カウンタを利用させてもらっているのですが、 URL に about ですとか、 http といった文字列が含まれているとブックマーク数を取得しに行かない問題を認識していました。少しだけ時間を取ってコードをみてみたりしたのですが、フィルター設定の初期設定値が問題のようです。 about:* が問題で about: の : が 0 以上繰り返すものと正規表現で判断し、 URL に about が含まれていればフィルタが効いてしまう状態でした。 ^about:.* と変えてあげることで about が URL 文字列に含まれていてもリクエストしてくれるようになりました。他のフィルタも同じ形に修正しました。 今は HTTPS アクセスはデフォルトで遮断してくれていますが、例えば MDC が https だけ許容していたりしているので、例外的な設定もあると嬉しいなあと思います。 MDC が http も受け付けてくれると嬉しいのですが、その場合ブックマークがばらばらになってしまう問題もあるので難しいところです。 あと ^https?://.*\.自社ドメイン/.* みたいなものを入れ..</description>
<content:encoded><![CDATA[<h3>SBM カウンタのフィルター設定</h3><p><a href="http://miniturbo.org/products/sbmcounter/">SBM カウンタ</a>を利用させてもらっているのですが、 URL に about ですとか、 http といった文字列が含まれているとブックマーク数を取得しに行かない問題を認識していました。少しだけ時間を取ってコードをみてみたりしたのですが、フィルター設定の初期設定値が問題のようです。</p>
<pre>about:*</pre>
<p>が問題で about: の : が 0 以上繰り返すものと正規表現で判断し、 URL に about が含まれていればフィルタが効いてしまう状態でした。</p>
<pre>^about:.*</pre>
<p>と変えてあげることで about が URL 文字列に含まれていてもリクエストしてくれるようになりました。他のフィルタも同じ形に修正しました。</p>
<p>今は HTTPS アクセスはデフォルトで遮断してくれていますが、例えば <a href="https://developer.mozilla.org/">MDC</a> が https だけ許容していたりしているので、例外的な設定もあると嬉しいなあと思います。 MDC が http も受け付けてくれると嬉しいのですが、その場合ブックマークがばらばらになってしまう問題もあるので難しいところです。</p>
<p>あと ^https?://.*\.自社ドメイン/.* みたいなものを入れておかないと、自社サーバーにアクセスしたときにも URL を通知してしまうので、こういった拡張をつかうときは機密情報が漏れないようにしておくことが大事だと思います。</p>
<p><a href="http://www.pshared.net/diary/20100228.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100224.html#p01">
<link>http://www.pshared.net/diary/20100224.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100224.html#p01" />
<dc:date>2010-02-26T02:43:12+09:00</dc:date>
<title>URL を綺麗にするグリモン UrlCleaner</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Greasemonkey</dc:subject>
<description>余分なパラメータが URL についていたら削除するグリモンです。ブックマークの URL を分散させないことを目的としています。 http://github.com/ussy/greasemonkey/raw/master/urlcleaner.user.js SITEINFO を定義していけばいいようにしています。今のところ下の定義になっています。  url  正規表現で対象 URL を指定します。  live  URL に残しておきたいパラメーター名を指定します。マッチした場合は指定した以外のパラメーター名は削除します。  kill  URL から消し去りたいパラメーター名を指定します。マッチしなかったパラメーターは残ります。   今のところ FeedBunner と Youtube だけです。 rss パラメーターがついてしまうとか、色々あった気がしますが、忘れてしまったので気がついたときに SITEINFO に追加していこうと思います。増やすと動作が重くなりますけれど・・・ RSS のパラメーターがついてしまうとか、それぞれグリモンがあって、ひとつで管理したくてつくりました。..</description>
<content:encoded><![CDATA[<h3>URL を綺麗にするグリモン UrlCleaner</h3><p>余分なパラメータが URL についていたら削除するグリモンです。ブックマークの URL を分散させないことを目的としています。</p>
<p><a href="http://github.com/ussy/greasemonkey/raw/master/urlcleaner.user.js">http://github.com/ussy/greasemonkey/raw/master/urlcleaner.user.js</a></p>
<p>SITEINFO を定義していけばいいようにしています。今のところ下の定義になっています。</p>
<dl>
<dt>url</dt>
<dd> 正規表現で対象 URL を指定します。
</dd>
<dt>live</dt>
<dd> URL に残しておきたいパラメーター名を指定します。マッチした場合は指定した以外のパラメーター名は削除します。
</dd>
<dt>kill</dt>
<dd> URL から消し去りたいパラメーター名を指定します。マッチしなかったパラメーターは残ります。
</dd>
</dl>
<p>今のところ FeedBunner と Youtube だけです。 rss パラメーターがついてしまうとか、色々あった気がしますが、忘れてしまったので気がついたときに SITEINFO に追加していこうと思います。増やすと動作が重くなりますけれど・・・</p>
<p>RSS のパラメーターがついてしまうとか、それぞれグリモンがあって、ひとつで管理したくてつくりました。</p>
<p>[追記]</p>
<p>wedata から SITEINFO 読む込む対応します。</p>
<p>[追々記]</p>
<p>対応しました。バグもありましたので、同じ URL から更新お願いします。</p>
<p><a href="http://wedata.net/databases/UrlCleaner/items">http://wedata.net/databases/UrlCleaner/items</a></p>
<p><a href="http://www.pshared.net/diary/20100224.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100216.html#p01">
<link>http://www.pshared.net/diary/20100216.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100216.html#p01" />
<dc:date>2010-02-17T02:42:25+09:00</dc:date>
<title>Firefox 拡張 LDRNotifier を Github に置きました</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Firefox</dc:subject>
<description>http://github.com/ussy/ldrnotifier それにともなって更新先の URL も Github にして、バージョンを 1.0.5 に上げました。またライセンスを MPL から MIT に変更します。 更新スクリプト create_package.sh は keysnail のものを参考(ほぼパクリ)にさせて頂きました。</description>
<content:encoded><![CDATA[<h3>Firefox 拡張 LDRNotifier を Github に置きました</h3><p><a href="http://github.com/ussy/ldrnotifier">http://github.com/ussy/ldrnotifier</a></p>
<p>それにともなって更新先の URL も Github にして、バージョンを 1.0.5 に上げました。またライセンスを MPL から MIT に変更します。</p>
<p>更新スクリプト create_package.sh は <a href="http://github.com/mooz/keysnail">keysnail</a> のものを参考(ほぼパクリ)にさせて頂きました。</p>
<p><a href="http://www.pshared.net/diary/20100216.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100210.html#p01">
<link>http://www.pshared.net/diary/20100210.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100210.html#p01" />
<dc:date>2010-02-11T00:59:42+09:00</dc:date>
<title>Cocoa Emacs へのドラッグアンドドロップでウィンドウを開かないようにする</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Emacs</dc:subject>
<dc:subject>Mac</dc:subject>
<description>ファイルのドラッグアンドドロップや、グリモンのエディタに Emacs.app を指定していた場合、編集しようとすると新たにウィンドウが出てしまいます。 以下の設定をつけてあげることで、開いているウィンドウの新規バッファに開くことができました。 (setq ns-pop-up-frames nil)</description>
<content:encoded><![CDATA[<h3>Cocoa Emacs へのドラッグアンドドロップでウィンドウを開かないようにする</h3><p>ファイルのドラッグアンドドロップや、グリモンのエディタに Emacs.app を指定していた場合、編集しようとすると新たにウィンドウが出てしまいます。</p>
<p>以下の設定をつけてあげることで、開いているウィンドウの新規バッファに開くことができました。</p>
<pre>(setq ns-pop-up-frames nil)</pre>
<p><a href="http://www.pshared.net/diary/20100210.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100127.html#p01">
<link>http://www.pshared.net/diary/20100127.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100127.html#p01" />
<dc:date>2010-01-27T23:57:01+09:00</dc:date>
<title>Android 端末のディスプレイサイズを取得する</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Android</dc:subject>
<description>Activity#onCreate WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); Log.d(&quot;display&quot;, &quot;w:&quot; + display.getWidth()); Log.d(&quot;display&quot;, &quot;h:&quot; + display.getHeight()); 実行結果 w:320 h:480 onCreate 時には、まだレイアウトの初期化が行われないため View の width/height からは 0 が返ってきます。調べてみると WindowManager を経由して取得した Display クラスから onCreate 時に取得できました。 こちらは View の onSizeChanged イベントから取得する方法です。 throw Life - Viewの幅と高さを取得する方法を考える</description>
<content:encoded><![CDATA[<h3>Android 端末のディスプレイサイズを取得する</h3><h4>Activity#onCreate</h4>
<pre>WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Log.d("display", "w:" + display.getWidth());
Log.d("display", "h:" + display.getHeight());</pre>
<h4>実行結果</h4>
<pre>w:320
h:480</pre>
<p>onCreate 時には、まだレイアウトの初期化が行われないため View の width/height からは 0 が返ってきます。調べてみると WindowManager を経由して取得した Display クラスから onCreate 時に取得できました。</p>
<p>こちらは View の onSizeChanged イベントから取得する方法です。</p>
<p><a href="http://www.adamrocker.com/blog/225/get_real_view_width_and_height.html">throw Life - Viewの幅と高さを取得する方法を考える</a></p>
<p><a href="http://www.pshared.net/diary/20100127.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100123.html#p02">
<link>http://www.pshared.net/diary/20100123.html#p02</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100123.html#p02" />
<dc:date>2010-01-23T15:04:12+09:00</dc:date>
<title>Sequel で保存時にタイムスタンプをつける</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Ruby</dc:subject>
<dc:subject>Sequel</dc:subject>
<description>カラム名を created_at, updated_at にしておくと、 save メソッドを呼び出したときに自動的に作成、更新時間を更新してくれるみたいです。カラム型は timestamp で確認しています。 さらに追加時にも更新時間を入れたい場合には timestamps プラグインを利用して、オプションを渡してあげるとよいです。 DB = Sequel.connect(&quot;sqlite://test.db&quot;)  class User  Sequel::Model   plugin :timestamps, :update_on_create = true end  DB.transaction do   User.new(:name = 'aaa').save   User.new(:name = 'bbb').save end 既存システムで、すでに別のカラム名が使われている場合には下のオプションを渡してあげると変更できます。 plugin :timestamps, :create = 'created_on', :update = 'updated_on' Module: ..</description>
<content:encoded><![CDATA[<h3>Sequel で保存時にタイムスタンプをつける</h3><p>カラム名を created_at, updated_at にしておくと、 save メソッドを呼び出したときに自動的に作成、更新時間を更新してくれるみたいです。カラム型は timestamp で確認しています。</p>
<p>さらに追加時にも更新時間を入れたい場合には timestamps プラグインを利用して、オプションを渡してあげるとよいです。</p>
<pre>DB = Sequel.connect("sqlite://test.db")

class User &lt; Sequel::Model
  plugin :timestamps, :update_on_create =&gt; true
end

DB.transaction do
  User.new(:name =&gt; 'aaa').save
  User.new(:name =&gt; 'bbb').save
end</pre>
<p>既存システムで、すでに別のカラム名が使われている場合には下のオプションを渡してあげると変更できます。</p>
<pre>plugin :timestamps, :create =&gt; 'created_on', :update =&gt; 'updated_on'</pre>
<p><a href="http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/Timestamps.html">Module: Sequel::Plugins::Timestamps [Sequel: The Database Toolkit for Ruby]</a></p>
<p>モデルすべてに適用したい場合は Sequel::Model で定義してあげるとよいみたいです。</p>
<pre>class Sequel::Model
   plugin :timestamps, :update_on_create =&gt; true, :create =&gt; 'created_on', :update =&gt; 'updated_on'
end

class User &lt; Sequel::Model; end</pre>
<p><a href="http://www.pshared.net/diary/20100123.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100123.html#p01">
<link>http://www.pshared.net/diary/20100123.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100123.html#p01" />
<dc:date>2010-01-23T14:09:35+09:00</dc:date>
<title>Encoding::UndefinedConversionError</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Ruby</dc:subject>
<dc:subject>Sequel</dc:subject>
<description>Ruby 1.9 上の Sequel で sqlite3 からマルチバイト文字列を含んだレコードを取得し to_json しようとすると Encoding::UndefinedConversionError: &quot;\xE2&quot; from ASCII-8BIT to UTF-8 というエラーが出力されます。 String#force_encoding で、いちいち utf-8 しないといけないのかと思ったところ、きちんと Sequel の plugin にエンコーディングを変換できるものが提供されていました。 class User  Sequel::Model   plugin :force_encoding, 'utf-8' end</description>
<content:encoded><![CDATA[<h3>Encoding::UndefinedConversionError</h3><p>Ruby 1.9 上の Sequel で sqlite3 からマルチバイト文字列を含んだレコードを取得し to_json しようとすると</p>
<pre>Encoding::UndefinedConversionError: "\xE2" from ASCII-8BIT to UTF-8</pre>
<p>というエラーが出力されます。</p>
<p>String#force_encoding で、いちいち utf-8 しないといけないのかと思ったところ、きちんと Sequel の plugin にエンコーディングを変換できるものが提供されていました。</p>
<pre>class User &lt; Sequel::Model
  plugin :force_encoding, 'utf-8'
end</pre>
<p><a href="http://www.pshared.net/diary/20100123.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100121.html#p01">
<link>http://www.pshared.net/diary/20100121.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100121.html#p01" />
<dc:date>2010-01-22T00:38:52+09:00</dc:date>
<title>Sinatra(Rack) のセッションを無効にする</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Ruby</dc:subject>
<dc:subject>Sinatra</dc:subject>
<dc:subject>Rack</dc:subject>
<description>まずサーバーセッションを有効にするには起動ファイルである config.ru で use します。 use Rack::Session::Pool 引数にオプションをつけてセッションを有効期限を変えたりします。 あとはクライアントから呼び出されたアクション(コントローラー)で session_options に :drop オプションを渡してあげると削除されます。 get '/' do   (session[:count] = (session[:count] || 0) + 1).to_s end  get '/clear' do   request.session_options[:drop] = true end http://localhost:4567/ をたたくとリクエストした数だけカウント数が画面に表示され、 /clear を叩いてから再度 / を叩くと、セッション ID が新たに割り当てられ 1 に戻ります。 :renew を渡すと新たなセッション ID を割り振りつつ、前の情報をマージしてくれます。 session.clear は単純に中身の Hash オブジェク..</description>
<content:encoded><![CDATA[<h3>Sinatra(Rack) のセッションを無効にする</h3><p>まずサーバーセッションを有効にするには起動ファイルである config.ru で use します。</p>
<pre>use Rack::Session::Pool</pre>
<p>引数にオプションをつけてセッションを有効期限を変えたりします。</p>
<p>あとはクライアントから呼び出されたアクション(コントローラー)で session_options に :drop オプションを渡してあげると削除されます。</p>
<pre>get '/' do
  (session[:count] = (session[:count] || 0) + 1).to_s
end

get '/clear' do
  request.session_options[:drop] = true
end</pre>
<p><a href="http://localhost:4567/">http://localhost:4567/</a> をたたくとリクエストした数だけカウント数が画面に表示され、 /clear を叩いてから再度 / を叩くと、セッション ID が新たに割り当てられ 1 に戻ります。 :renew を渡すと新たなセッション ID を割り振りつつ、前の情報をマージしてくれます。</p>
<p>session.clear は単純に中身の Hash オブジェクトをクリアするだけで、セッション ID はそのままでした。</p>
<p><a href="http://www.pshared.net/diary/20100121.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100117.html#p01">
<link>http://www.pshared.net/diary/20100117.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100117.html#p01" />
<dc:date>2010-01-18T03:01:07+09:00</dc:date>
<title>Sequel でマイグレーション</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Ruby</dc:subject>
<dc:subject>ORM</dc:subject>
<description>Ruby にある軽量 ORM Sequel を簡単に触ったことはあるのですが、マイグレーションもできるということで試してみました。 インストール $ sudo gem install rake $ sudo gem install sequel $ sudo gem install sqlite3-ruby 構成 +app_root/  +Rakefile  +db/   +migrate/    +001_migrate.rb    +002_migrate.rb 001_migrate.rb #!/usr/bin/env ruby  Class.new(Sequel::Migration) do   def up     create_table :users do       primary_key :id       varchar :name, :size = 32, :unique = true       varchar :salt, :size = 32, :null = false       varchar :hashed_password, :size = 6..</description>
<content:encoded><![CDATA[<h3>Sequel でマイグレーション</h3><p>Ruby にある軽量 ORM <a href="http://sequel.rubyforge.org/">Sequel</a> を簡単に触ったことはあるのですが、マイグレーションもできるということで試してみました。</p>
<h4>インストール</h4>
<pre>$ sudo gem install rake
$ sudo gem install sequel
$ sudo gem install sqlite3-ruby</pre>
<h4>構成</h4>
<pre>+app_root/
 +Rakefile
 +db/
  +migrate/
   +001_migrate.rb
   +002_migrate.rb</pre>
<h4>001_migrate.rb</h4>
<pre>#!/usr/bin/env ruby

Class.new(Sequel::Migration) do
  def up
    create_table :users do
      primary_key :id
      varchar :name, :size =&gt; 32, :unique =&gt; true
      varchar :salt, :size =&gt; 32, :null =&gt; false
      varchar :hashed_password, :size =&gt; 64, :null =&gt; false
      varchar :mail_address, :size =&gt; 128, :null =&gt; false
      timestamp :created_at
      timestamp :updated_at
    end

    add_index :users, :name
  end

  def down
    drop_index :users, :name
    drop_table :users
  end

end</pre>
<h4>002_migrate.rb</h4>
<pre>#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

Class.new(Sequel::Migration) do
  def up
    create_table :tags do
      primary_key :id
      varchar :name, :size =&gt; 32
    end

    from(:tags).insert(:name =&gt; 'あとでやる')
    from(:tags).insert(:name =&gt; '明日から本気出す')
  end

  def down
    drop_table :tags
  end

end</pre>
<p>クラスを匿名で生成していますが、意味づけを行う場合は名前をきちんとつけたほうが良いかもしれません。</p>
<p>Rake は引数を渡すと ENV 変数に書き込まれるので、これでバージョンを指定できます。</p>
<h4>Rakefile</h4>
<pre>#!/usr/bin/env ruby

require 'rubygems'
require 'rake'
require 'sequel'
require 'sequel/extensions/migration'

namespace :db do
  desc "migrate database"
  task :migrate do
    target = target.to_i if (target = ENV['target'])
    current = current.to_i if (current = ENV['current'])

    DB = Sequel.connect("sqlite://db/app.sqlite3")
    Sequel::Migrator.apply(DB, './db/migrate', target, current)
  end
end</pre>
<p>最新版 (version 2) にする</p>
<pre>$ rake db:migrate</pre>
<p>バージョンを 1 に戻す</p>
<pre>$ rake db:migrate target=3</pre>
<p>わざわざ rake しなくても、コマンドから migrate できます。 -m でマイグレーションファイルを格納しているディレクトリを指定、 -M でバージョンを指定します。</p>
<pre>$ sequel -m ./db/migrate sqlite://db/keyself.db -M 1</pre>
<p>マイグレーションとは関係ありませんが、 model をつくる場合は最低限なものであればこれだけです。</p>
<h4>user.rb</h4>
<pre>class User &lt; Sequel::Model; end</pre>
<p>users テーブルと関連づけられ、様々な操作が行えます。手軽にデータベースを操作したい場合に使っていきたいと思う ORM です。</p>
<p><a href="http://www.pshared.net/diary/20100117.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100110.html#p01">
<link>http://www.pshared.net/diary/20100110.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100110.html#p01" />
<dc:date>2010-01-11T03:54:01+09:00</dc:date>
<title>AIDL インターフェース引数に Parcelable 実装クラスを指定する</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Android</dc:subject>
<description>Android で画面操作を行っているときに電話がかかってくると、処理が停止されてしまいます。しかし停止させず処理を継続させたい場合にはサービスという概念が用意されており、これを利用することで処理をバックエンドで続けてくれるとのこと。 実装方法はいくつかあるのですが、今回は AIDL ファイルに Java インターフェースを定義して、コールバックを受け取れるバインダという種類を選択してみました。なお AIDL ファイルに記述したインターフェースは ADT によって、インターフェースを実装したクラスが自動的に生成されます。 まず AIDL ファイルに定義するインターフェースの引数、戻り値に指定できるものとして以下の制約があるとのことです。  プリミティブ型 String, List, Map, CharSequence, AIDL ファイルに定義したインターフェース Parcelable インターフェースを実装したクラス  新しく Parcelable インターフェースというものが出てきたのですが、すごく適当にいうと Serializable の Android 用みたいなものです。..</description>
<content:encoded><![CDATA[<h3>AIDL インターフェース引数に Parcelable 実装クラスを指定する</h3><p>Android で画面操作を行っているときに電話がかかってくると、処理が停止されてしまいます。しかし停止させず処理を継続させたい場合にはサービスという概念が用意されており、これを利用することで処理をバックエンドで続けてくれるとのこと。</p>
<p>実装方法はいくつかあるのですが、今回は AIDL ファイルに Java インターフェースを定義して、コールバックを受け取れるバインダという種類を選択してみました。なお AIDL ファイルに記述したインターフェースは ADT によって、インターフェースを実装したクラスが自動的に生成されます。</p>
<p>まず AIDL ファイルに定義するインターフェースの引数、戻り値に指定できるものとして以下の制約があるとのことです。</p>
<ul>
<li>プリミティブ型</li>
<li>String, List, Map, CharSequence, AIDL ファイルに定義したインターフェース</li>
<li>Parcelable インターフェースを実装したクラス</li>
</ul>
<p>新しく Parcelable インターフェースというものが出てきたのですが、すごく適当にいうと Serializable の Android 用みたいなものです。 Java の Serializable は冗長なので、 Android ではリモート通信間に使うものには Parcelable インターフェースを実装するルールのようです。</p>
<p>で、今回 Parcelable インターフェースを実装した ValueObject を渡そうとしたところ意外にハマってしまったのでメモしておきます。</p>
<p>example.dto.Hoge クラスが Parcelable インタフェースを実装しているものとします。(インターフェース実装は省略します)</p>
<p>Hoge クラスと同じ example.dto パッケージに Hoge.aidl ファイルを作成します。</p>
<h4>Hoge.aidl</h4>
<pre>package example.dto;

parcelable Hoge;</pre>
<p>ここでは Hoge クラスが parcelable であることを宣言します。</p>
<p>続いてコールバックを受け取るリスナを example.service パッケージに定義します。</p>
<h4>HogeCallbackListener.aidl</h4>
<pre>package example.service;

import example.dto.Hoge;

interface HogeCallbackListener {

    void receive(in Hoge hoge);
}</pre>
<p>ここでは先ほど Hoge.aidl で定義した Hoge クラスを import し、インターフェースの引数に in を指定しました。なお public をつけるとおこられます。これで利用するための準備は整いました。</p>
<p>この後に AndroidManifest ファイルに Service を定義したり、 Activity や Service にコードを記述したりと面倒な作業が待っています。</p>
<h4>参考</h4>
<p><a href="http://developer.android.com/intl/ja/guide/developing/tools/aidl.html">http://developer.android.com/intl/ja/guide/developing/tools/aidl.html</a></p>
<p><a href="http://www.pshared.net/diary/20100110.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100109.html#p01">
<link>http://www.pshared.net/diary/20100109.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100109.html#p01" />
<dc:date>2010-01-10T03:08:03+09:00</dc:date>
<title>WebView と assets 連携</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Android</dc:subject>
<description>Android には WebKit ブラウザが内蔵されていて、 SDK にはそのエンジンを利用した WebView というコンポーネントが提供されています。  使い方は layout に WebView コンポーネントを配置して Activity から WebView インスタンスを取得し、以下のメソッドを呼び出すことで描画が行えます。  WebView#loadUrl WebView#loadData WebView#loadDataWithBaseURL  loadUrl は URL を指定し、 loadData は html 文字列から描画を行うものですが、今回は loadDataWithBaseURL を使いました。というのもローカルに css ファイルを作成して、 html から参照させたかったからです。 [追記] loadUrl でも assets 連携が行えました。 webView.loadUrl(&quot;file:///android_asset/index.html&quot;); [/追記] まずリソースファイルとなる html ファイルおよび css ファイルを作成します。ア..</description>
<content:encoded><![CDATA[<h3>WebView と assets 連携</h3><p>Android には WebKit ブラウザが内蔵されていて、 SDK にはそのエンジンを利用した WebView というコンポーネントが提供されています。 </p>
<p>使い方は layout に WebView コンポーネントを配置して Activity から WebView インスタンスを取得し、以下のメソッドを呼び出すことで描画が行えます。</p>
<ol>
<li>WebView#loadUrl</li>
<li>WebView#loadData</li>
<li>WebView#loadDataWithBaseURL</li>
</ol>
<p>loadUrl は URL を指定し、 loadData は html 文字列から描画を行うものですが、今回は loadDataWithBaseURL を使いました。というのもローカルに css ファイルを作成して、 html から参照させたかったからです。<img class="right" src="http://www.pshared.net/diary/images/20100109_0.png" alt="配置" title="配置" width="202" height="138"></p>
<p>[追記]</p>
<p>loadUrl でも assets 連携が行えました。</p>
<pre>webView.loadUrl("file:///android_asset/index.html");</pre>
<p>[/追記]</p>
<p>まずリソースファイルとなる html ファイルおよび css ファイルを作成します。アプリケーションのルートディレクトリに assets ディレクトリを作成し、その直下に対象のファイルを置きます。</p>
<p>あとやることは Activity から WebView インスタンスを取得し、メソッドで呼び出すだけです。</p>
<pre>webView.loadDataWithBaseURL("file:///android_asset/", html, "text/html", "utf-8", null);</pre>
<p>第一引数に file:///android_asset を指定することで、アプリケーションルートに作成した assets ディレクトリにマッピングが行われます。最後の引数は baseURL の取得がうまく行えなかったときのエラーページを指定するらしいです。今回は内部ファイルにアクセスするので null にしました。</p>
<p>これで assets ディレクトリを基底ディレクトリとし、 html から assets ディレクトリの中にアクセスできるようになりました。</p>
<h4>index.html</h4>
<pre>&lt;link rel="stylesheet" type="text/css" href="./default.css" /&gt;</pre>
<p>それから assets ディレクトリの資源に直接アクセスしたい場合は、 Context#getAssets (Activity) から AssetManager を取得し、 AssetManager#open メソッドから可能です。</p>
<p>今回は html ファイルをローカルに置いて、テンプレートの中身を書き換える形にしてみました。以下コードです。</p>
<h4>Java</h4>
<pre>public class WebViewActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String template = getTemplateHtml("index.html");
        String html = template.replaceAll("%s", "&lt;h1&gt;Hello!&lt;/h1&gt;");

        WebView webView = (WebView) findViewById(R.id.webView);
        webView.loadDataWithBaseURL("file:///android_asset/", html, "text/html", "utf-8", null);
    }

    private String getTemplateHtml(String path) {
        InputStream in = null;
        try {
            in = getAssets().open(path);
            byte[] buffer = IOUtils.read(in); // 自作ユーティリティ
            return new String(buffer, "utf-8");
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {
             IOUtils.close(in);
         }
    }
}</pre>
<h4>HTML</h4>
<pre>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv="content-type" content="text/html; charset=utf-8" /&gt;
    &lt;meta http-equiv="content-script-type" content="text/javascript" /&gt;
    &lt;meta http-equiv="content-style-type" content="text/css" /&gt;
    &lt;link rel="stylesheet" type="text/css" href="./default.css" /&gt;
  &lt;/head&gt;
  &lt;body&gt;%s&lt;/body&gt;
&lt;/html&gt;</pre>
<h4>CSS</h4>
<pre>body {
  margin: 0;
  padding: 0;
  background-color: black;
  color: white;
}</pre>
<p>WebView は JavaScript との連携も用意されていて、色々できそうです。時間を取って追ってみたいコンポーネントでした。</p>
<p><a href="http://www.pshared.net/diary/20100109.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.pshared.net/diary/20100105.html#p01">
<link>http://www.pshared.net/diary/20100105.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.pshared.net/diary/20100105.html#p01" />
<dc:date>2010-01-05T16:30:38+09:00</dc:date>
<title>HTTP Client 4.0 でリダイレクトしないようにする</title>
<dc:creator>Ussy</dc:creator>
<dc:subject>Java</dc:subject>
<description>Apache Commons HTTP Client のバージョン 3.x には HttpMethod#setFollowRedirects があったのですが、 4.x から綺麗に取り除かれています。 4.0 では以下のように HttpParams に設定してあげるとリダイレクトしなくなりました。 HttpParams params = new BasicHttpParams(); params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); ログイン画面にリダイレクトされたときに、リダイレクト先のコンテンツを取得されるのを抑止し、 302 コードが欲しかったのです。 ドキュメント Chapter 5. HTTP client service</description>
<content:encoded><![CDATA[<h3>HTTP Client 4.0 でリダイレクトしないようにする</h3><p>Apache Commons HTTP Client のバージョン 3.x には HttpMethod#setFollowRedirects があったのですが、 4.x から綺麗に取り除かれています。</p>
<p>4.0 では以下のように HttpParams に設定してあげるとリダイレクトしなくなりました。</p>
<pre>HttpParams params = new BasicHttpParams();
params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);</pre>
<p>ログイン画面にリダイレクトされたときに、リダイレクト先のコンテンツを取得されるのを抑止し、 302 コードが欲しかったのです。</p>
<h4>ドキュメント</h4>
<p><a href="http://hc.apache.org/httpcomponents-client/tutorial/html/httpagent.html#d4e1151">Chapter 5. HTTP client service</a></p>
<p><a href="http://www.pshared.net/diary/20100105.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
</rdf:RDF>
