<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C0EER3c5fSp7ImA9WhRRFEk.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856</id><updated>2011-11-28T09:53:26.925+09:00</updated><category term="Mantis" /><category term="Apple" /><category term="python" /><category term="Linux" /><category term="Hadoop" /><category term="Visitors" /><category term="Amazon Web Services" /><title>2606-36J</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://2606-36j.blogspot.com/" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/2606-36J" /><feedburner:info uri="blogspot/2606-36j" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CU4EQ347fyp7ImA9Wx5SFUU.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-8533586207952711476</id><published>2010-08-12T12:21:00.002+09:00</published><updated>2010-08-12T12:31:42.007+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-12T12:31:42.007+09:00</app:edited><title>Twitter account/update_profile_image API</title><content type="html">こんなところで注意喚起しても、って気がしますが、&lt;br /&gt;７月中旬くらいまで動いていた account/update_profile_image APIが突然動かなくなった皆さんへ。&lt;br /&gt;&lt;br /&gt;http://twitter.com/account/update_profile_image.xml&lt;br /&gt;を&lt;br /&gt;http://api.twitter.com/1/account/update_profile_image.xml&lt;br /&gt;に変えると直る可能性が高いと思われます。&lt;br /&gt;&lt;br /&gt;国内外でいろいろなサンプルコードが twitter.com を利用しているため、&lt;br /&gt;TwitterのAPIドキュメントが api.twitter.com を指していても気付かない人が国内外で多数発生。&lt;br /&gt;twitter.comが突然期待通りに動作せず、且つAPIからは200のステータスが返ってきた事で余計に混乱。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-8533586207952711476?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/sj33cYfcuI8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/8533586207952711476/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=8533586207952711476" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/8533586207952711476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/8533586207952711476?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/sj33cYfcuI8/twitter-accountupdateprofileimage-api.html" title="Twitter account/update_profile_image API" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2010/08/twitter-accountupdateprofileimage-api.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEEQn46fSp7ImA9WxBaFUw.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-105903739933773398</id><published>2010-03-25T19:15:00.003+09:00</published><updated>2010-03-25T19:23:23.015+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-25T19:23:23.015+09:00</app:edited><title>Amazon SimpleDBをPythonから使う(2)</title><content type="html">昨日に引き続いてPythonでbotoを使ってSimpleDBを使う。&lt;br /&gt;検索まではうまくできたものの、selectやqueryで検索した時に、じゃあその結果についてるキーは何なのよ、悩んだ結果、&lt;a href="http://code.google.com/p/boto/wiki/SimpleDbIntro"&gt;wiki&lt;/a&gt;に載ってました。。&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;from boto.sdb.connection import SDBConnection&lt;br /&gt;&lt;br /&gt;domain = 'mydomain' # ドメイン名&lt;br /&gt;key = 'abcde' # 一意となるキー名&lt;br /&gt;&lt;br /&gt;# 接続&lt;br /&gt;c = SDBConnection()&lt;br /&gt;# 既存のドメインから探す&lt;br /&gt;d = c.lookup(domain)&lt;br /&gt;&lt;br /&gt;# SimpleDB Query Languageで検索&lt;br /&gt;rs = d.select("select * from `%(domain)s` where 'aaa'='bbb'" % {'domain': domain})&lt;br /&gt;# 戻り値はResultSetオブジェクトへのイテレータなので、nextメソッドで中身を取り出す。&lt;br /&gt;item = rs.next()&lt;br /&gt;&lt;br /&gt;print item.name # キーはコレ&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-105903739933773398?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/9NKSdxjfTng" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/105903739933773398/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=105903739933773398" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/105903739933773398?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/105903739933773398?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/9NKSdxjfTng/amazon-simpledbpython2.html" title="Amazon SimpleDBをPythonから使う(2)" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2010/03/amazon-simpledbpython2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIDQHw6eip7ImA9WxBaFUw.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-4696843633302997250</id><published>2010-03-24T18:59:00.004+09:00</published><updated>2010-03-25T19:22:51.212+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-25T19:22:51.212+09:00</app:edited><title>Amazon SimpleDBをPythonから使う(1)</title><content type="html">今更ながら&lt;a href="http://aws.amazon.com/simpledb/"&gt;SimpleDB&lt;/a&gt;(以下、SDB)を使ってみた。&lt;br /&gt;使用言語はPython。PythonからAWSを使うときには&lt;a href="http://code.google.com/p/boto/"&gt;boto&lt;/a&gt;が便利なのでこれで何とでもなるでしょう、という思い込み。&lt;br /&gt;(S3で使うぶんには特に不満はなかったが、SDBに関しては微妙な部分もある。)&lt;br /&gt;&lt;br /&gt;今回の利用にあたっては、2つのキーを.bashrcに書いて環境変数として利用している。&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;export AWS_ACCESS_KEY_ID=&lt;acces_key&gt;&lt;br /&gt;export AWS_SECRET_ACCESS_KEY=&lt;secret_key&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;まずはデータを入れる方法。&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;from boto.sdb.connection import SDBConnection&lt;br /&gt;&lt;br /&gt;domain = 'mydomain' # ドメイン名&lt;br /&gt;key = 'abcde' # 一意となるキー名&lt;br /&gt;&lt;br /&gt;# 接続&lt;br /&gt;c = SDBConnection()&lt;br /&gt;&lt;br /&gt;# 既存のドメインから探す&lt;br /&gt;d = c.lookup(domain)&lt;br /&gt;if not d:&lt;br /&gt; # 該当するドメインがなかったら新たに作る&lt;br /&gt; d = c.create_domain(domain)&lt;br /&gt;&lt;br /&gt;# 指定したキーで既存のデータを探す&lt;br /&gt;item = d.get_item(key)&lt;br /&gt;if not item:&lt;br /&gt; # 該当するデータがなかったら新たに作る&lt;br /&gt; item = d.new_item(key)&lt;br /&gt;item['aaa'] = 'bbb'&lt;br /&gt;item['ccc'] = {'ddd': 'eee', 'fff': 'ggg'}&lt;br /&gt;# SDBへ保存&lt;br /&gt;item.save()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;lookupやget_itemは該当するデータがなければNoneが返ってくるので、&lt;br /&gt;これを使ってキーのみならずドメインもinsertとupdateを共通化できる。&lt;br /&gt;&lt;br /&gt;次にデータの取得だが、キーを基に一本釣りする場合は、&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;from boto.sdb.connection import SDBConnection&lt;br /&gt;&lt;br /&gt;domain = 'mydomain' # ドメイン名&lt;br /&gt;key = 'abcde' # 一意となるキー名&lt;br /&gt;&lt;br /&gt;# 接続&lt;br /&gt;c = SDBConnection()&lt;br /&gt;# 既存のドメインから探す&lt;br /&gt;d = c.lookup(domain)&lt;br /&gt;# キーを指定してデータを取得&lt;br /&gt;item = d.get_item(key)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;といった感じで簡単。&lt;br /&gt;&lt;br /&gt;ハマったのはqueryを使ってkey-valueのvalueについて条件を付けて検索をする場合。&lt;br /&gt;AWSではSimpleDB Query LanguageというSQLと同じような記述で検索するクエリー言語があるわけですが、botoで使う場合にはselectメソッドが前提らしい。一見似たようなqueryメソッドとかget_with_attributesメソッドは条件の指定方法が全然違ったりする。&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;from boto.sdb.connection import SDBConnection&lt;br /&gt;&lt;br /&gt;domain = 'mydomain' # ドメイン名&lt;br /&gt;key = 'abcde' # 一意となるキー名&lt;br /&gt;&lt;br /&gt;# 接続&lt;br /&gt;c = SDBConnection()&lt;br /&gt;# 既存のドメインから探す&lt;br /&gt;d = c.lookup(domain)&lt;br /&gt;&lt;br /&gt;# SimpleDB Query Languageで検索&lt;br /&gt;rs = d.select("select * from `%(domain)s` where 'aaa'='bbb'" % {'domain': domain})&lt;br /&gt;# 戻り値はResultSetオブジェクトへのイテレータなので、nextメソッドで中身を取り出す。&lt;br /&gt;item = rs.next()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;selectメソッドの方がSQLライクに条件を設定しやすくて良いのですが、ついでにqueryメソッドを使った場合はコチラ。&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;from boto.sdb.connection import SDBConnection&lt;br /&gt;&lt;br /&gt;domain = 'mydomain' # ドメイン名&lt;br /&gt;key = 'abcde' # 一意となるキー名&lt;br /&gt;&lt;br /&gt;# 接続&lt;br /&gt;c = SDBConnection()&lt;br /&gt;# 既存のドメインから探す&lt;br /&gt;d = c.lookup(domain)&lt;br /&gt;&lt;br /&gt;# queryメソッドで検索&lt;br /&gt;rs = d.query("['aaa' = 'bbb']")&lt;br /&gt;# 戻り値はResultSetオブジェクトへのイテレータなので、nextメソッドで中身を取り出す。&lt;br /&gt;item = rs.next()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ドメインを明示しなくて良かったり、一瞬queryメソッドの方が良さそうに見えるのですが、queryメソッドで条件を複数設定したり、order句を付ける方法が今のところ無い気がします。&lt;br /&gt;&lt;br /&gt;これで快適にkey-valueで配列とか辞書型とか放り込んで自由なデータの持ち方ができる！と思い、調子に乗って(?)valueに階層を掘っていったとしても、下の階層はselectメソッドを使っても検索の対象とならないので注意！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-4696843633302997250?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/YWHZcSANFbQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/4696843633302997250/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=4696843633302997250" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/4696843633302997250?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/4696843633302997250?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/YWHZcSANFbQ/amazon-simpledbpython.html" title="Amazon SimpleDBをPythonから使う(1)" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2010/03/amazon-simpledbpython.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UFSX05eip7ImA9WxNVGEo.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-6514637551559087340</id><published>2009-10-30T12:26:00.003+09:00</published><updated>2009-10-30T13:00:18.322+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-30T13:00:18.322+09:00</app:edited><title>CentOS5.3のAMI作成（再び）</title><content type="html">Amazon EC2でサーバを構築する際のベースには以前作ったCentOS5.3のイメージを使用しているのですが、相変わらずKernelが2.6.18だったり、ディスク容量が1GBだったりして使い勝手が良くないために手直しすることにしました。&lt;br /&gt;実際にはKernelは起動時にAmazonが提供しているAKIを選択できるのですが、選ぶ作業も地味に煩わしいのでFedra用と思われる2.6.21をデフォルト選択するようにしつつ、ディスク容量は/(root)ディスクの最大容量10GBに。&lt;br /&gt;作っている途中で作業を誤って元々作ってあったCentOS5.3のイメージをS3上で上書きして駄目にしたりしましたが無事に起動が確認できたのでpublicに。&lt;br /&gt;これまで使っていた2.6.18のカーネルと比べて違うのは、提供されているモジュールの種類が増えているのが一番大きいところ。モジュール群も/lib/modules以下に展開済みなのですぐにmodprobeできます。難点はAMIのサイズが大きくなったので起動に時間がかかるところでしょうか。&lt;br /&gt;&lt;br /&gt;AMI ID:ami-d36182ba&lt;br /&gt;Manifest: tmhrnskw.com/AMI/CentOS5.3-i386.manifest.xml&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-6514637551559087340?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/2DB5XRQqeEs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/6514637551559087340/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=6514637551559087340" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/6514637551559087340?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/6514637551559087340?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/2DB5XRQqeEs/centos53ami.html" title="CentOS5.3のAMI作成（再び）" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/10/centos53ami.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcNQHg_cSp7ImA9WxNXEkU.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-8888549535674456768</id><published>2009-09-30T11:41:00.002+09:00</published><updated>2009-09-30T12:58:11.649+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-30T12:58:11.649+09:00</app:edited><title>TDA7491KITの組み立て</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SsLF4HvMsjI/AAAAAAAAAQU/7slv1-O-LiI/s1600-h/IMG_0045.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SsLF4HvMsjI/AAAAAAAAAQU/7slv1-O-LiI/s400/IMG_0045.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5387085672228893234" /&gt;&lt;/a&gt;&lt;br /&gt;Arduinoをやるにせよ、電子工作経験が少ない私としては組込み分野というのはわからないことだらけなので基本に立ち返っていろいろ勉強してみる事にしました。そして電子工作の初歩といえばアンプでしょ、とあまり根拠のないところから始めてみることに。&lt;br /&gt;&lt;br /&gt;「そもそもアンプって増幅させる装置ということでしょ？プレーヤーのボリューム大きくすれば音量なんて大きくなるのに、それを作ることの意味ってイマイチよくわからない」というあたりからスタートしているのでいろいろ調べれば調べるほどにこれまでの無知を思い知らされます。&lt;br /&gt;&lt;br /&gt;そもそも個人的には自宅でのアンプ需要ってあまりないのだけれど、作る以上は方向性を決めなければいけません。最近は専ら買ったCDをiTunesで取り込んでiPodで聴いている事が多いので、CDプレーヤを用意するよりはiPodをソースとした方が使いやすい。となれば&lt;a href="http://www.bose.co.jp/jp_jp?url=/consumer_audio/multimedia_speakers/for_your_ipod/index.jsp"&gt;BOSEのこういうの&lt;/a&gt;とかiPod Hi-Fiをイメージして音楽を再生しつつ充電もできるものにしようかと。&lt;br /&gt;&lt;br /&gt;アンプ自体についてはいろいろ調べてみたところ、ICにもいろいろ種類があってオペアンプとかパワーアンプとかあるらしいですが、パワーアンプのICを使えばできそうだと思って買い出しへ。ところが事前に調べたICが秋葉原で探しまわっても売ってない！秋葉原で電子工作のパーツが見つからないという事態を1ミリも想定していなかったので、とりあえずスピーカーユニットだけ買って再検討。&lt;br /&gt;&lt;br /&gt;スピーカーユニットは自作派の（たぶん）定番FOSTEX。丁度新製品が出た直後くらいだったようで、よくわからないけれど今後の入手性を考えて新製品FE126Enをチョイス。45Wまで出せるそうですが、そんなことをしたら近所から苦情が来るでしょう。とりあえず下手をしても壊れてしまわないように安全マージンを多めに取ったつもりで。&lt;br /&gt;&lt;br /&gt;再びアンプですが、どうやら最近のトレンドは事前に調べた内容とは違うようで、D級アンプとかオーディオ用のオペアンプを使っているようです。真空管はずっと根強い人気があるようですが、ここはICにこだわって。再び秋葉原を探しまわるものの、D級アンプ単体で売られている状況は見られず、オペアンプはイマイチ区別がつかないのでキット頼りに方向転換。初心者だし。&lt;br /&gt;&lt;br /&gt;若松通商にてカマデンのTDA7491KITと若松通商のTA2020-020/KIT、マルツパーツ館でトラ技2008年3月号のD級アンプキットを買ってきました。３つも必要ないといえばそれまでですが、いろいろ数をこなして見えてくる事もあろうかと。&lt;br /&gt;&lt;br /&gt;とりあえず一番簡単そう（というか既に実装済み部品の多い）カマデンTDA7491KITに着手。取説通りに部品をハンダ付けして手元にあった古いイヤホンを分解して接続、スピーカーユニットもそのままつないでみたのが冒頭の画像。特にトラブルもなくすんなり音が出ました。音の善し悪しはスピーカーがこの状態なのでどうこう言える筈もなく。&lt;br /&gt;&lt;br /&gt;キットを使ってすんなり音が出たとはいえ、最初に鳴った時はちょっとテンション上がります。&lt;br /&gt;スピーカーをフルレンジから２Wayに変更したり、アンプ部分を気分で取り替えたりアップグレードしたりできるのは自作ならではかもしれません。ハイエンドはキリがないオーディオの世界ですから、自作を前提とするなどの制約を付けて楽しむのが自分には丁度良い気がします。&lt;br /&gt;&lt;br /&gt;とりあえず音は出たのでスピーカーユニットをちゃんと箱に詰めたり、iPodのドック接続端子からLine出力を取ってくるのを次のフェーズとします。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-8888549535674456768?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/fq65MmcrCAw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/8888549535674456768/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=8888549535674456768" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/8888549535674456768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/8888549535674456768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/fq65MmcrCAw/tda7491kit.html" title="TDA7491KITの組み立て" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SsLF4HvMsjI/AAAAAAAAAQU/7slv1-O-LiI/s72-c/IMG_0045.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/09/tda7491kit.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEARXY-fip7ImA9WxNTGE8.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-7844543385116147253</id><published>2009-08-21T12:35:00.003+09:00</published><updated>2009-08-21T13:07:24.856+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-21T13:07:24.856+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Amazon Web Services" /><title>CentOS5.3のAMI作成(x86_64版)</title><content type="html">昨日の&lt;a href="http://2606-36j.blogspot.com/2009/08/centos53ami.html"&gt;i386版&lt;/a&gt;に加えてx86_64版を作りました。&lt;br /&gt;&lt;br /&gt;AMI ID: ami-2397774a&lt;br /&gt;Manifest: tmhrnskw.com/AMI/CentOS5.3-x86_64.manifest.xml&lt;br /&gt;&lt;br /&gt;構成はi386版と一緒。&lt;br /&gt;これでlargeインスタンスも安心。&lt;br /&gt;&lt;br /&gt;このようなAMIを何故わざわざ作っているのかと言うと、Amazon EC2にはAmazon謹製のCentOSイメージがないためRightScale等のサードパーティ製のものを利用することになるのですが、サードパーティ製のものは独自のスクリプトが仕込まれていたり、不要なサービスが起動していたりするので、最小インストール構成のCentOSを自分自身が求めていたためです。&lt;br /&gt;&lt;br /&gt;他のエントリにも書いていますが、&lt;br /&gt;・# yum groupinstall Core でインストールされるパッケージ&lt;br /&gt;・内部の/etc/rc.localスクリプトの実行に必要なパッケージ（スクリプトの内容はAmazonのドキュメントにあるもの）&lt;br /&gt;・ec2-ami-toolsの実行に必要なパッケージ&lt;br /&gt;・screen&lt;br /&gt;これらのみインストールしているため予め起動しているプロセスも非常に少なく、makeやgcc等もない状態です。タイムゾーンすらJPTではありません。&lt;br /&gt;&lt;br /&gt;公開されているAMIの中にはシンプルな構成のものよりは「インスタンスを立ち上げればすぐに○○ができますよ！」といったサトウのごはん的なものが多いようですが、サーバ構築ができる人がカスタマイズのベースに使っていただければ、と思って公開しています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-7844543385116147253?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/l6Ysm20k7zo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/7844543385116147253/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=7844543385116147253" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/7844543385116147253?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/7844543385116147253?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/l6Ysm20k7zo/centos53amix8664.html" title="CentOS5.3のAMI作成(x86_64版)" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/08/centos53amix8664.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YMQnc5fyp7ImA9WxNVGEo.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-5746477423986084530</id><published>2009-08-20T12:40:00.005+09:00</published><updated>2009-10-30T12:59:43.927+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-30T12:59:43.927+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Amazon Web Services" /><title>CentOS5.3のAMI作成</title><content type="html">CentOS5.3がリリースされてからしばらく経ちますが、&lt;a href="http://2606-36j.blogspot.com/2009/02/centos52ami.html"&gt;5.2の時&lt;/a&gt;と同様にAMIを作りました。&lt;br /&gt;&lt;br /&gt;AMI ID: ami-0d907064(※削除しました 新AMI IDは &lt;a href="http://2606-36j.blogspot.com/2009/10/centos53ami.html"&gt;ami-d36182ba&lt;/a&gt;）&lt;br /&gt;Manifest: tmhrnskw.com/AMI/CentOS5.3-i386.manifest.xml&lt;br /&gt;&lt;br /&gt;今回もi386版をとりあえず作成。&lt;br /&gt;カスタマイズの元イメージ用なので、最小インストールと言える構成になっています。&lt;br /&gt;kernelはAmazonの提供している2.6.18、対応するmoduleもイメージ内に展開済みです。&lt;br /&gt;&lt;br /&gt;個人的にCentOS5.3の嬉しいところとしては、サードパーティのパッケージを使わなくてもPHP5とMySQL5が使えるようになっているあたりでした。&lt;br /&gt;インスタンスを立ち上げてSSHでログイン後、&lt;br /&gt;# yum install php mysql-server&lt;br /&gt;# /etc/init.d/httpd start&lt;br /&gt;# /etc/init.d/mysqld start&lt;br /&gt;でLAMP構成が動き出すから楽です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-5746477423986084530?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/MaM5IUXpasc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/5746477423986084530/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=5746477423986084530" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/5746477423986084530?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/5746477423986084530?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/MaM5IUXpasc/centos53ami.html" title="CentOS5.3のAMI作成" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/08/centos53ami.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMCR3k6fip7ImA9WxJbGEs.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-3796840896680240532</id><published>2009-07-29T15:54:00.005+09:00</published><updated>2009-07-29T18:41:06.716+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-29T18:41:06.716+09:00</app:edited><title>Getting Started with Arduino</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T7Pt3YYwCZA/SnAYdTHo41I/AAAAAAAAAQM/MIvTsMjQNr8/s1600-h/IMG_0027.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_T7Pt3YYwCZA/SnAYdTHo41I/AAAAAAAAAQM/MIvTsMjQNr8/s400/IMG_0027.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5363814047825847122" /&gt;&lt;/a&gt;&lt;br /&gt;Arduino Duemilanovaが届いたのでまずはお約束なLED点灯から。&lt;br /&gt;何せ電子工作って初めてなもので。&lt;br /&gt;&lt;br /&gt;とは言え&lt;a href="http://arduino.cc/"&gt;Arduinoサイト&lt;/a&gt;からIDEとドライバのセットを&lt;a href="http://arduino.cc/en/Main/Software"&gt;ダウンロード&lt;/a&gt;＆インストールして本体をUSBケーブルと繋いでコードを書いて実行するだけなのですが。&lt;br /&gt;&lt;br /&gt;IDEは起動時に例外が出て怒られたので32bitモードで起動するように対処。&lt;br /&gt;&lt;br /&gt;オライリーから出てる「Arduinoをはじめよう」を倣ってLEDの点滅。&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;#define LED 13&lt;br /&gt;&lt;br /&gt;void setup()&lt;br /&gt;{&lt;br /&gt;  pinMode(LED, OUTPUT);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void loop()&lt;br /&gt;{&lt;br /&gt;  digitalWrite(LED, HIGH);&lt;br /&gt;  delay(1000);&lt;br /&gt;  digitalWrite(LED, LOW);&lt;br /&gt;  delay(1000);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ちなみにArduino Duelilanova本体に付いているLEDで動作確認ができるところを&lt;br /&gt;早とちりしてわざわざ5個入りLEDを買ってしまいました。&lt;br /&gt;LEDのアノード（足の長い方）をデジタルの13番に、カソード（足の短い方）をGNDに差し込んで上記のコードを実行しても同じように点滅してくれます。&lt;br /&gt;&lt;br /&gt;で、何作るかなぁ。&lt;br /&gt;しばらくはいろいろなセンサーを繋げてみたりするつもりです。&lt;br /&gt;まずは情報の多いWiiヌンチャクあたりから。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-3796840896680240532?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/A5dfand2GH8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/3796840896680240532/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=3796840896680240532" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3796840896680240532?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3796840896680240532?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/A5dfand2GH8/getting-started-with-arduino.html" title="Getting Started with Arduino" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_T7Pt3YYwCZA/SnAYdTHo41I/AAAAAAAAAQM/MIvTsMjQNr8/s72-c/IMG_0027.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/07/getting-started-with-arduino.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcBRHszeip7ImA9WxJbE08.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-5199447851937447144</id><published>2009-07-23T12:10:00.003+09:00</published><updated>2009-07-23T12:34:15.582+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-23T12:34:15.582+09:00</app:edited><title>307 Temporary Redirect</title><content type="html">わかっているようであまりわかっていない物事が多いなぁと思った話。&lt;br /&gt;&lt;br /&gt;「Locationヘッダでリダイレクトさせる時にPOSTで値を渡せるのか」&lt;br /&gt;&lt;br /&gt;これまであまりそういった事をやった事が無いので思わず&lt;br /&gt;「GETじゃないと無理」&lt;br /&gt;と答えたものの、QUERY_STRINGを引き継げればできるんじゃないかと思って&lt;br /&gt;調べ始めたところ、そのようなことをしなくてもHTTPステータスコード"307"で&lt;br /&gt;POSTされた値を引き継いで任意のURLにリダイレクトさせることができました。&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;header('Location: http://www.example.com/redirect/target/', true, 307);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;但しこの方法、ブラウザによっては警告のダイアログが表示されてしまいます。&lt;br /&gt;&lt;br /&gt;そもそも（私だけかも知れませんが）あまり聞き慣れないこのステータスコード"307"。&lt;br /&gt;HTTP1.1で追加されたステータスコードらしいのですが、&lt;br /&gt;そもそもHTTP/1.0のステータスコード"302 Moved Temporarily"はPOSTされた値を引き継がない&lt;br /&gt;クライアントが多かったためHTTP/1.1でステータスコードをわける事になったの&lt;a href="http://www.onflow.jp/cyano/archives/161"&gt;だそうです。&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ちなみにHTTP/1.1の"302"は"Found"、&lt;br /&gt;HTTP/1.0では意味を持たなかった"303"は"See Other"に変わっている訳ですが、&lt;br /&gt;HTTP/1.1のRFCができたのは1999年6月なので、このことを10年も経って初めて知るあたり&lt;br /&gt;己の勉強不足を感じます。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-5199447851937447144?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/DqQiWODnz3Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/5199447851937447144/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=5199447851937447144" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/5199447851937447144?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/5199447851937447144?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/DqQiWODnz3Y/307-temporary-redirect.html" title="307 Temporary Redirect" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/07/307-temporary-redirect.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQCRnw6fyp7ImA9WxJQFU0.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-2078760920508055943</id><published>2009-05-28T18:14:00.005+09:00</published><updated>2009-05-28T18:36:07.217+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T18:36:07.217+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>ClientFormによるmultipart/form-dataなPOST</title><content type="html">pythonからスクリプトからWebサーバへファイルをmultipart/form-dataでPOSTする方法その２。&lt;br /&gt;というか、前回のpycurlを使ったスクリプトが上手くいかなかったりしたのでリトライ。&lt;br /&gt;&lt;br /&gt;今回は&lt;a href="http://wwwsearch.sourceforge.net/ClientForm/"&gt;ClientForm&lt;/a&gt;を使った方法。&lt;br /&gt;ClientFormの特徴としてFormのあるページをparseしてオブジェクトを生成するところ。&lt;br /&gt;ページの取得とか、POSTを行う部分はurllib2の助けを借りるのですが。&lt;br /&gt;&lt;br /&gt;Form&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;form action="http://example.com/post.cgi" method="POST" enctype="multipart/form-data"&amp;gt;&lt;br /&gt;      &amp;lt;input type="text" name="text_field"&amp;gt;&lt;br /&gt;      &amp;lt;input type="file" naem="image"&amp;gt;&lt;br /&gt;    &amp;lt;/form&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Script&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;import urllibs2&lt;br /&gt;import ClientForm&lt;br /&gt;&lt;br /&gt;request = urllib2.Request("http://example.com/form.html")&lt;br /&gt;response = urllib2.urlopen(request)&lt;br /&gt;forms = ClientForm.ParseResponse(response, backwards_compat=False)&lt;br /&gt;response.close()&lt;br /&gt;&lt;br /&gt;form = forms[0]&lt;br /&gt;form['text_field'] = 'Test Text Data'&lt;br /&gt;form.add_file(open('image.jpg','rb'))&lt;br /&gt;&lt;br /&gt;urllib2.urlopen(form.click())&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-2078760920508055943?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/f5Gt_nrxNq0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/2078760920508055943/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=2078760920508055943" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/2078760920508055943?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/2078760920508055943?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/f5Gt_nrxNq0/clientformmultipartform-datapost.html" title="ClientFormによるmultipart/form-dataなPOST" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/05/clientformmultipartform-datapost.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4GQ3Y7eip7ImA9WxJRGUs.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-1013071938237729321</id><published>2009-05-22T09:51:00.005+09:00</published><updated>2009-05-22T12:28:42.802+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-22T12:28:42.802+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Pythonからmultipart/form-dataでPOSTする</title><content type="html">pythonスクリプトからWebサーバへファイルをmultipart/form-dataでPOSTする方法を探して右往左往。結局一番シンプルなのはpycurlでした。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;import pycurl&lt;br /&gt;&lt;br /&gt;c = pycurl.Curl()&lt;br /&gt;c.setopt(c.URL, "http://sample.com/post.cgi")&lt;br /&gt;c.setopt(c.POST, 1)&lt;br /&gt;c.setopt(c.HTTPPOST, [('text_field', 'Test Text Data'),&lt;br /&gt;                      ('image', (c.FORM_FILE, 'test.jpg'))])&lt;br /&gt;c.perform()&lt;br /&gt;c.close()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;そもそも設定できるオプション(setopt)の項目すらきちんと把握できてないのですが、curlのpython用インターフェースなので知ってると便利。&lt;br /&gt;&lt;br /&gt;multipart/form-dataならurllib2があるじゃないか、という向きもありますが、ファイルのreadの部分でUnicodeDecodeErrorとか言われて萎えた。open('test.jpg','rb')で開いたものをUnicodeDecodeErrorってちょっと理不尽に感じたので。&lt;br /&gt;&lt;br /&gt;たぶん自分の努力が足りてないせいなんでしょうけれども。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-1013071938237729321?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/hcdu31QFips" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/1013071938237729321/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=1013071938237729321" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/1013071938237729321?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/1013071938237729321?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/hcdu31QFips/pythonmultipartform-datapost.html" title="Pythonからmultipart/form-dataでPOSTする" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/05/pythonmultipartform-datapost.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQFSH04cSp7ImA9WxJTEkQ.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-2171351721897615894</id><published>2009-04-16T11:14:00.016+09:00</published><updated>2009-04-21T15:11:59.339+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-21T15:11:59.339+09:00</app:edited><title>MantisのPluginを作ってみる(2)</title><content type="html">&lt;a href="http://2606-36j.blogspot.com/2009/04/mantisplugin.html"&gt;前回&lt;/a&gt;はMantisのプラグイン管理に表示されるだけで機能としては何もないプラグインを作りましたが、今回からはMantisを要求管理システムとして使用できるようなプラグインを作成します。&lt;br /&gt;&lt;br /&gt;Mantisに要求を登録する場合はメニューの「登録」から行うのが一般的ですが、元々がバグ管理システムなので社内で何らかの申請書を提出する場合にはどこに何を記入したら良いのかユーザが迷ってしまいます。&lt;br /&gt;またユーザの思いのままに自由なフォーマットで登録された要求は、その要求を判断・処理する側にとっても作業しづらいため、同様の要求はある程度統一されたフォーマットで登録して欲しいものです。&lt;br /&gt;&lt;br /&gt;この点を解決するためにプラグインでカスタムフォームを作り、社内の各種申請フォームをまとめて行きたいと思います。&lt;br /&gt;まずはプラグインの名称をApplicationFormとし、プラグインを置く場所を作成します。&lt;br /&gt;&lt;br /&gt;# mkdir plugins/ApplicationForm&lt;br /&gt;# vi plugins/ApplicationForm/ApplicationForm.php&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;require_once(config_get('classpath') . 'MantisPlugin.class.php');&lt;br /&gt;&lt;br /&gt;class ApplicationFormPlugin extends MantisPlugin {&lt;br /&gt;&lt;br /&gt;// プラグインについての情報を記載&lt;br /&gt;function register() {&lt;br /&gt;    $this-&gt;name = 'ApplicationForm';&lt;br /&gt;    $this-&gt;description = 'Application form for work flows.';&lt;br /&gt;    $this-&gt;page = '';&lt;br /&gt;&lt;br /&gt;    $this-&gt;version = '0.1';&lt;br /&gt;    $this-&gt;requires = array(&lt;br /&gt;        'MantisCore' =&gt; '1.2.0',&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;    $this-&gt;author = 'nskw';&lt;br /&gt;    $this-&gt;contact = 'nskw@sample.com';&lt;br /&gt;    $this-&gt;url = '';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// 利用するイベントとメソッドを紐付け&lt;br /&gt;function hooks() {&lt;br /&gt;    $hooks = array(&lt;br /&gt;        'EVENT_MENU_MAIN' =&gt; 'MainMenu',&lt;br /&gt;    );&lt;br /&gt;    return $hooks;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// メインメニューでの表示内容を返す&lt;br /&gt;function MainMenu() {&lt;br /&gt;    return array('&amp;lt;a href="'. plugin_page('application_menu') .'"&amp;gt;'. plugin_lang_get('title') .'&amp;lt;/a&amp;gt;');&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;前回と比べるとイベントをフックさせる部分について加わったくらいですが、メインメニューへの項目が追加されます。&lt;br /&gt;plugin_page()の引数はこのプラグイン内のPHPファイル(pages/application_menu.php)を呼び出すためのpathを返します。plugin_lang_get()はプラグイン内の言語ファイルから該当する文字列を返します。&lt;br /&gt;&lt;br /&gt;メインメニューに追加した項目をクリックした際に表示するページを作ります。&lt;br /&gt;&lt;br /&gt;# mkdir plugins/ApplicationForm/pages&lt;br /&gt;# vi plugins/ApplicationForm/pages/application_menu.php&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;// Mantisの共通ヘッダ部分を表示します&lt;br /&gt;html_page_top1();&lt;br /&gt;html_page_top2();&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;div align="center"&amp;gt;&lt;br /&gt;&amp;lt;table class="width90" cellspacing="1"&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt;&lt;br /&gt; &amp;lt;td class="form-title"&amp;gt;&amp;lt;?php echo plugin_lang_get('title'); ?&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;// pagesディレクトリ内で"application_form_"で始まるPHPファイルを申請フォームとしてリストアップします&lt;br /&gt;$handle = opendir(dirname(__FILE__));&lt;br /&gt;while(false !== ($file = readdir($handle))){&lt;br /&gt; if(preg_match("/^(application_(form_.+))\.php/",$file, $matches)){&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;tr class="row-1"&amp;gt;&lt;br /&gt; &amp;lt;td class="category" width="30%"&amp;gt;&amp;lt;a href="plugin.php?page=ApplicationForm/&amp;lt;?php echo $matches[1]; ?&amp;gt;"&amp;gt;&amp;lt;?php echo plugin_lang_get( $matches[2] . "_title" ); ?&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt; &amp;lt;td width="70%"&amp;gt;&amp;lt;?php echo plugin_lang_get( $matches[2] . "_description" ); ?&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;// Mantisの共通フッタ部分を表示します&lt;br /&gt;html_page_bottom1( __FILE__ );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ここまでで使用しているプラグイン用言語ファイルを作ります。&lt;br /&gt;以下では英語表記の言語ファイルを作っていますが、日本語(UTF8)の場合はstrings_japanese.txtという名前で作ります。&lt;br /&gt;表示言語の切り替えはユーザの言語環境設定に基づき、該当する言語ファイルがなければ英語の言語ファイルを読み込むようです。勿論、多言語化が不要でしたらPHPファイルに直接書き込む方法も採れます。&lt;br /&gt;&lt;br /&gt;# mkdir plugins/ApplicationForm/lang&lt;br /&gt;# vi plugins/ApplicationForm/lang/strings_english.txt&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;$s_plugin_ApplicationForm_title = 'Application Menu';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これで下のように新しいメニューが追加されました。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T7Pt3YYwCZA/Se1jOQI_L7I/AAAAAAAAAPI/Nah09sjG9cw/s1600-h/%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3+2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 256px; height: 74px;" src="http://4.bp.blogspot.com/_T7Pt3YYwCZA/Se1jOQI_L7I/AAAAAAAAAPI/Nah09sjG9cw/s320/%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3+2.png" alt="" id="BLOGGER_PHOTO_ID_5327023030751145906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;今回はとりあえず申請メニューを表示するところまで。&lt;br /&gt;ここまででpages以下のPHPファイルを呼び出す方法がわかったので、次回は実際に申請フォームを作って要求の登録まで行います。呼び出されたPHPファイルは共通ヘッダ／フッタすら明示的に呼び出さないと表示されないのでAjaxなんかもプラグインに組み込みやすいですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-2171351721897615894?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/iWxROSCFnTU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/2171351721897615894/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=2171351721897615894" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/2171351721897615894?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/2171351721897615894?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/iWxROSCFnTU/mantisplugin2.html" title="MantisのPluginを作ってみる(2)" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_T7Pt3YYwCZA/Se1jOQI_L7I/AAAAAAAAAPI/Nah09sjG9cw/s72-c/%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3+2.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/04/mantisplugin2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkANQnYzcCp7ImA9WxVaGEk.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-7453811835109805430</id><published>2009-04-14T16:14:00.011+09:00</published><updated>2009-04-16T11:26:33.888+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-16T11:26:33.888+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mantis" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>MantisのPluginを作ってみる(1)</title><content type="html">&lt;a href="http://www.mantisbt.org/"&gt;Mantis&lt;/a&gt;はBTS(BugTrackingSystem)ですが、単にバグを管理するだけでなく&lt;br /&gt;ワークフローに入れてみると比較的小さな会社でも組織化させるにあたって有効です。&lt;br /&gt;丁度前に勤めていた会社でそのような使い方をしていたのですが、元々のコードを&lt;br /&gt;かなりいじったものを使っていたのでバージョンアップは時の運。&lt;br /&gt;&lt;br /&gt;今時のMantis 1.2系ではプラグインで拡張できるようになっているらしいので、&lt;br /&gt;しばらくコレをさわってみることにしました。&lt;br /&gt;&lt;br /&gt;とりあえずはMantis 1.2.0a3をダウンロードしてセットアップ。&lt;br /&gt;デフォルトではPluginは /path/to/mantis/plugins/ 以下に置くことになっています。&lt;br /&gt;試しにTestingPluginを作成してみます。&lt;br /&gt;&lt;br /&gt;# mkdir plugins/Testing&lt;br /&gt;# vi plugins/Testing.php&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// 基となるクラスファイルを読み込みます&lt;br /&gt;require_once( config_get( 'class_path' ) . 'MantisPlugin.class.php' );&lt;br /&gt;&lt;br /&gt;// MantisPluginを継承してクラスを作成&lt;br /&gt;class TestingPlugin extends MantisPlugin {&lt;br /&gt;    // PluginをMantisに認識させるのに必要な情報をregisterメソッドで定義します&lt;br /&gt;    function register( ) {&lt;br /&gt;        $this-&gt;name = 'Test'; // Pluginの名称&lt;br /&gt;        $this-&gt;description = 'Just a testing plugin. under construnction.'; // Pluginの説明&lt;br /&gt;        $this-&gt;page = '';&lt;br /&gt;&lt;br /&gt;        $this-&gt;version = '0.1'; // このPluginのバージョン&lt;br /&gt;        $this-&gt;requires = array(&lt;br /&gt;            'MantisCore' =&gt; '1.2.0',&lt;br /&gt;        ); // 依存するPluginとそのバージョン&lt;br /&gt;&lt;br /&gt;        $this-&gt;author = 'vegao'; // 作成者&lt;br /&gt;        $this-&gt;contact = 'vegao@sample.com'; // 作成者への連絡先&lt;br /&gt;        $this-&gt;url = ''; // 作成者のURL&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;単にPluginとして認識されるようにregisterのみ記述しているだけですが、&lt;br /&gt;コレでも一応「システム管理」の「プラグイン管理」に表示されます。&lt;br /&gt;&lt;br /&gt;ドキュメントを見る限り、MantisのPluginの仕組みはEventがどーのこーのと書かれていますが&lt;br /&gt;徐々に紐解いて行くことにします。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-7453811835109805430?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/7oQJf9ve95k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/7453811835109805430/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=7453811835109805430" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/7453811835109805430?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/7453811835109805430?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/7oQJf9ve95k/mantisplugin.html" title="MantisのPluginを作ってみる(1)" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/04/mantisplugin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMGSHk6cCp7ImA9WxVaFk0.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-3541036395418384856</id><published>2009-04-08T11:56:00.017+09:00</published><updated>2009-04-13T14:27:09.718+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-13T14:27:09.718+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Hadoop" /><title>Hadoop Cluster Setup（和訳）</title><content type="html">&lt;a href="http://hadoop.apache.org/core/docs/current/cluster_setup.html"&gt;Hadoop Cluster Setup&lt;/a&gt;の日本語超訳版。まだ途中なんでまた後で直す予定。&lt;br /&gt;---&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;1.目的&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;このドキュメントではインストール方法、僅か数ノードから数千ノードによる非常に大規模な構成まで組めるHadoopクラスタの設定と運用について説明しています。&lt;br /&gt;&lt;br /&gt;Hadoopを始めるにはまず、単一のコンピュータにHadoopをインストールしてみるのが良いでしょう。(参照：&lt;a href="http://hadoop.apache.org/core/docs/current/quickstart.html"&gt;Hadoop Quick Start&lt;/a&gt;）&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;2.事前に必要なもの&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;クラスターの各ノードに&lt;a href="http://hadoop.apache.org/core/docs/current/quickstart.html#PreReqs"&gt;必要なソフトウェア&lt;/a&gt;がインストールされていること&lt;/li&gt;&lt;li&gt;Hadoopソフトウェアの&lt;a href="http://hadoop.apache.org/core/docs/current/quickstart.html#Download"&gt;ダウンロード&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;3.インストール&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hadoopクラスタをインストールするためにクラスタの各ノードでソフトウェアを解凍します。&lt;br /&gt;&lt;br /&gt;通常はクラスタ内の１台のコンピュータをNanmeNodeとJobTrackerとして排他的に扱います。これらがマスタとなります。&lt;br /&gt;クラスタ内の残りのコンピュータはDataNode兼TaskTrackerとして動作します。これらがスレーブとなります。&lt;br /&gt;&lt;br /&gt;解凍したディレクトリをHADOOP_HOMEと呼びます。クラスタ内の全てのコンピュータはたいてい同じHADOOP_HOMEとします。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;4.設定&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;以下のセクションにてHadoopクラスタの設定方法を説明します。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4.1.設定ファイル&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hadoopの設定はconfディレクトリ内の２つの重要な設定ファイルで行われます。&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://hadoop.apache.org/core/docs/current/hadoop-default.html"&gt;hadoop-default.xml&lt;/a&gt; - 読み取り専用のデフォルト設定&lt;/li&gt;&lt;li&gt;hadoop-site.xml - サイト固有の設定&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Hadoopフレームワークがこれらの設定ファイルによってどのように動作するのか詳しく知るには&lt;a href="http://hadoop.apache.org/core/docs/current/api/org/apache/hadoop/conf/Configuration.html"&gt;こちら&lt;/a&gt;を参照してください。&lt;br /&gt;&lt;br /&gt;また、conf/hadoop-env.shにサイト固有の値を書き入れる事でbinディレクトリ内のスクリプトの動作をコントロールする事ができます。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4.2.サイト設定&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Hadoopクラスタの設定をするためにHadoopデーモンがうまく動作するように環境設定をする必要があります。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;HadoopデーモンはNameNode/DataNode、JobTracker/TaskTrackerに分類されます。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;4.2.1.Hadoopデーモンの環境を設定する&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;管理者はconf/hadoop-env.shスクリプトでHadoopデーモンプロセスのためにサイト固有のカスタマイズをする必要があります。&lt;br /&gt;&lt;br /&gt;少なくとも各ノードでJAVA_HOMEの設定が正しいか確認するべきです。&lt;br /&gt;&lt;br /&gt;管理者はそれぞれのデーモンが使うHADOOP_*_OPTSを設定する事ができます。各オプションについては以下の通りです。&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Daemon&lt;/th&gt;&lt;th&gt;Configure Options&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;NameNode&lt;/td&gt;&lt;td&gt;HADOOP_NAMENODE_OPTS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DataNode&lt;/td&gt;&lt;td&gt;HADOOP_DATANODE_OPTS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SecondaryNamenode&lt;/td&gt;&lt;td&gt;HADOOP_SECONDARYNAMENODE_OPTS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;JobTracker&lt;/td&gt;&lt;td&gt;HADOOP_JOBTRACKER_OPTS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TaskTracker&lt;/td&gt;&lt;td&gt;HADOOP_TASKTRACKER_OPTS&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;例えば、NamenodeがparallelGCを使うように設定したい場合には以下の設定をhadoop-env.shに書き加えます。&lt;br /&gt;export HADOOP_NAMENODE_OPTS="-XX:+UseParallelGC ${HADOOP_NAMENODE_OPTS}"&lt;br /&gt;&lt;br /&gt;他に便利な設定パラメータとして設定できるものはこれらがあります。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;HADOOP_LOG_DIR - デーモンのログファイル出力先を指定します。指定されたディレクトリがなければ自動的に作成されます。&lt;/li&gt;&lt;li&gt;HADOOP_HEAPSIZE - 使用できるヒープサイズの最大量を"1000MB"のようにMBで指定できます。Hadoopデーモンのヒープサイズに指定されます。デフォルトでは1000MBです。&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span&gt;4.2.2.Hadoopデーモンの設定&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;このセクションではconf/hadoop-site.xmlで指定できるHadoopクラスタにとって重要なパラメタについて取り扱います。&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;th&gt;Notes&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;fs.default.name&lt;/td&gt;&lt;td&gt;NameNodeのURI&lt;/td&gt;&lt;td&gt;hdfs://hostname/&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.job.tracker&lt;/td&gt;&lt;td&gt;JobTrackerのHostnameまたはIPアドレスとPort番号&lt;/td&gt;&lt;td&gt;host:port&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;dfs.name.dir&lt;/td&gt;&lt;td&gt;ローカルファイルシステム上でNameNodeが名前空間の保存やトランザクションログを保存するディレクトリ&lt;/td&gt;&lt;td&gt;カンマ区切りのディレクトリのリストであった場合、冗長性のため全てのディレクトリにデータが複製されます。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;dfs.data.dir&lt;/td&gt;&lt;td&gt;カンマ区切りのリストに指定されたDataNodeのローカルファイルシステム上に保存されます。&lt;/td&gt;&lt;td&gt;カンマ区切りのディレクトリのリストであった場合、通常は異なるデバイスに上の全てのディレクトリにデータが保存されます。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.system.dir&lt;/td&gt;&lt;td&gt;Map/Reduceのフレームワークがシステムファイルを保存するHDFSのディレクトリ 例） /hadoop/mapred/system/&lt;/td&gt;&lt;td&gt;これはデフォルトのフィアルシステム(HDFS)内にあり、サーバとクライアントの両方からアクセスできる必要があります。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.local.dir&lt;/td&gt;&lt;td&gt;一時的なMap/Reduceのデータが保存されるローカルファイルシステム上のディレクトリをカンマ区切りで指定したリスト&lt;/td&gt;&lt;td&gt;複数指定することでディスクI/Oが増えます。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.tasktracker.{map|reduce}.tasks.maximum&lt;/td&gt;&lt;td&gt;TaskTrackerそれぞれに与え、同時実行するMap/Reduceタスクの最大数&lt;/td&gt;&lt;td&gt;デフォルトは2（Mapタスク2つとReduceタスク2つ）ですが、ハードウェア性能にとても左右されます。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;dfs.hosts/dfs.hosts.exclude&lt;/td&gt;&lt;td&gt;許可または除外されるDataNodeのリスト&lt;/td&gt;&lt;td&gt;必要であれば、これらのファイルでDataNodeをコントロールできます。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.hosts/mapred.hosts.exclude&lt;/td&gt;&lt;td&gt;許可または除外されるTaskTrackerのリスト&lt;/td&gt;&lt;td&gt;必要であれば、これらのファイルでTaskTrackerをコントロールできます。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.queue.names&lt;/td&gt;&lt;td&gt;送出可能なジョブをカンマ区切りにしたリスト&lt;/td&gt;&lt;td&gt;Map/Reduceシステムは常に少なくとも１つのdefaultトキューをサポートします。よって、このパラメータの値は常にdefaultという文字列を含める必要があります。&lt;a href="http://hadoop.apache.org/core/docs/current/capacity_scheduler.html"&gt;Capacityスケジューラ&lt;/a&gt;のようなHadoopでサポートされているいくつかのジョブスケジューラでは複数のキューをサポートしています。そのようなスケジューラを使用した場合、キューの名前を個別に指定する必要があります。一度キューが定義されると、ユーザはmapred.job.queue.nameのプロパティ名でジョブをキューに送ることができます。スケジューラによって管理されるこれらのキューの設定については別々のファイルに分けることができる。詳しくは同じくスケジューラのドキュメントを参照してくdさい。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.acls.enabled&lt;/td&gt;&lt;td&gt;ジョブの送出と管理にACLをサポートするかどうかを指定する&lt;/td&gt;&lt;td&gt;trueであればジョブの送出と管理にACLのチェックが行われます。ACLは後述のmapred.queue.queue-name.acl-nameから設定パラメータを取ります。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.queue.queue-name.acl-submit-job&lt;/td&gt;&lt;td&gt;queue-nameで指定したジョブを送出できるユーザとグループのリスト&lt;/td&gt;&lt;td&gt;ユーザとグループのリストはどちらもカンマ区切りで指定します。２つのリストは空白スペースで区切られます。例）user1,user2 group1,group2 もしグループだけを指定したいならば、値の最初に空白スペースを入れてください。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.queue.queue-name.acl-administer-job&lt;/td&gt;&lt;td&gt;queue-nameで指定した送出済みジョブの優先度を変更したり、中止させることができるユーザとグループのリスト&lt;/td&gt;&lt;td&gt;ユーザとグループのリストはどちらもカンマ区切りで指定します。２つのリストは空白スペースで区切られます。例）user1,user2 group1,group2 もしグループだけを指定したいならば、値の最初に空白スペースを入れてください。ジョブのオーナーはACLに関係なくそのジョブの優先度を変更したり中止させられることに注意してください。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;通常これら全てのパラメータはユーザアプリケーションによって上書きされないように&lt;a href="http://hadoop.apache.org/core/docs/current/api/org/apache/hadoop/conf/Configuration.html#FinalParams"&gt;final&lt;/a&gt;として設定されています。&lt;br /&gt;&lt;br /&gt;Real-World Cluster Configurations&lt;br /&gt;このセクションでは大規模クラスタでのソートベンチマークで使われるいくつかのデフォルトではない設定パラメータを挙げます。&lt;br /&gt;&lt;br /&gt;・9TBのデータを900ノードに保存するsort900を実行するのに使われるデフォルトではない設定値。&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;th&gt;Notes&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;dfs.block.size&lt;/td&gt;&lt;td style="text-align: right;"&gt;134217728&lt;/td&gt;&lt;td&gt;大規模ファイルシステムのためにHDFSブロックサイズを128MBに指定。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;dfs.namenode.handler.count&lt;/td&gt;&lt;td style="text-align: right;"&gt;40&lt;/td&gt;&lt;td&gt;多数のDataNodeからのRPCを処理させるためにNameNodeサーバのスレッド数を増やします。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.reduce.parallel.copies&lt;/td&gt;&lt;td style="text-align: right;"&gt;20&lt;/td&gt;&lt;td&gt;Higher number of parallel copies run by reduces to fetch outputs from very large number of maps.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.child.java.opts&lt;/td&gt;&lt;td&gt;-Xmx512M&lt;/td&gt;&lt;td&gt;Larger heap-size for child jvms of maps/reduces.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;fs.inmemory.size.mb&lt;/td&gt;&lt;td style="text-align: right;"&gt;200&lt;/td&gt;&lt;td&gt;Larger amount of memory allocated for the in-memory file-system used to merge map-outputs at the reduces.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;io.sort.factor&lt;/td&gt;&lt;td style="text-align: right;"&gt;100&lt;/td&gt;&lt;td&gt;More streams merged at once while sorting files.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;io.sort.mb&lt;/td&gt;&lt;td style="text-align: right;"&gt;200&lt;/td&gt;&lt;td&gt;Higher memory-limit while sorting data.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;io.file.buffer.size&lt;/td&gt;&lt;td style="text-align: right;"&gt;131072&lt;/td&gt;&lt;td&gt;Size of read/write buffer used in SequenceFiles.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;・14TBのデータを1400ノードに保存するsort1400と20TBのデータを2000ノードに保存するsort2000を実行するために更新した設定値&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;th&gt;Notes&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.job.tracker.handler.count&lt;/td&gt;&lt;td&gt;60&lt;/td&gt;&lt;td&gt;More JobTracker server threads to handle RPCs from large number of TaskTrackers.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.reduce.parallel.copies&lt;/td&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tasktracker.http.threads&lt;/td&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;More worker threads for the TaskTracker's http server. The http server is used by reduces to fetch intermediate map-outputs.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mapred.child.java.opts&lt;/td&gt;&lt;td&gt;-Xmx1024M&lt;/td&gt;&lt;td&gt;Larger heap-size for child jvms of maps/reduces.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;4.2.3.スレーブ&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;通常は１つのコンピュータをNameNodeとして、また１つのコンピュータをJobTrackerとして排他的に選択します。&lt;br /&gt;残りのコンピュータはDataNode兼TaskTrackerとし、スレーブとなります。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;4.2.4.ロギング&lt;/span&gt;&lt;br /&gt;Hadoopはロギングのために&lt;a href="http://commons.apache.org/logging/"&gt;Apache Common Logging&lt;/a&gt;フレームワークを通して&lt;a href="http://logging.apache.org/log4j/"&gt;Apache log4j&lt;/a&gt;を使います。Hadoopのロギング設定を変更するにはconf/log4j.propertiesを編集してください。（ログフォーマットなど）&lt;br /&gt;&lt;br /&gt;履歴ログ&lt;br /&gt;The job history files are stored in central location  hadoop.job.history.location  which can be on DFS also, whose default value is ${HADOOP_LOG_DIR}/history. The history web UI is accessible from job tracker web UI.&lt;br /&gt;&lt;br /&gt;履歴ファイルはユーザがhadoop.job.history.user.locationで指定したディレクトリにも記録されている。ファイルは指定したディレクトリの"_logs/history/"の中にある。よってデフォルトでは"mapred.output.dir/_logs/history/"となる。hadoop.job.history.user.locationの値をnoneにすることでロギングしないようにできる。&lt;br /&gt;&lt;br /&gt;指定したディレクトリで次のコマンドを実行して履歴ログのサマリを見る事ができる。&lt;br /&gt;$ bin/hadoop job -history output-dir&lt;br /&gt;このコマンドはジョブの詳細、失敗、中止を出力する。&lt;br /&gt;成功したタスクや各タスクの進行状況についてのより詳細については次のコマンドを実行することで閲覧できる。&lt;br /&gt;$ bin/hadoop job -history all output-dir&lt;br /&gt;&lt;br /&gt;全ての必要な設定が完了したら、通常は${HADOOP_HOME}/confとなる全てのコンピュータのHADOOP_CONF_DIRディレクトリにファイルを配布します。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;5.クラスタの再起動&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;5.1.Map/Reduce&lt;/span&gt;&lt;br /&gt;The job tracker restart can recover running jobs if mapred.jobtracker.restart.recover is set true and JobHistory logging is enabled. Also mapred.jobtracker.job.history.block.size value should be set to an optimal value to dump job history to disk as soon as possible, the typical value is 3145728(3MB).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;6.Hadoop Rack Awareness&lt;/span&gt;&lt;br /&gt;The HDFS and the Map/Reduce components are rack-aware.&lt;br /&gt;&lt;br /&gt;The NameNode and the JobTracker obtains the rack id of the slaves in the cluster by invoking an API resolve in an administrator configured module. The API resolves the slave's DNS name (also IP address) to a rack id. What module to use can be configured using the configuration item topology.node.switch.mapping.impl. The default implementation of the same runs a script/command configured using topology.script.file.name. If topology.script.file.name is not set, the rack id /default-rack is returned for any passed IP address. The additional configuration in the Map/Reduce part is mapred.cache.task.levels which determines the number of levels (in the network topology) of caches. So, for example, if it is the default value of 2, two levels of caches will be constructed - one for hosts (host -&gt; task mapping) and another for racks (rack -&gt; task mapping).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;7.Hadoop Startup&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To start a Hadoop cluster you will need to start both the HDFS and Map/Reduce cluster.&lt;br /&gt;&lt;br /&gt;Format a new distributed filesystem:&lt;br /&gt;$ bin/hadoop namenode -format&lt;br /&gt;&lt;br /&gt;Start the HDFS with the following command, run on the designated NameNode:&lt;br /&gt;$ bin/start-dfs.sh&lt;br /&gt;&lt;br /&gt;The bin/start-dfs.sh script also consults the ${HADOOP_CONF_DIR}/slaves file on the NameNode and starts the DataNode daemon on all the listed slaves.&lt;br /&gt;&lt;br /&gt;Start Map-Reduce with the following command, run on the designated JobTracker:&lt;br /&gt;$ bin/start-mapred.sh&lt;br /&gt;&lt;br /&gt;The bin/start-mapred.sh script also consults the ${HADOOP_CONF_DIR}/slaves file on the JobTracker and starts the TaskTracker daemon on all the listed slaves.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;8.Hadoop Shutdown&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Stop HDFS with the following command, run on the designated NameNode:&lt;br /&gt;$ bin/stop-dfs.sh&lt;br /&gt;&lt;br /&gt;The bin/stop-dfs.sh script also consults the ${HADOOP_CONF_DIR}/slaves file on the NameNode and stops the DataNode daemon on all the listed slaves.&lt;br /&gt;&lt;br /&gt;Stop Map/Reduce with the following command, run on the designated the designated JobTracker:&lt;br /&gt;$ bin/stop-mapred.sh&lt;br /&gt;&lt;br /&gt;The bin/stop-mapred.sh script also consults the ${HADOOP_CONF_DIR}/slaves file on the JobTracker and stops the TaskTracker daemon on all the listed slaves.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-3541036395418384856?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/jGPcOdDZ7ko" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/3541036395418384856/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=3541036395418384856" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3541036395418384856?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3541036395418384856?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/jGPcOdDZ7ko/hadoop-cluster-setup.html" title="Hadoop Cluster Setup（和訳）" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/04/hadoop-cluster-setup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08MQ309cSp7ImA9WxVaEUo.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-3125383818671990835</id><published>2009-03-30T16:22:00.004+09:00</published><updated>2009-04-08T17:38:02.369+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T17:38:02.369+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Visitors" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>Visitorsの最近のブラウザ対応</title><content type="html">またしてもVisitorsです。&lt;br /&gt;ずっと0.7からバージョンが変わらないVisitors。&lt;br /&gt;動作はちゃんとしてくれるからいいようなものの、&lt;br /&gt;やはり更新されていないと気になるところもある訳で。&lt;br /&gt;&lt;br /&gt;今回はBrowsersレポートで最近のInternetExplorerが「Explorer unknown version」とか、&lt;br /&gt;GoogleChromeが「Safari」に分類されてしまうのに対応するpatch。&lt;br /&gt;ただ、これもまた時が経てば新たなpatchを作らねばならない感じ。。&lt;br /&gt;&lt;br /&gt;これまで３回分のpatchを適用して作成したrpmファイルはこちら。&lt;br /&gt;&lt;a href="https://tmhrnskw.com.s3.amazonaws.com/visitors/visitors-0.70-1.i386.rpm"&gt;visitors-0.70-1.i386.rpm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;*** ../visitors_0.7/visitors.c 2006-03-31 00:31:49.000000000 +0900&lt;br /&gt;--- visitors.c 2009-03-30 16:07:23.000000000 +0900&lt;br /&gt;***************&lt;br /&gt;*** 1435,1441 ****&lt;br /&gt;--- 1435,1444 ----&lt;br /&gt;    "MSIE 4", "Explorer 4.x",&lt;br /&gt;    "MSIE 5", "Explorer 5.x",&lt;br /&gt;    "MSIE 6", "Explorer 6.x",&lt;br /&gt;+   "MSIE 7", "Explorer 7.x",&lt;br /&gt;+   "MSIE 8", "Explorer 8.x",&lt;br /&gt;    "MSIE", "Explorer unknown version",&lt;br /&gt;+   "Chrome", NULL,&lt;br /&gt;    "Safari", NULL,&lt;br /&gt;    "Konqueror", NULL,&lt;br /&gt;    "Galeon", NULL,&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-3125383818671990835?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/mxROy2aRH8k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/3125383818671990835/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=3125383818671990835" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3125383818671990835?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3125383818671990835?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/mxROy2aRH8k/visitors_30.html" title="Visitorsの最近のブラウザ対応" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/03/visitors_30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04HRn07eip7ImA9WxVaEUo.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-4151192811555150691</id><published>2009-03-26T21:11:00.010+09:00</published><updated>2009-04-08T17:38:57.302+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T17:38:57.302+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Visitors" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>Visitors XML output patch</title><content type="html">どうしてそんなにVisitorsにご執心なのか。たぶん生Cで書かれてるからかな。&lt;br /&gt;今日は&lt;a href="http://2606-36j.blogspot.com/2009/03/visitors.html"&gt;前回&lt;/a&gt;に続いて集計結果をXML形式で出力するpatchを作ってみた。Visitors-0.7のvisitors.cに対するpatchだが、基本的にgraphizには対応していない。&lt;br /&gt;&lt;s&gt;前回のpatchと両方当てることはまだ考えない方が良い。後で気が向いた時にもっとまともなpatchに仕上げるつもり。&lt;/s&gt;&lt;br /&gt;03/30追記：前回分と今回分のpatchの出力を少し変えました。多分コレで両方当てられるかと。&lt;br /&gt;&lt;br /&gt;そもそもVisitorsのサイトに&lt;br /&gt;&lt;blockquote&gt;Visitors is internally designed to be extended. You can develop more output modules for it if you are not happy with html and text only. Check the source code to see how the output modules already developed work. You have just to define methods for your new output module like print_header, print_title, and so on. &lt;/blockquote&gt;&lt;br /&gt;出力が気に食わなければOutput moduleでも書いたらいいじゃん、ってあるくらいだから&lt;br /&gt;「結構スマートな作りになってるのかな？」とか思ったら実際そうでもない。&lt;br /&gt;XMLみたいに入れ子で出力する事はあまり考慮されていない作りだから&lt;br /&gt;結局Output HTML moduleもOutput Text moduleも少しだけ手を入れました。&lt;br /&gt;&lt;br /&gt;visitors-xmloutput.patch&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;*** ../visitors_0.7/visitors.c 2006-03-31 00:31:49.000000000 +0900&lt;br /&gt;--- visitors.c 2009-03-30 16:05:20.000000000 +0900&lt;br /&gt;***************&lt;br /&gt;*** 113,118 ****&lt;br /&gt;--- 113,119 ----&lt;br /&gt;   void (*print_hline)(FILE *fp);&lt;br /&gt;   void (*print_credits)(FILE *fp);&lt;br /&gt;   void (*print_report_link)(FILE *fp, char *report);&lt;br /&gt;+  void (*print_element)(FILE *fp, char *element, int close);&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;  /* Just a string with cached length */&lt;br /&gt;***************&lt;br /&gt;*** 1965,1970 ****&lt;br /&gt;--- 1966,1976 ----&lt;br /&gt;   return;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;+ void om_text_print_element(FILE *fp, char *element, int close)&lt;br /&gt;+ {&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;  struct outputmodule OutputModuleText = {&lt;br /&gt;   om_text_print_header,&lt;br /&gt;   om_text_print_footer,&lt;br /&gt;***************&lt;br /&gt;*** 1979,1984 ****&lt;br /&gt;--- 1985,1991 ----&lt;br /&gt;   om_text_print_hline,&lt;br /&gt;   om_text_print_credits,&lt;br /&gt;   om_text_print_report_link,&lt;br /&gt;+  om_text_print_element,&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;  /* ---------------------------- html output module -------------------------- */&lt;br /&gt;***************&lt;br /&gt;*** 2308,2313 ****&lt;br /&gt;--- 2315,2325 ----&lt;br /&gt;   return;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;+ void om_html_print_element(FILE *fp, char *element, int close)&lt;br /&gt;+ {&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;  struct outputmodule OutputModuleHtml = {&lt;br /&gt;   om_html_print_header,&lt;br /&gt;   om_html_print_footer,&lt;br /&gt;***************&lt;br /&gt;*** 2322,2329 ****&lt;br /&gt;--- 2334,2536 ----&lt;br /&gt;   om_html_print_hline,&lt;br /&gt;   om_html_print_credits,&lt;br /&gt;   om_html_print_report_link,&lt;br /&gt;+  om_html_print_element,&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;+ /* ---------------------------- xml output module --------------------------- */&lt;br /&gt;+ void om_xml_print_element(FILE *fp, char *element, int close)&lt;br /&gt;+ {&lt;br /&gt;+  if (!close) {&lt;br /&gt;+   fprintf(fp, "&lt;%s&gt;", element);&lt;br /&gt;+  } else {&lt;br /&gt;+   fprintf(fp, "&lt;/%s&gt;\n", element);&lt;br /&gt;+  }&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_header(FILE *fp)&lt;br /&gt;+ {&lt;br /&gt;+  fprintf(fp, "&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n");&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_footer(FILE *fp)&lt;br /&gt;+ {&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_title(FILE *fp, char *title)&lt;br /&gt;+ {&lt;br /&gt;+  om_xml_print_element(fp, "title", 0);&lt;br /&gt;+  fprintf(fp, title);&lt;br /&gt;+  om_xml_print_element(fp, "title", 1);&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_subtitle(FILE *fp, char *subtitle)&lt;br /&gt;+ {&lt;br /&gt;+  om_xml_print_element(fp, "subtitle", 0);&lt;br /&gt;+  fprintf(fp, subtitle);&lt;br /&gt;+  om_xml_print_element(fp, "subtitle", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_numkey_info(FILE *fp, char *key, int val)&lt;br /&gt;+ {&lt;br /&gt;+  fprintf(fp, "&lt;key name=\"%s\"&gt;", key);&lt;br /&gt;+  fprintf(fp, "%d", val);&lt;br /&gt;+  om_xml_print_element(fp, "key", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_keykey_entry(FILE *fp, char *key1, char *key2, int num)&lt;br /&gt;+ {&lt;br /&gt;+  fprintf(fp, "&lt;order num=\"%d\"&gt;", num);&lt;br /&gt;+  om_xml_print_element(fp, "name", 0);&lt;br /&gt;+  fprintf(fp, "%s", key1);&lt;br /&gt;+  om_xml_print_element(fp, "name", 1);&lt;br /&gt;+  om_xml_print_element(fp, "value", 0);&lt;br /&gt;+  fprintf(fp, "%s", key2);&lt;br /&gt;+  om_xml_print_element(fp, "value", 1);&lt;br /&gt;+  om_xml_print_element(fp, "order", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_numkey_entry(FILE *fp, char *key, int val, char *link, int num)&lt;br /&gt;+ {&lt;br /&gt;+  fprintf(fp, "&lt;order num=\"%d\"&gt;", num);&lt;br /&gt;+  if (link != NULL) {&lt;br /&gt;+   fprintf(fp, "&lt;name url=\"%s\"&gt;%s", link, key);&lt;br /&gt;+  } else if (!strncmp(key, "http://", 7)) {&lt;br /&gt;+   fprintf(fp, "&lt;name url=\"%s\"&gt;%s", link, key);&lt;br /&gt;+  } else {&lt;br /&gt;+   fprintf(fp, "&lt;name&gt;%s", key);&lt;br /&gt;+  }&lt;br /&gt;+  om_xml_print_element(fp, "name", 1);&lt;br /&gt;+  om_xml_print_element(fp, "value", 0);&lt;br /&gt;+  fprintf(fp, "%d", val);&lt;br /&gt;+  om_xml_print_element(fp, "value", 1);&lt;br /&gt;+  om_xml_print_element(fp, "order", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_bar(FILE *fp, int l, char *leftclass, char *rightclass)&lt;br /&gt;+ {&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_numkeybar_entry(FILE *fp, char *key, int max, int tot, int this)&lt;br /&gt;+ {&lt;br /&gt;+  int l, weekend;&lt;br /&gt;+  float p;&lt;br /&gt;+ &lt;br /&gt;+  if (tot == 0) tot++;&lt;br /&gt;+  if (max == 0) max++;&lt;br /&gt;+  l = ((float)(100*this))/max;&lt;br /&gt;+  p = ((float)(100*this))/tot;&lt;br /&gt;+  weekend = vi_is_weekend(key);&lt;br /&gt;+ &lt;br /&gt;+  if (weekend)&lt;br /&gt;+   fprintf(fp, "&lt;item weekend=\"1\"&gt;");&lt;br /&gt;+  else&lt;br /&gt;+   fprintf(fp, "&lt;item weekend=\"0\"&gt;");&lt;br /&gt;+  om_xml_print_element(fp, "name", 0);&lt;br /&gt;+  fprintf(fp, "%s", key);&lt;br /&gt;+  om_xml_print_element(fp, "name", 1);&lt;br /&gt;+  om_xml_print_element(fp, "value", 0);&lt;br /&gt;+  fprintf(fp, "%d", this);&lt;br /&gt;+  om_xml_print_element(fp, "value", 1);&lt;br /&gt;+  om_xml_print_element(fp, "percent", 0);&lt;br /&gt;+  fprintf(fp, "%02.1f%%", p);&lt;br /&gt;+  om_xml_print_element(fp, "percent", 1);&lt;br /&gt;+  om_xml_print_element(fp, "item", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_numkeycomparativebar_entry(FILE *fp, char *key, int tot, int this)&lt;br /&gt;+ {&lt;br /&gt;+  int l, weekend;&lt;br /&gt;+  float p;&lt;br /&gt;+ &lt;br /&gt;+  if (tot ==0) tot++;&lt;br /&gt;+  p = ((float)(100*this))/tot;&lt;br /&gt;+  l = (int) p;&lt;br /&gt;+  weekend = vi_is_weekend(key);&lt;br /&gt;+ &lt;br /&gt;+  if (weekend)&lt;br /&gt;+   fprintf(fp, "&lt;item weekend=\"1\"&gt;");&lt;br /&gt;+  else&lt;br /&gt;+   fprintf(fp, "&lt;item weekend=\"0\"&gt;");&lt;br /&gt;+  om_xml_print_element(fp, "name", 0);&lt;br /&gt;+  fprintf(fp, "%s", key);&lt;br /&gt;+  om_xml_print_element(fp, "name", 1);&lt;br /&gt;+  om_xml_print_element(fp, "value", 0);&lt;br /&gt;+  fprintf(fp, "%d", this);&lt;br /&gt;+  om_xml_print_element(fp, "value", 1);&lt;br /&gt;+  om_xml_print_element(fp, "percent", 0);&lt;br /&gt;+  fprintf(fp, "%02.1f%%", p);&lt;br /&gt;+  om_xml_print_element(fp, "percent", 1);&lt;br /&gt;+  om_xml_print_element(fp, "item", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_bidimentional_map(FILE *fp, int xlen, int ylen, char **xlabel, char **ylabel, int *value)&lt;br /&gt;+ {&lt;br /&gt;+  int x, y, l, max = 0;&lt;br /&gt;+ &lt;br /&gt;+  /* Get the max value */&lt;br /&gt;+  l = xlen*ylen;&lt;br /&gt;+  for (x = 0; x &lt; l; x++)&lt;br /&gt;+   if (max &lt; value[x])&lt;br /&gt;+    max = value[x];&lt;br /&gt;+  if (max == 0) max++; /* avoid division by zero */&lt;br /&gt;+  /* print the map */&lt;br /&gt;+  om_xml_print_element(fp, "items", 0);&lt;br /&gt;+  for (y = 0; y &lt; ylen; y++) {&lt;br /&gt;+   fprintf(fp, "&lt;item name=\"%s\"&gt;", ylabel[y]);&lt;br /&gt;+   for (x = 0; x &lt; xlen; x++) {&lt;br /&gt;+    fprintf(fp, "&lt;value name=\"%s\"&gt;%d", xlabel[x], value[(y*xlen)+x]);&lt;br /&gt;+    om_xml_print_element(fp, "value", 1);&lt;br /&gt;+   }&lt;br /&gt;+   om_xml_print_element(fp, "item", 1);&lt;br /&gt;+  }&lt;br /&gt;+  om_xml_print_element(fp, "items", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_hline(FILE *fp)&lt;br /&gt;+ {&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_credits(FILE *fp)&lt;br /&gt;+ {&lt;br /&gt;+  om_xml_print_element(fp, "credits", 0);&lt;br /&gt;+  fprintf(fp, "Statistics generated with VISITORS version %s", VI_VERSION_STR);&lt;br /&gt;+  om_xml_print_element(fp, "credits", 1);&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ void om_xml_print_report_link(FILE *fp, char *report)&lt;br /&gt;+ {&lt;br /&gt;+  return;&lt;br /&gt;+ }&lt;br /&gt;+ &lt;br /&gt;+ struct outputmodule OutputModuleXml = {&lt;br /&gt;+  om_xml_print_header,&lt;br /&gt;+  om_xml_print_footer,&lt;br /&gt;+  om_xml_print_title,&lt;br /&gt;+  om_xml_print_subtitle,&lt;br /&gt;+  om_xml_print_numkey_info,&lt;br /&gt;+  om_xml_print_keykey_entry,&lt;br /&gt;+  om_xml_print_numkey_entry,&lt;br /&gt;+  om_xml_print_numkeybar_entry,&lt;br /&gt;+  om_xml_print_numkeycomparativebar_entry,&lt;br /&gt;+  om_xml_print_bidimentional_map,&lt;br /&gt;+  om_xml_print_hline,&lt;br /&gt;+  om_xml_print_credits,&lt;br /&gt;+  om_xml_print_report_link,&lt;br /&gt;+  om_xml_print_element,&lt;br /&gt;+ };&lt;br /&gt;  &lt;br /&gt;  /* ---------------------------------- output -------------------------------- */&lt;br /&gt;  void vi_print_statistics(struct vih *vih)&lt;br /&gt;***************&lt;br /&gt;*** 2345,2357 ****&lt;br /&gt;--- 2552,2568 ----&lt;br /&gt;     max = vih-&gt;hour[i];&lt;br /&gt;    tot += vih-&gt;hour[i];&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Hours distribution");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Percentage of hits in every hour of the day");&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; 24; i++) {&lt;br /&gt;    char buf[8];&lt;br /&gt;    sprintf(buf, "%02d", i);&lt;br /&gt;    Output-&gt;print_numkeybar_entry(fp, buf, max, tot, vih-&gt;hour[i]);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_weekdays_report(FILE *fp, struct vih *vih)&lt;br /&gt;***************&lt;br /&gt;*** 2362,2372 ****&lt;br /&gt;--- 2573,2587 ----&lt;br /&gt;     max = vih-&gt;weekday[i];&lt;br /&gt;    tot += vih-&gt;weekday[i];&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Weekdays distribution");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Percentage of hits in every day of the week");&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; 7; i++) {&lt;br /&gt;    Output-&gt;print_numkeybar_entry(fp, vi_wdname[i], max, tot, vih-&gt;weekday[i]);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /* Generic function for qsort(3) called to sort a table.&lt;br /&gt;***************&lt;br /&gt;*** 2463,2468 ****&lt;br /&gt;--- 2678,2684 ----&lt;br /&gt;   int months;&lt;br /&gt;   void **table;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Unique visitors in each day");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Multiple hits with the same IP, user agent and access day, are considered a single visit");&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of unique visitors",&lt;br /&gt;***************&lt;br /&gt;*** 2481,2498 ****&lt;br /&gt;     max = value;&lt;br /&gt;    tot += value;&lt;br /&gt;   }&lt;br /&gt;   for (i = 0; i &lt; days; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;    Output-&gt;print_numkeybar_entry(fp, key, max, tot, value);&lt;br /&gt;   }&lt;br /&gt;   free(table);&lt;br /&gt;!         Output-&gt;print_hline(fp);&lt;br /&gt;  &lt;br /&gt;   /* Montly */&lt;br /&gt;   if (Config_process_monthly_visitors == 0) return;&lt;br /&gt;   tot = max = 0;&lt;br /&gt;   months = ht_used(&amp;vih-&gt;month);&lt;br /&gt;   Output-&gt;print_title(fp, "Unique visitors in each month");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Multiple hits with the same IP, user agent and access day, are considered a single visit");&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of unique visitors",&lt;br /&gt;--- 2697,2718 ----&lt;br /&gt;     max = value;&lt;br /&gt;    tot += value;&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; days; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;    Output-&gt;print_numkeybar_entry(fp, key, max, tot, value);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;   free(table);&lt;br /&gt;!  Output-&gt;print_hline(fp);&lt;br /&gt;!  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  &lt;br /&gt;   /* Montly */&lt;br /&gt;   if (Config_process_monthly_visitors == 0) return;&lt;br /&gt;   tot = max = 0;&lt;br /&gt;   months = ht_used(&amp;vih-&gt;month);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Unique visitors in each month");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Multiple hits with the same IP, user agent and access day, are considered a single visit");&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of unique visitors",&lt;br /&gt;***************&lt;br /&gt;*** 2511,2522 ****&lt;br /&gt;--- 2731,2745 ----&lt;br /&gt;     max = value;&lt;br /&gt;    tot += value;&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; months; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;    Output-&gt;print_numkeybar_entry(fp, key, max, tot, value);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;   free(table);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /* A report to compare visits originating from google VS all the rest. */&lt;br /&gt;***************&lt;br /&gt;*** 2525,2530 ****&lt;br /&gt;--- 2748,2754 ----&lt;br /&gt;   int days = ht_used(&amp;vih-&gt;date), i, months;&lt;br /&gt;   void **table;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Unique visitors from Google in each day");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "The red part of the bar expresses the percentage of visits originated from Google");&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of unique visitors",&lt;br /&gt;***************&lt;br /&gt;*** 2539,2544 ****&lt;br /&gt;--- 2763,2769 ----&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;   qsort(table, days, sizeof(void*)*2, qsort_cmp_dates_key);&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; days; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;***************&lt;br /&gt;*** 2547,2558 ****&lt;br /&gt;    googlevalue = vi_counter_val(&amp;vih-&gt;googledate, key);&lt;br /&gt;    Output-&gt;print_numkeycomparativebar_entry(fp, key, value, googlevalue);&lt;br /&gt;   }&lt;br /&gt;   free(table);&lt;br /&gt;!         Output-&gt;print_hline(fp);&lt;br /&gt;  &lt;br /&gt;   /* Montly */&lt;br /&gt;   if (Config_process_monthly_visitors == 0) return;&lt;br /&gt;   months = ht_used(&amp;vih-&gt;month);&lt;br /&gt;   Output-&gt;print_title(fp, "Unique visitors from Google in each month");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "The red part of the bar expresses the percentage of visits originated from Google");&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of unique visitors",&lt;br /&gt;--- 2772,2786 ----&lt;br /&gt;    googlevalue = vi_counter_val(&amp;vih-&gt;googledate, key);&lt;br /&gt;    Output-&gt;print_numkeycomparativebar_entry(fp, key, value, googlevalue);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;   free(table);&lt;br /&gt;!  Output-&gt;print_hline(fp);&lt;br /&gt;!  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  &lt;br /&gt;   /* Montly */&lt;br /&gt;   if (Config_process_monthly_visitors == 0) return;&lt;br /&gt;   months = ht_used(&amp;vih-&gt;month);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Unique visitors from Google in each month");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "The red part of the bar expresses the percentage of visits originated from Google");&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of unique visitors",&lt;br /&gt;***************&lt;br /&gt;*** 2567,2572 ****&lt;br /&gt;--- 2795,2801 ----&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;   qsort(table, months, sizeof(void*)*2, qsort_cmp_months_key);&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; months; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;***************&lt;br /&gt;*** 2575,2581 ****&lt;br /&gt;--- 2804,2812 ----&lt;br /&gt;    googlevalue = vi_counter_val(&amp;vih-&gt;googlemonth, key);&lt;br /&gt;    Output-&gt;print_numkeycomparativebar_entry(fp, key, value, googlevalue);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;   free(table);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_generic_keyval_report(FILE *fp, char *title, char *subtitle,&lt;br /&gt;***************&lt;br /&gt;*** 2586,2591 ****&lt;br /&gt;--- 2817,2823 ----&lt;br /&gt;   int items = ht_used(ht), i;&lt;br /&gt;   void **table;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, title);&lt;br /&gt;   Output-&gt;print_subtitle(fp, subtitle);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, info, items);&lt;br /&gt;***************&lt;br /&gt;*** 2594,2599 ****&lt;br /&gt;--- 2826,2832 ----&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;   qsort(table, items, sizeof(void*)*2, compar);&lt;br /&gt;+  Output-&gt;print_element(fp, "orders", 0);&lt;br /&gt;   for (i = 0; i &lt; items; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;***************&lt;br /&gt;*** 2604,2610 ****&lt;br /&gt;--- 2837,2845 ----&lt;br /&gt;    else&lt;br /&gt;     Output-&gt;print_numkey_entry(fp, key, value, NULL, i+1);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "orders", 1);&lt;br /&gt;   free(table);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_generic_keyvalbar_report(FILE *fp, char *title, char *subtitle,&lt;br /&gt;***************&lt;br /&gt;*** 2615,2620 ****&lt;br /&gt;--- 2850,2856 ----&lt;br /&gt;   int items = ht_used(ht), i, max = 0, tot = 0;&lt;br /&gt;   void **table;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, title);&lt;br /&gt;   Output-&gt;print_subtitle(fp, subtitle);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, info, items);&lt;br /&gt;***************&lt;br /&gt;*** 2628,2633 ****&lt;br /&gt;--- 2864,2870 ----&lt;br /&gt;    tot += value;&lt;br /&gt;    if (value &gt; max) max = value;&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 0);&lt;br /&gt;   for (i = 0; i &lt; items; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;***************&lt;br /&gt;*** 2637,2643 ****&lt;br /&gt;--- 2874,2882 ----&lt;br /&gt;    else&lt;br /&gt;     Output-&gt;print_numkeybar_entry(fp, key, max, tot, value);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "items", 1);&lt;br /&gt;   free(table);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /* This is similar to the generic key/val report, but&lt;br /&gt;***************&lt;br /&gt;*** 2650,2655 ****&lt;br /&gt;--- 2889,2895 ----&lt;br /&gt;   int items = ht_used(ht), i;&lt;br /&gt;   void **table;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, title);&lt;br /&gt;   Output-&gt;print_subtitle(fp, subtitle);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, info, items);&lt;br /&gt;***************&lt;br /&gt;*** 2658,2663 ****&lt;br /&gt;--- 2898,2904 ----&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;   qsort(table, items, sizeof(void*)*2, compar);&lt;br /&gt;+  Output-&gt;print_element(fp, "orders", 0);&lt;br /&gt;   for (i = 0; i &lt; items; i++) {&lt;br /&gt;    char *key = table[i*2];&lt;br /&gt;    long value = (long) table[(i*2)+1];&lt;br /&gt;***************&lt;br /&gt;*** 2683,2689 ****&lt;br /&gt;--- 2924,2932 ----&lt;br /&gt;     Output-&gt;print_numkey_entry(fp, key, value, link, i+1);&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "orders", 1);&lt;br /&gt;   free(table);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_referers_report(FILE *fp, struct vih *vih)&lt;br /&gt;***************&lt;br /&gt;*** 2841,2846 ****&lt;br /&gt;--- 3084,3090 ----&lt;br /&gt;   int items = ht_used(ht), i;&lt;br /&gt;   void **table;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, title);&lt;br /&gt;   Output-&gt;print_subtitle(fp, subtitle);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, info, items);&lt;br /&gt;***************&lt;br /&gt;*** 2849,2854 ****&lt;br /&gt;--- 3093,3099 ----&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;   qsort(table, items, sizeof(void*)*2, compar);&lt;br /&gt;+  Output-&gt;print_element(fp, "orders", 0);&lt;br /&gt;   for (i = 0; i &lt; items; i++) {&lt;br /&gt;    struct tm *tm;&lt;br /&gt;    char ftime[1024];&lt;br /&gt;***************&lt;br /&gt;*** 2863,2869 ****&lt;br /&gt;--- 3108,3116 ----&lt;br /&gt;       (url[0] == '\0') ? "none" : url, i+1);&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "orders", 1);&lt;br /&gt;   free(table);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_googled_report(FILE *fp, struct vih *vih)&lt;br /&gt;***************&lt;br /&gt;*** 2953,2964 ****&lt;br /&gt;--- 3200,3213 ----&lt;br /&gt;   char buf[VI_LINE_MAX];&lt;br /&gt;   time_t now = time(NULL);&lt;br /&gt;   snprintf(buf, VI_LINE_MAX, "Generated: %s", ctime(&amp;now));&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "General information");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Information about analyzed log files");&lt;br /&gt;   Output-&gt;print_subtitle(fp, buf);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of entries processed", vih-&gt;processed);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Number of invalid entries", vih-&gt;invalid);&lt;br /&gt;   Output-&gt;print_numkey_info(fp, "Processing time in seconds", (vih-&gt;endt)-(vih-&gt;startt));&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_report_links(FILE *fp)&lt;br /&gt;***************&lt;br /&gt;*** 2994,2999 ****&lt;br /&gt;--- 3243,3249 ----&lt;br /&gt;   };&lt;br /&gt;   unsigned int i, num = 0;&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Generated reports");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Click on the report name you want to see");&lt;br /&gt;   for (i = 0; i &lt; sizeof(l)/sizeof(void*); i += 2) {&lt;br /&gt;***************&lt;br /&gt;*** 3006,3011 ****&lt;br /&gt;--- 3256,3262 ----&lt;br /&gt;    if (active)&lt;br /&gt;     Output-&gt;print_report_link(fp, (char*)l[i]);&lt;br /&gt;   }&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_weekdayhour_map_report(FILE *fp, struct vih *vih)&lt;br /&gt;***************&lt;br /&gt;*** 3027,3032 ****&lt;br /&gt;--- 3278,3284 ----&lt;br /&gt;     minj = j;&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Weekday-Hour combined map");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Brighter means higher level of hits");&lt;br /&gt;   snprintf(buf, VI_LINE_MAX, "Hour with max traffic starting at %s %s:00 with hits",&lt;br /&gt;***************&lt;br /&gt;*** 3037,3042 ****&lt;br /&gt;--- 3289,3295 ----&lt;br /&gt;   Output-&gt;print_numkey_info(fp, buf, hw[minj]);&lt;br /&gt;   Output-&gt;print_hline(fp);&lt;br /&gt;   Output-&gt;print_bidimentional_map(fp, 24, 7, xlabel, ylabel, hw);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_monthday_map_report(FILE *fp, struct vih *vih)&lt;br /&gt;***************&lt;br /&gt;*** 3062,3067 ****&lt;br /&gt;--- 3315,3321 ----&lt;br /&gt;     minj = j;&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;+  Output-&gt;print_element(fp, "report", 0);&lt;br /&gt;   Output-&gt;print_title(fp, "Month-Day combined map");&lt;br /&gt;   Output-&gt;print_subtitle(fp, "Brighter means higher level of hits");&lt;br /&gt;   snprintf(buf, VI_LINE_MAX, "Day with max traffic is %s %s with hits",&lt;br /&gt;***************&lt;br /&gt;*** 3072,3077 ****&lt;br /&gt;--- 3326,3332 ----&lt;br /&gt;   Output-&gt;print_numkey_info(fp, buf, md[minj]);&lt;br /&gt;   Output-&gt;print_hline(fp);&lt;br /&gt;   Output-&gt;print_bidimentional_map(fp, 31, 12, xlabel, ylabel, md);&lt;br /&gt;+  Output-&gt;print_element(fp, "report", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_hline(FILE *fp)&lt;br /&gt;***************&lt;br /&gt;*** 3087,3097 ****&lt;br /&gt;--- 3342,3354 ----&lt;br /&gt;  void vi_print_header(FILE *fp)&lt;br /&gt;  {&lt;br /&gt;   Output-&gt;print_header(fp);&lt;br /&gt;+  Output-&gt;print_element(fp, "visitors", 0);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void vi_print_footer(FILE *fp)&lt;br /&gt;  {&lt;br /&gt;   Output-&gt;print_footer(fp);&lt;br /&gt;+  Output-&gt;print_element(fp, "visitors", 1);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /* Generate the report writing it to the output file 'of'.&lt;br /&gt;***************&lt;br /&gt;*** 3536,3541 ****&lt;br /&gt;--- 3793,3800 ----&lt;br /&gt;      Output = &amp;OutputModuleText;&lt;br /&gt;     else if (!strcasecmp(ago_optarg, "html"))&lt;br /&gt;      Output = &amp;OutputModuleHtml;&lt;br /&gt;+    else if (!strcasecmp(ago_optarg, "xml"))&lt;br /&gt;+     Output = &amp;OutputModuleXml;&lt;br /&gt;     else {&lt;br /&gt;      fprintf(stderr, "Unknown output module '%s'\n",&lt;br /&gt;        ago_optarg);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-4151192811555150691?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/Zn7lEYWPtQA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/4151192811555150691/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=4151192811555150691" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/4151192811555150691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/4151192811555150691?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/Zn7lEYWPtQA/visitors-xml-output-patch.html" title="Visitors XML output patch" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/03/visitors-xml-output-patch.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04CQH48eSp7ImA9WxVaEUo.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-6718134994550504568</id><published>2009-03-24T20:07:00.004+09:00</published><updated>2009-04-08T17:39:21.071+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T17:39:21.071+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Visitors" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>visitorsの出力を制御する</title><content type="html">アクセスログ解析のvisitorsですが、オプションを選択しなくても表示される項目がいくつかあります。&lt;a href="http://www.hping.org/visitors/report.html"&gt;出力結果&lt;/a&gt;中の以下の項目がそうです。&lt;br /&gt;&lt;br /&gt;General information&lt;br /&gt;Generated reports&lt;br /&gt;Unique visitors in each day&lt;br /&gt;Unique visitors in each month&lt;br /&gt;Unique visitors from Google in each day&lt;br /&gt;Requested pages&lt;br /&gt;Requested images and CSS&lt;br /&gt;Referers&lt;br /&gt;Weekdays distribution&lt;br /&gt;Hours distribution&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.hping.org/visitors/visitors-0.7.tar.gz"&gt;現時点での最新版0.7&lt;/a&gt;のvisitors.cに後述するpatchを適用するとデフォルト（表示項目のオプション未指定）での出力はヘッダ、フッタだけになります。&lt;br /&gt;新たに追加した表示オプションは以下。&lt;br /&gt;&lt;br /&gt;--credits 上下のクレジットを出力します。&lt;br /&gt;--information "General information"を出力します。&lt;br /&gt;--report-link "Generated reports"を出力します。&lt;br /&gt;--visits "Unique visitors in each day"と"Unique visitors in each month"を出力します。&lt;br /&gt;--google-visits "Unique visitors from Google in each day"を出力します。&lt;br /&gt;--pages "Requested pages"を出力します。&lt;br /&gt;--images "Requested images and CSS"を出力します。&lt;br /&gt;--referers "Referers"を出力します。&lt;br /&gt;--weekdays "Weekdays distribution"を出力します。&lt;br /&gt;--hours "Hours distribution"を出力します。&lt;br /&gt;&lt;br /&gt;patchはこちら。（インデントを直してる部分とかありますけど。）&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;*** ../visitors_0.7/visitors.c 2006-03-31 00:31:49.000000000 +0900&lt;br /&gt;--- visitors.c 2009-03-30 16:06:55.000000000 +0900&lt;br /&gt;***************&lt;br /&gt;*** 45,51 ****&lt;br /&gt;   int endt;&lt;br /&gt;   int processed;&lt;br /&gt;   int invalid;&lt;br /&gt;!         int blacklisted;&lt;br /&gt;   int hour[24];&lt;br /&gt;   int weekday[7];&lt;br /&gt;   int weekdayhour[7][24]; /* hour and weekday combined data */&lt;br /&gt;--- 45,51 ----&lt;br /&gt;   int endt;&lt;br /&gt;   int processed;&lt;br /&gt;   int invalid;&lt;br /&gt;!  int blacklisted;&lt;br /&gt;   int hour[24];&lt;br /&gt;   int weekday[7];&lt;br /&gt;   int weekdayhour[7][24]; /* hour and weekday combined data */&lt;br /&gt;***************&lt;br /&gt;*** 61,67 ****&lt;br /&gt;   struct hashtable referersage;&lt;br /&gt;   struct hashtable date;&lt;br /&gt;   struct hashtable googledate;&lt;br /&gt;!         struct hashtable adsensed;&lt;br /&gt;   struct hashtable month;&lt;br /&gt;   struct hashtable googlemonth;&lt;br /&gt;   struct hashtable agents;&lt;br /&gt;--- 61,67 ----&lt;br /&gt;   struct hashtable referersage;&lt;br /&gt;   struct hashtable date;&lt;br /&gt;   struct hashtable googledate;&lt;br /&gt;!  struct hashtable adsensed;&lt;br /&gt;   struct hashtable month;&lt;br /&gt;   struct hashtable googlemonth;&lt;br /&gt;   struct hashtable agents;&lt;br /&gt;***************&lt;br /&gt;*** 74,82 ****&lt;br /&gt;   struct hashtable os;&lt;br /&gt;   struct hashtable browsers;&lt;br /&gt;   struct hashtable robots;&lt;br /&gt;!         struct hashtable googlehumanlanguage;&lt;br /&gt;!         struct hashtable screenres;&lt;br /&gt;!         struct hashtable screendepth;&lt;br /&gt;   char *error;&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;--- 74,82 ----&lt;br /&gt;   struct hashtable os;&lt;br /&gt;   struct hashtable browsers;&lt;br /&gt;   struct hashtable robots;&lt;br /&gt;!  struct hashtable googlehumanlanguage;&lt;br /&gt;!  struct hashtable screenres;&lt;br /&gt;!  struct hashtable screendepth;&lt;br /&gt;   char *error;&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;***************&lt;br /&gt;*** 145,154 ****&lt;br /&gt;--- 145,159 ----&lt;br /&gt;  int Config_max_tld = 20;&lt;br /&gt;  int Config_max_robots = 20;&lt;br /&gt;  int Config_process_agents = 0;&lt;br /&gt;+ int Config_process_credits = 0;&lt;br /&gt;  int Config_process_google = 0;&lt;br /&gt;  int Config_process_google_keyphrases = 0;&lt;br /&gt;  int Config_process_google_keyphrases_age = 0;&lt;br /&gt;  int Config_process_google_human_language = 0;&lt;br /&gt;+ int Config_process_google_visits = 0;&lt;br /&gt;+ int Config_process_hours = 0;&lt;br /&gt;+ int Config_process_images = 0;&lt;br /&gt;+ int Config_process_information = 0;&lt;br /&gt;  int Config_process_web_trails = 0;&lt;br /&gt;  int Config_process_weekdayhour_map = 0;&lt;br /&gt;  int Config_process_monthday_map = 0;&lt;br /&gt;***************&lt;br /&gt;*** 157,166 ****&lt;br /&gt;--- 162,176 ----&lt;br /&gt;  int Config_process_os = 0;&lt;br /&gt;  int Config_process_browsers = 0;&lt;br /&gt;  int Config_process_error404 = 0;&lt;br /&gt;+ int Config_process_pages = 0;&lt;br /&gt;  int Config_process_pageviews = 0;&lt;br /&gt;  int Config_process_monthly_visitors = 1;&lt;br /&gt;+ int Config_process_referers = 0;&lt;br /&gt;+ int Config_process_report_links = 0;&lt;br /&gt;  int Config_process_robots = 0;&lt;br /&gt;  int Config_process_screen_info = 0;&lt;br /&gt;+ int Config_process_visits = 0;&lt;br /&gt;+ int Config_process_weekdays = 0;&lt;br /&gt;  int Config_graphviz_mode = 0;&lt;br /&gt;  int Config_graphviz_ignorenode_google = 0;&lt;br /&gt;  int Config_graphviz_ignorenode_external = 0;&lt;br /&gt;***************&lt;br /&gt;*** 3121,3136 ****&lt;br /&gt;    return 1;&lt;br /&gt;   /* Report generation */&lt;br /&gt;   vi_print_header(fp);&lt;br /&gt;!  vi_print_credits(fp);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_information_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_report_links(fp);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_visits_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_googlevisits_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;   if (Config_process_weekdayhour_map) {&lt;br /&gt;    vi_print_weekdayhour_map_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;--- 3131,3156 ----&lt;br /&gt;    return 1;&lt;br /&gt;   /* Report generation */&lt;br /&gt;   vi_print_header(fp);&lt;br /&gt;!  if (Config_process_credits) {&lt;br /&gt;!   vi_print_credits(fp);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_information) {&lt;br /&gt;!   vi_print_information_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_report_links) {&lt;br /&gt;!   vi_print_report_links(fp);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_visits) {&lt;br /&gt;!   vi_print_visits_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_google_visits) {&lt;br /&gt;!   vi_print_googlevisits_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;   if (Config_process_weekdayhour_map) {&lt;br /&gt;    vi_print_weekdayhour_map_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;***************&lt;br /&gt;*** 3143,3154 ****&lt;br /&gt;    vi_print_pageviews_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;   }&lt;br /&gt;!  vi_print_pages_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_images_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_referers_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;   if (Config_process_referers_age) {&lt;br /&gt;    vi_print_referers_age_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;--- 3163,3180 ----&lt;br /&gt;    vi_print_pageviews_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;   }&lt;br /&gt;!  if (Config_process_pages) {&lt;br /&gt;!   vi_print_pages_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_images) {&lt;br /&gt;!   vi_print_images_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_referers) {&lt;br /&gt;!   vi_print_referers_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;   if (Config_process_referers_age) {&lt;br /&gt;    vi_print_referers_age_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;***************&lt;br /&gt;*** 3205,3216 ****&lt;br /&gt;    vi_print_trails_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;   }&lt;br /&gt;!  vi_print_weekdays_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_hours_report(fp, vih);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;!  vi_print_credits(fp);&lt;br /&gt;!  vi_print_hline(fp);&lt;br /&gt;   vi_print_footer(fp);&lt;br /&gt;   if (of != NULL)&lt;br /&gt;    fclose(fp);&lt;br /&gt;--- 3231,3248 ----&lt;br /&gt;    vi_print_trails_report(fp, vih);&lt;br /&gt;    vi_print_hline(fp);&lt;br /&gt;   }&lt;br /&gt;!  if (Config_process_weekdays) {&lt;br /&gt;!   vi_print_weekdays_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_hours) {&lt;br /&gt;!   vi_print_hours_report(fp, vih);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;!  if (Config_process_credits) {&lt;br /&gt;!   vi_print_credits(fp);&lt;br /&gt;!   vi_print_hline(fp);&lt;br /&gt;!  }&lt;br /&gt;   vi_print_footer(fp);&lt;br /&gt;   if (of != NULL)&lt;br /&gt;    fclose(fp);&lt;br /&gt;***************&lt;br /&gt;*** 3301,3318 ****&lt;br /&gt;  /* ----------------------------------- main --------------------------------- */&lt;br /&gt;  &lt;br /&gt;  /* command line switche IDs */&lt;br /&gt;! enum { OPT_MAXREFERERS, OPT_MAXPAGES, OPT_MAXIMAGES, OPT_USERAGENTS, OPT_ALL, OPT_MAXLINES, OPT_GOOGLE, OPT_MAXGOOGLED, OPT_MAXUSERAGENTS, OPT_OUTPUT, OPT_VERSION, OPT_HELP, OPT_PREFIX, OPT_TRAILS, OPT_GOOGLEKEYPHRASES, OPT_GOOGLEKEYPHRASESAGE, OPT_MAXGOOGLEKEYPHRASES, OPT_MAXGOOGLEKEYPHRASESAGE, OPT_MAXTRAILS, OPT_GRAPHVIZ, OPT_WEEKDAYHOUR_MAP, OPT_MONTHDAY_MAP, OPT_REFERERSAGE, OPT_MAXREFERERSAGE, OPT_TAIL, OPT_TLD, OPT_MAXTLD, OPT_STREAM, OPT_OUTPUTFILE, OPT_UPDATEEVERY, OPT_RESETEVERY, OPT_OS, OPT_BROWSERS, OPT_ERROR404, OPT_MAXERROR404, OPT_TIMEDELTA, OPT_PAGEVIEWS, OPT_ROBOTS, OPT_MAXROBOTS, OPT_GRAPHVIZ_ignorenode_GOOGLE, OPT_GRAPHVIZ_ignorenode_EXTERNAL, OPT_GRAPHVIZ_ignorenode_NOREFERER, OPT_GOOGLEHUMANLANGUAGE, OPT_FILTERSPAM, OPT_MAXADSENSED, OPT_GREP, OPT_EXCLUDE, OPT_IGNORE404, OPT_DEBUG, OPT_SCREENINFO};&lt;br /&gt;  &lt;br /&gt;  /* command line switches definition:&lt;br /&gt;   * the rule with short options is to take upper case the&lt;br /&gt;   * 'special' options (the option a normal user should not use) */&lt;br /&gt;  static struct ago_optlist visitors_optlist[] = {&lt;br /&gt;   { 'A',  "all",   OPT_ALL,  AGO_NOARG},&lt;br /&gt;   { 'T',  "trails",  OPT_TRAILS,  AGO_NOARG},&lt;br /&gt;   { 'G', "google",  OPT_GOOGLE,  AGO_NOARG},&lt;br /&gt;   { 'K', "google-keyphrases", OPT_GOOGLEKEYPHRASES, AGO_NOARG},&lt;br /&gt;   { 'Z', "google-keyphrases-age", OPT_GOOGLEKEYPHRASESAGE, AGO_NOARG},&lt;br /&gt;!         { 'H',  "google-human-language", OPT_GOOGLEHUMANLANGUAGE, AGO_NOARG},&lt;br /&gt;   { 'U', "user-agents",  OPT_USERAGENTS,  AGO_NOARG},&lt;br /&gt;   { 'W',  "weekday-hour-map", OPT_WEEKDAYHOUR_MAP, AGO_NOARG},&lt;br /&gt;   { 'M',  "month-day-map", OPT_MONTHDAY_MAP, AGO_NOARG},&lt;br /&gt;--- 3333,3355 ----&lt;br /&gt;  /* ----------------------------------- main --------------------------------- */&lt;br /&gt;  &lt;br /&gt;  /* command line switche IDs */&lt;br /&gt;! enum { OPT_MAXREFERERS, OPT_MAXPAGES, OPT_MAXIMAGES, OPT_USERAGENTS, OPT_ALL, OPT_MAXLINES, OPT_GOOGLE, OPT_MAXGOOGLED, OPT_MAXUSERAGENTS, OPT_OUTPUT, OPT_VERSION, OPT_HELP, OPT_PREFIX, OPT_TRAILS, OPT_GOOGLEKEYPHRASES, OPT_GOOGLEKEYPHRASESAGE, OPT_MAXGOOGLEKEYPHRASES, OPT_MAXGOOGLEKEYPHRASESAGE, OPT_MAXTRAILS, OPT_GRAPHVIZ, OPT_WEEKDAYHOUR_MAP, OPT_MONTHDAY_MAP, OPT_REFERERSAGE, OPT_MAXREFERERSAGE, OPT_TAIL, OPT_TLD, OPT_MAXTLD, OPT_STREAM, OPT_OUTPUTFILE, OPT_UPDATEEVERY, OPT_RESETEVERY, OPT_OS, OPT_BROWSERS, OPT_ERROR404, OPT_MAXERROR404, OPT_TIMEDELTA, OPT_PAGEVIEWS, OPT_ROBOTS, OPT_MAXROBOTS, OPT_GRAPHVIZ_ignorenode_GOOGLE, OPT_GRAPHVIZ_ignorenode_EXTERNAL, OPT_GRAPHVIZ_ignorenode_NOREFERER, OPT_GOOGLEHUMANLANGUAGE, OPT_FILTERSPAM, OPT_MAXADSENSED, OPT_GREP, OPT_EXCLUDE, OPT_IGNORE404, OPT_DEBUG, OPT_SCREENINFO, OPT_CREDITS, OPT_GOOGLEVISITS, OPT_HOURS, OPT_IMAGES, OPT_INFORMATION, OPT_PAGES, OPT_REFERERS, OPT_REPORTLINK, OPT_VISITS, OPT_WEEKDAYS };&lt;br /&gt;  &lt;br /&gt;  /* command line switches definition:&lt;br /&gt;   * the rule with short options is to take upper case the&lt;br /&gt;   * 'special' options (the option a normal user should not use) */&lt;br /&gt;  static struct ago_optlist visitors_optlist[] = {&lt;br /&gt;   { 'A',  "all",   OPT_ALL,  AGO_NOARG},&lt;br /&gt;+  { '\0', "credits",  OPT_CREDITS, AGO_NOARG},&lt;br /&gt;   { 'T',  "trails",  OPT_TRAILS,  AGO_NOARG},&lt;br /&gt;   { 'G', "google",  OPT_GOOGLE,  AGO_NOARG},&lt;br /&gt;   { 'K', "google-keyphrases", OPT_GOOGLEKEYPHRASES, AGO_NOARG},&lt;br /&gt;   { 'Z', "google-keyphrases-age", OPT_GOOGLEKEYPHRASESAGE, AGO_NOARG},&lt;br /&gt;!  { 'H',  "google-human-language", OPT_GOOGLEHUMANLANGUAGE, AGO_NOARG},&lt;br /&gt;!  { '\0', "google-visits", OPT_GOOGLEVISITS, AGO_NOARG},&lt;br /&gt;!  { '\0', "hours", OPT_HOURS, AGO_NOARG},&lt;br /&gt;!  { '\0', "images", OPT_IMAGES, AGO_NOARG},&lt;br /&gt;!  { '\0', "information", OPT_INFORMATION, AGO_NOARG},&lt;br /&gt;   { 'U', "user-agents",  OPT_USERAGENTS,  AGO_NOARG},&lt;br /&gt;   { 'W',  "weekday-hour-map", OPT_WEEKDAYHOUR_MAP, AGO_NOARG},&lt;br /&gt;   { 'M',  "month-day-map", OPT_MONTHDAY_MAP, AGO_NOARG},&lt;br /&gt;***************&lt;br /&gt;*** 3322,3327 ****&lt;br /&gt;--- 3359,3369 ----&lt;br /&gt;   { 'B',  "browsers",  OPT_BROWSERS,  AGO_NOARG},&lt;br /&gt;   { 'X',  "error404",  OPT_ERROR404,  AGO_NOARG},&lt;br /&gt;   { 'Y',  "pageviews",  OPT_PAGEVIEWS,  AGO_NOARG},&lt;br /&gt;+  { '\0', "pages", OPT_PAGES, AGO_NOARG},&lt;br /&gt;+  { '\0', "referers", OPT_REFERERS, AGO_NOARG},&lt;br /&gt;+  { '\0', "report-link", OPT_REPORTLINK, AGO_NOARG},&lt;br /&gt;+  { '\0', "visits", OPT_VISITS, AGO_NOARG},&lt;br /&gt;+  { '\0', "weekdays", OPT_WEEKDAYS, AGO_NOARG},&lt;br /&gt;   { 'S', "robots",  OPT_ROBOTS,  AGO_NOARG},&lt;br /&gt;   { '\0', "screen-info",  OPT_SCREENINFO,  AGO_NOARG},&lt;br /&gt;   { '\0', "stream",  OPT_STREAM,  AGO_NOARG},&lt;br /&gt;***************&lt;br /&gt;*** 3343,3350 ****&lt;br /&gt;   { 'a', "max-referers-age", OPT_MAXREFERERSAGE, AGO_NEEDARG},&lt;br /&gt;   { 'd', "max-domains",  OPT_MAXTLD,  AGO_NEEDARG},&lt;br /&gt;   { 's', "max-robots",  OPT_MAXROBOTS,  AGO_NEEDARG},&lt;br /&gt;!         { '\0', "grep",                 OPT_GREP,               AGO_NEEDARG},&lt;br /&gt;!         { '\0', "exclude",              OPT_EXCLUDE,            AGO_NEEDARG},&lt;br /&gt;   { 'P',  "prefix",  OPT_PREFIX,  AGO_NEEDARG},&lt;br /&gt;   { 'o',  "output",  OPT_OUTPUT,  AGO_NEEDARG},&lt;br /&gt;   { 'V',  "graphviz",  OPT_GRAPHVIZ,  AGO_NOARG},&lt;br /&gt;--- 3385,3392 ----&lt;br /&gt;   { 'a', "max-referers-age", OPT_MAXREFERERSAGE, AGO_NEEDARG},&lt;br /&gt;   { 'd', "max-domains",  OPT_MAXTLD,  AGO_NEEDARG},&lt;br /&gt;   { 's', "max-robots",  OPT_MAXROBOTS,  AGO_NEEDARG},&lt;br /&gt;!  { '\0', "grep",                 OPT_GREP,               AGO_NEEDARG},&lt;br /&gt;!  { '\0', "exclude",              OPT_EXCLUDE,            AGO_NEEDARG},&lt;br /&gt;   { 'P',  "prefix",  OPT_PREFIX,  AGO_NEEDARG},&lt;br /&gt;   { 'o',  "output",  OPT_OUTPUT,  AGO_NEEDARG},&lt;br /&gt;   { 'V',  "graphviz",  OPT_GRAPHVIZ,  AGO_NOARG},&lt;br /&gt;***************&lt;br /&gt;*** 3357,3364 ****&lt;br /&gt;   { 'v',  "version",  OPT_VERSION,  AGO_NOARG},&lt;br /&gt;   { '\0', "tail",   OPT_TAIL,  AGO_NOARG},&lt;br /&gt;   { '\0', "time-delta",  OPT_TIMEDELTA,  AGO_NEEDARG},&lt;br /&gt;!         { '\0', "filter-spam",          OPT_FILTERSPAM,         AGO_NOARG},&lt;br /&gt;!         { '\0', "ignore-404",           OPT_IGNORE404,          AGO_NOARG},&lt;br /&gt;   { '\0', "debug",  OPT_DEBUG,  AGO_NOARG},&lt;br /&gt;   { 'h', "help",   OPT_HELP,  AGO_NOARG},&lt;br /&gt;   AGO_LIST_TERM&lt;br /&gt;--- 3399,3406 ----&lt;br /&gt;   { 'v',  "version",  OPT_VERSION,  AGO_NOARG},&lt;br /&gt;   { '\0', "tail",   OPT_TAIL,  AGO_NOARG},&lt;br /&gt;   { '\0', "time-delta",  OPT_TIMEDELTA,  AGO_NEEDARG},&lt;br /&gt;!  { '\0', "filter-spam",          OPT_FILTERSPAM,         AGO_NOARG},&lt;br /&gt;!  { '\0', "ignore-404",           OPT_IGNORE404,          AGO_NOARG},&lt;br /&gt;   { '\0', "debug",  OPT_DEBUG,  AGO_NOARG},&lt;br /&gt;   { 'h', "help",   OPT_HELP,  AGO_NOARG},&lt;br /&gt;   AGO_LIST_TERM&lt;br /&gt;***************&lt;br /&gt;*** 3462,3468 ****&lt;br /&gt;     Config_process_google_keyphrases_age = 1;&lt;br /&gt;     break;&lt;br /&gt;    case OPT_GOOGLEHUMANLANGUAGE:&lt;br /&gt;!                         Config_process_google_keyphrases = 1;&lt;br /&gt;     Config_process_google_human_language = 1;&lt;br /&gt;     break;&lt;br /&gt;    case OPT_TLD:&lt;br /&gt;--- 3504,3510 ----&lt;br /&gt;     Config_process_google_keyphrases_age = 1;&lt;br /&gt;     break;&lt;br /&gt;    case OPT_GOOGLEHUMANLANGUAGE:&lt;br /&gt;!    Config_process_google_keyphrases = 1;&lt;br /&gt;     Config_process_google_human_language = 1;&lt;br /&gt;     break;&lt;br /&gt;    case OPT_TLD:&lt;br /&gt;***************&lt;br /&gt;*** 3498,3504 ****&lt;br /&gt;     Config_process_error404 = 1;&lt;br /&gt;     Config_process_pageviews = 1;&lt;br /&gt;     Config_process_robots = 1;&lt;br /&gt;!                         Config_process_screen_info = 1;&lt;br /&gt;     break;&lt;br /&gt;    case OPT_PREFIX:&lt;br /&gt;     if (Config_prefix_num &lt; VI_PREFIXES_MAX) {&lt;br /&gt;--- 3540,3556 ----&lt;br /&gt;     Config_process_error404 = 1;&lt;br /&gt;     Config_process_pageviews = 1;&lt;br /&gt;     Config_process_robots = 1;&lt;br /&gt;!    Config_process_screen_info = 1;&lt;br /&gt;!    Config_process_credits = 1;&lt;br /&gt;!    Config_process_google_visits = 1;&lt;br /&gt;!    Config_process_hours = 1;&lt;br /&gt;!    Config_process_images = 1;&lt;br /&gt;!    Config_process_information = 1;&lt;br /&gt;!    Config_process_pages = 1;&lt;br /&gt;!    Config_process_referers = 1;&lt;br /&gt;!    Config_process_report_links = 1;&lt;br /&gt;!    Config_process_visits = 1;&lt;br /&gt;!    Config_process_weekdays = 1;&lt;br /&gt;     break;&lt;br /&gt;    case OPT_PREFIX:&lt;br /&gt;     if (Config_prefix_num &lt; VI_PREFIXES_MAX) {&lt;br /&gt;***************&lt;br /&gt;*** 3582,3605 ****&lt;br /&gt;    case OPT_TIMEDELTA:&lt;br /&gt;     Config_time_delta = atoi(ago_optarg);&lt;br /&gt;     break;&lt;br /&gt;!                 case OPT_FILTERSPAM:&lt;br /&gt;!                         Config_filter_spam = 1;&lt;br /&gt;!                         break;&lt;br /&gt;!                 case OPT_GREP:&lt;br /&gt;!                         ConfigAddGrepPattern(ago_optarg, VI_PATTERNTYPE_GREP);&lt;br /&gt;!                         break;&lt;br /&gt;!                 case OPT_EXCLUDE:&lt;br /&gt;!                         ConfigAddGrepPattern(ago_optarg, VI_PATTERNTYPE_EXCLUDE);&lt;br /&gt;!                         break;&lt;br /&gt;!                 case OPT_IGNORE404:&lt;br /&gt;!                         Config_ignore_404 = 1;&lt;br /&gt;!                         break;&lt;br /&gt;!                 case OPT_DEBUG:&lt;br /&gt;!                         Config_debug = 1;&lt;br /&gt;!                         break;&lt;br /&gt;!                 case OPT_SCREENINFO:&lt;br /&gt;!                         Config_process_screen_info = 1;&lt;br /&gt;!                         break;&lt;br /&gt;    case AGO_ALONE:&lt;br /&gt;     if (filenamec &lt; VI_FILENAMES_MAX)&lt;br /&gt;      filenames[filenamec++] = ago_optarg;&lt;br /&gt;--- 3634,3687 ----&lt;br /&gt;    case OPT_TIMEDELTA:&lt;br /&gt;     Config_time_delta = atoi(ago_optarg);&lt;br /&gt;     break;&lt;br /&gt;!   case OPT_FILTERSPAM:&lt;br /&gt;!    Config_filter_spam = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_GREP:&lt;br /&gt;!    ConfigAddGrepPattern(ago_optarg, VI_PATTERNTYPE_GREP);&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_EXCLUDE:&lt;br /&gt;!    ConfigAddGrepPattern(ago_optarg, VI_PATTERNTYPE_EXCLUDE);&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_IGNORE404:&lt;br /&gt;!    Config_ignore_404 = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_DEBUG:&lt;br /&gt;!    Config_debug = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_SCREENINFO:&lt;br /&gt;!    Config_process_screen_info = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_CREDITS:&lt;br /&gt;!    Config_process_credits = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_GOOGLEVISITS:&lt;br /&gt;!    Config_process_google_visits = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_HOURS:&lt;br /&gt;!    Config_process_hours = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_IMAGES:&lt;br /&gt;!    Config_process_images = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_INFORMATION:&lt;br /&gt;!    Config_process_information = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_PAGES:&lt;br /&gt;!    Config_process_pages = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_REFERERS:&lt;br /&gt;!    Config_process_referers = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_REPORTLINK:&lt;br /&gt;!    Config_process_report_links = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_VISITS:&lt;br /&gt;!    Config_process_visits = 1;&lt;br /&gt;!    break;&lt;br /&gt;!   case OPT_WEEKDAYS:&lt;br /&gt;!    Config_process_weekdays = 1;&lt;br /&gt;!    break;&lt;br /&gt;    case AGO_ALONE:&lt;br /&gt;     if (filenamec &lt; VI_FILENAMES_MAX)&lt;br /&gt;      filenames[filenamec++] = ago_optarg;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-6718134994550504568?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/w8AVxbCL0Sk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/6718134994550504568/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=6718134994550504568" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/6718134994550504568?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/6718134994550504568?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/w8AVxbCL0Sk/visitors.html" title="visitorsの出力を制御する" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/03/visitors.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQMRn45cCp7ImA9WxVbE0Q.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-3707078915469794939</id><published>2009-03-19T19:38:00.002+09:00</published><updated>2009-03-30T16:33:07.028+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-30T16:33:07.028+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Visitors" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>Visitors for CentOS5.2</title><content type="html">AmazonEC2上のCentOS5.2でApacheのアクセスログ解析が必要になったのでvisitorsでも試してみようかと。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# yum install visitors&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;とかではインストールできないのでrpmfindでバイナリパッケージを探すも、すんなりインストールされるrpmがなく、&lt;br /&gt;specファイルからビルドする事に。&lt;br /&gt;&lt;br /&gt;検索してみたところ、&lt;a href="http://oss.poyo.jp/websvn/log.php?repname=rpm&amp;path=%2Ftrunk%2Frpm%2Fvisitors%2Fvisitors.spec&amp;sc=1"&gt;specファイル&lt;/a&gt;が見つかったのでこれとソースtarballを使って&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# rpmbuild -bb --clean /usr/src/redhat/SPECS/visitors.spec&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これでビルド完了。&lt;br /&gt;ついでにspecファイルを少々直しておそらく使わないであろうgraphvizがなくてもインストールできるように。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#Requires:       graphviz&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;graphvizも面白い試みなんだけど、graphvizをインストールする際に依存するパッケージが多いので。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-3707078915469794939?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/irKh6aVY3T4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/3707078915469794939/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=3707078915469794939" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3707078915469794939?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3707078915469794939?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/irKh6aVY3T4/visitors-for-centos52.html" title="Visitors for CentOS5.2" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/03/visitors-for-centos52.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIESHkyeip7ImA9WxBTGU4.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-2263393607229040123</id><published>2009-03-13T18:02:00.006+09:00</published><updated>2009-12-16T12:18:29.792+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-16T12:18:29.792+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Amazon Web Services" /><title>Amazon EBS Snapshotスクリプト</title><content type="html">Amazon EC2 のサーバにあるデータのバックアップ、どうしてますか？&lt;br /&gt;S3に投げる？それもアリですけど、データをEBSに置くようにしているとSnapshotバックアップが簡単にできるので、&lt;br /&gt;これを自動化するスクリプトを書きました。Amazonのサービスはpythonのbotoというライブラリがいろいろできて便利。&lt;br /&gt;Usageの通り、第一引数(num)は世代数、volume-idは対象のEBS VolumeのIDを指定します。&lt;br /&gt;&lt;br /&gt;cronなんかに&lt;br /&gt;0 0 * * * /path/to/snapshot.py 7 vol-00000000&lt;br /&gt;という感じで登録しておく事を前提に作りました。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;import sys&lt;br /&gt;from boto.ec2.connection import EC2Connection&lt;br /&gt;&lt;br /&gt;if(len(sys.argv) != 3):&lt;br /&gt;    print "Usage: snapshot.py &amp;lt;num&amp;gt; &amp;lt;volume-id&amp;gt;"&lt;br /&gt;    sys.exit()&lt;br /&gt;&lt;br /&gt;conn = EC2Connection('aws_access_key','aws_secret_access_key')&lt;br /&gt;conn.create_snapshot(sys.argv[2])&lt;br /&gt;snapshot = {}&lt;br /&gt;for x in conn.get_all_snapshots():&lt;br /&gt;    if(x.volume_id == sys.argv[2]):&lt;br /&gt;        tmp = {x.id:x.start_time}&lt;br /&gt;        snapshot.update(tmp)&lt;br /&gt;snapshot = sorted(snapshot.items(), key=lambda (k, v): (v, k), reverse=True)&lt;br /&gt;for i in range(int(sys.argv[1]), len(snapshot)):&lt;br /&gt;    conn.delete_snapshot(snapshot[i][0])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2009/12/16修正：8行目のquit()をsys.exit()に変更しました。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-2263393607229040123?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/jc2hRBBez5w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/2263393607229040123/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=2263393607229040123" title="1 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/2263393607229040123?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/2263393607229040123?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/jc2hRBBez5w/amazon-ebs-snapshot.html" title="Amazon EBS Snapshotスクリプト" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/03/amazon-ebs-snapshot.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUCRng_fCp7ImA9WxVUGEQ.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-4015605616962294761</id><published>2009-02-05T16:43:00.003+09:00</published><updated>2009-03-24T21:21:07.644+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-24T21:21:07.644+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Amazon Web Services" /><title>CentOS5.2のAMI作成</title><content type="html">だいぶ以前に作ったものですが、&lt;a href="http://bba-ltom.blogspot.com/2008/04/gentoo-linuxami2.html"&gt;GentooのAMIを作った誰かさん&lt;/a&gt;のススメに従って&lt;br /&gt;CentOS5.2のAMIを公開してみました。&lt;br /&gt;&lt;br /&gt;AMI ID: ami-1fe40376&lt;br /&gt;Manifest: tmhrnskw.com/AMI/CentOS5.2-i386.manifest.xml&lt;br /&gt;&lt;br /&gt;作り方等は時間があれば別途。&lt;br /&gt;元々はRightScaleのイメージを使っていたのですが、CentOS5.2のイメージがなかなか&lt;br /&gt;安定していなかったり、RightScale社用のスクリプトが入っていたりするので&lt;br /&gt;シンプルでベーシックなイメージにしました。&lt;br /&gt;&lt;br /&gt;yum groupinstall core&lt;br /&gt;&lt;br /&gt;で入るパッケージくらいしか入っていないので、カスタマイズしてご利用ください。&lt;br /&gt;Timezoneの変更もお忘れなく。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-4015605616962294761?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/phcxwquge0A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/4015605616962294761/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=4015605616962294761" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/4015605616962294761?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/4015605616962294761?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/phcxwquge0A/centos52ami.html" title="CentOS5.2のAMI作成" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/02/centos52ami.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFRXo-fyp7ImA9WxVUGEQ.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-3304717660246713871</id><published>2009-01-14T10:23:00.003+09:00</published><updated>2009-03-24T21:20:14.457+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-24T21:20:14.457+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>ケースから欲しくなるiPod nano</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.eino.jp/products/EIAP01/images/EIAP01PA_main.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://www.eino.jp/products/EIAP01/images/EIAP01PA_main.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;現行のiPod nanoにあまり魅力を感じなかったので見送り気分だったのですが、&lt;br /&gt;たまたまコレを見て欲しくなった！&lt;br /&gt;&lt;a href="http://www.eino.jp/products/EIAP01/index.html"&gt;メーカーサイト&lt;/a&gt;を見る限り、売上の一部は国際環境NGO団体に寄付されるらしい。&lt;br /&gt;正直このテの寄付とか後追いせずに購入したいとは思わないタチですが、企画とデザインの勝利なのか商品に魅力は感じられます。丁度良いチープさと1,780円という手頃な価格設定も良いね。&lt;br /&gt;まさかケースが気に入って中身を欲しくなるとは。。&lt;br /&gt;&lt;br /&gt;ちなみに同メーカーサイトにあるDS Liteドレスアップフィルムとか、キーボードも気になる仕上がり。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-3304717660246713871?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/Qzurgqb735w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/3304717660246713871/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=3304717660246713871" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3304717660246713871?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/3304717660246713871?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/Qzurgqb735w/ipod-nano.html" title="ケースから欲しくなるiPod nano" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/01/ipod-nano.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYMSXczfyp7ImA9WxVUGEQ.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-7715018637462605321</id><published>2009-01-14T09:59:00.003+09:00</published><updated>2009-03-24T21:19:48.987+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-24T21:19:48.987+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Amazon Web Services" /><title>AmazonEC2でロードバランシング</title><content type="html">Amazon EC2を使う時に大活躍する&lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=609"&gt;Elasticfox&lt;/a&gt;ですが、AmazonからWebベースの&lt;a href="https://console.aws.amazon.com/"&gt;管理画面(Amazon Management Console)&lt;/a&gt;が提供されました。&lt;br /&gt;機能的にはElasticfoxと大差ないのですが、機能説明の一部、"Coming Soon!"に下記の記述が。&lt;br /&gt;&lt;blockquote&gt;Monitoring, Load Balancing and Auto-scaling - View real-time monitoring of operational metrics within Amazon EC2, configure load balancing and auto-scaling rules through a web-based UI. &lt;/blockquote&gt;&lt;br /&gt;CloudFrontでかなり利用の幅が広がったAWSですが、EC2でここまでやってくれると助かるなぁ。現状は監視ツール使ったりリバースプロキシ立ち上げたりしてますが、ロードバランシングとか自動スケーリングとか素晴らしいな、Amazon。パフォーマンスとか気になるけど。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-7715018637462605321?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/xBhMQ4mpJN0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/7715018637462605321/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=7715018637462605321" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/7715018637462605321?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/7715018637462605321?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/xBhMQ4mpJN0/aws-management-console.html" title="AmazonEC2でロードバランシング" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2009/01/aws-management-console.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFRXo-cCp7ImA9WxVUGEQ.&quot;"><id>tag:blogger.com,1999:blog-1832832471925430856.post-5542404661102079019</id><published>2008-12-22T14:11:00.003+09:00</published><updated>2009-03-24T21:20:14.458+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-24T21:20:14.458+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>MobileMeと税</title><content type="html">MobileMeの更新催促メールが届いた。&lt;br /&gt;Macユーザになってからとりあえず料金を払って登録してみたもののほとんど何も使っていない。&lt;br /&gt;使わない理由はデータを自分の直接管理外のメディアに保存することに抵抗があるからに他ならない。&lt;br /&gt;&lt;br /&gt;このまま更新するとまるで「Mac税」みたいなので更新をやめようかと思った。&lt;br /&gt;ふとiTunesを見ればアカウントに****@mac.com。。&lt;br /&gt;更新をやめると当然今iTunesで使っているアカウントは使えなくなるのだろうな。&lt;br /&gt;購入履歴とか再ダウンロードとか影響がありそうな気がする。&lt;br /&gt;「Mac税」ではなく「iTunes税」として支払続けるのか悩む。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1832832471925430856-5542404661102079019?l=2606-36j.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/2606-36J/~4/taHzWx0Iyss" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://2606-36j.blogspot.com/feeds/5542404661102079019/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1832832471925430856&amp;postID=5542404661102079019" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/5542404661102079019?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1832832471925430856/posts/default/5542404661102079019?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/2606-36J/~3/taHzWx0Iyss/mobileme.html" title="MobileMeと税" /><author><name>nskw</name><uri>http://www.blogger.com/profile/08949244153318981666</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://1.bp.blogspot.com/_T7Pt3YYwCZA/SX67gKekerI/AAAAAAAAANw/ByRiscOFFMU/S220/n1297030766_49556_3737.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://2606-36j.blogspot.com/2008/12/mobileme.html</feedburner:origLink></entry></feed>

