Vista で hosts ファイルを書き換えるには

Windows Vista では System 下のファイルを編集しようとするとアクセス拒否される。そういうときは、メモ帳(テキストエディタ)をスタートメニューから右クリックして、コンテキストメニューの「管理者として実行」から起動する。それから対象ファイルを開くと編集できる。 で、それが全うなやり方なのかと調べたら、http://support.microsoft.com/kb/923947/ja 全うでした。まあ、Windows 版 sudo vi /etc/hosts ということなのかな。

2008年1月22日 · Toshimitsu Takahashi

Solaris で logadm の設定(Apache のログをローテート)

以前書いたエントリは、直接 /etc/logadm.conf を書き換えていたが、作法としては下記のようにコマンドからエントリを登録する方が良い。 # logadm -w apache2 -p 1w -C 5 \ -t '$file.%Y-%m-%d' \ -a '/usr/apache2/bin/apachectl graceful' \ '/var/apache2/logs/*{access,error}_log' オプション -w [エントリ名] -p [ローテートする周期] Ny: N年 Nm : N月 Nw : N週間 Nd : N日 Nh : N時間 -C N ローテートしたファイルをN世代残す -t [ローテートしたファイルのテンプレート] -a [ローテート後に実行するコマンド]

2008年1月19日 · Toshimitsu Takahashi

Ruby で Premature end of script headers

CGI を作っていて、Premature end of script headers が全然消えない。 print ‘Content-Type:text/html\r\n\r\n’ ってシングルクォートで囲うと、\r\nが特殊文字ではなくそのままに認識されるのでした。 print “Content-Type:text/html\r\n\r\n” でないとダメ。 あと、require しているライブラリへのパーミッションがなかったりしても Premature end of script headers が起きる。 気づきにくかったのは popen での Broken Pipe エラー、これは呼び出していたスクリプトの実行権限がなかった。

2008年1月18日 · Toshimitsu Takahashi

「Suica 利用履歴から運賃を算出」ガジェットの UI をタブ仕様に変更

先日作った、Suica(スイカ)のガジェットだが、ユーザーインターフェイスが微妙だ。入出力のエリアを並べているので領域を広い。入力と出力が同時に見えている必要もないと思ったのでタブ化して分けてみた。それにタブ名をナビゲーションメッセージになったので、ちょっとわかりやすくなったかもしれない。 Google ガジェットでタブを使うには ModulePrefs で と使用を宣言。 1 2 3 4 5 <?xml version="1.0" encoding="utf-8"?> <Module> <ModulePrefs …> <Require feature="tabs" /> </ModulePrefs> 下記のようにタブのインスタンスを作って、addTab でタブのキャプションとそのタブの領域となる div タグの ID を引数に渡す。三番目の引数はタブが選択されたときのイベント関数を指定できる。chg の中で変換を走らせている。 1 2 3 var tabs = new _IG_Tabs(__MODULE_ID__); tabs.addTab("履歴を入力", "tabIn"); tabs.addTab("結果を表示", "tabOut", chg); タブ化すると、DOMツリーの構造が変わるため document.getElementById ではなく _gel(id) で取得する必要がある。 Content のソース 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 <script type="text/javascript"> <!-- String.prototype.trim = function() { return this.replace(/^\\s+|\\s+$/g, ''); }; String.prototype.getLines = function() { var lines = this.split("\\n"); for (var i=lines.length-1; i>=0; i--) { if (lines\[i\].trim().length == 0) { lines.splice(i, 1); } } return lines; }; function line2map(line) { var c = line.split(' '); if (c\[1\] == "物販") c\[2\] = c\[1\]; return { date: c\[0\], dept:c\[2\], arrv:c\[4\], acc: c\[5\].substr(1).replace(',',"") }; } function outtable(input) { try { var lines = input.getLines(); if (lines\[0\].indexOf('月/日') \> -1) lines.shift(); var i = lines.length - 1; var pre_acc = line2map(lines\[i\]).acc; var out = ""; while (--i >= 0) { if (lines\[i\].replace(' ',"").length == 0) continue; var item = line2map(lines\[i\]); if (item.dept.length > 0) { out += "<tr><td>" + item.date + "</td><td>" + item.dept + "</td><td>" out += item.arrv + "</td><td>" + (pre_acc - item.acc) + "</tr>"; } pre_acc = item.acc; } return '<table cellspacing="0" style="font-size:10.5pt" width="300">' + out + '</table>'; } catch(err) { return null; } } function chg(evt) { var textIn = _gel("textIn"); var ret = outtable(textIn.value); if (ret != null) _gel("textOut").innerHTML = ret; } function firstFocus(obj) { obj.value=''; obj.style.color='#000'; obj.onfocus = null; } //--> </script> <style type="text/css"> @import url(http://www.google.com/ig/tablib.css); </style> <div id="tabIn" style="height:135px;"> <textarea id="textIn" style="color:gray;font-size:10pt;width:100%;height:135px;overflow:scroll" onfocus="firstFocus(this)" onchange="chg()" >SF(電子マネー)利用履歴をペースト</textarea></td> </div> <div id="tabOut" style="height:135px;"> <div id="textOut" style="font-size:10.5pt;height:135px;padding:2px 0;overflow:scroll"></div> </div> <script> var tabs = new \_IG\_Tabs(\_\_MODULE\_ID__); tabs.addTab("履歴を入力", "tabIn"); tabs.addTab("結果を表示", "tabOut", chg); </script>

2008年1月14日 · Toshimitsu Takahashi

Google AJAX Feed API と jQuery でフィードをスライドショー表示するガジェットを作る

先日、オライリーの Amazon ベストセラートップ 10 のフィードを生成をした。それを今度はスライドショーっぽく表示するガジェットを作ってみる。 フィードの取得には、Google Feed API — Google Developers を使う。これで RSS/ATOM の規格に左右されないし、サーバーサイドの中継 CGI を作る必要もなくなる。 スライドショー表示はクロスフェードさせたい。Prototype + Rico より jQuery (http://jquery.com/) の方が簡単だと思うのでこちらを選択した。 Google AJAX Feed API まずは Sign-up for an API Key - Google Loader — Google Developers でアクセスキーを取得する。 Google.load はおまじない。1 はバージョンらしい。 <script type="text/javascript" src="http://www.google.com/jsapi?key=キー"></script> <script type="text/javascript"> google.load("feeds", "1"); Google.feeds.Feed(フィードのURL) で取得の準備。 setNumEntries はエントリをいくつ取るかを設定する(デフォルトは 4)。 load でコールバック関数を指定する。 Google.setOnLoadCallback(initialize); で初期化関数をロード時に実行するようにする。 取得したフィード情報は、result.feed で取れる。通常だと JSON で返る。 http://code.google.com/intl/ja/apis/ajaxfeeds/documentation/reference.html#JSON 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function initialize() { var feed = new google.feeds.Feed("http://feed.tilfin.net/amazon/oreilly-bestseller.xml"); feed.setNumEntries(10); feed.load(function(result) { if (!result.error) { var container = document.getElementById("container"); for (var i = 0; i < result.feed.entries.length; i++) { var entry = result.feed.entries\[i\]; var div = document.createElement("div"); div.innerHTML = '<a target="_blank" href="' + entry.link + '"><p>' + entry.title + '</p><div class="ctn">' + entry.content + '</div></a>'; div.className = 'page'; div.id = "page" + i; container.appendChild(div); if (i > 0) $("#page" + i).hide(); } pages = result.feed.entries.length; } }); } google.setOnLoadCallback(initialize); </script> まあ、サンプル見てわかるとおり、とても簡単。 ...

2008年1月13日 · Toshimitsu Takahashi

REXML と Libxml-Ruby とのエンティティ出力比較

REXML で大きな XML ファイルを処理したらあまりにも遅かった。Ruby で書かれているのでいたし方ないんですが。もちろん REXML は標準でついているし、手軽に使えて良いという大きなメリットがあるけど、行う処理が数時間レベルなので速くしたい。そこで Libxml http://libxml.rubyforge.org/ を試すことに。 行うのは XML → XML 変換なので、エンティティの出力が気になった。そこで次のようなコードを実行して、結果を比較してみる。 テストしたコード 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #!/usr/bin/env ruby # require 'rubygems' require 'xml/libxml' require 'rexml/document' str =<<EOS <?xml version="1.0" encoding="UTF-8"?> <root> <title>Tosshi&apos;s メモ書き</title> <array> <item attr='&apos;'> &lt;html&gt; &apos;TAG&quot; </item> <item attr="&quot;"><!\[CDATA\[ CDATA &lt;html&gt; &apos;TAG&qout; <>"' \]\]></item> </array> </root> EOS puts <<EOS \[ libxml-ruby \] EOS xp = XML::Parser.new xp.string = str libxmldoc = xp.parse puts "document :" puts libxmldoc node = libxmldoc.root.find_first("title") print "Node :" puts node print "content :" puts node.content print "child.to_s:" puts node.child.to_s libxmldoc.root.find("array/item").each do |item| print "Node :" puts item print "content :" puts item.content print "child.to_s:" puts item.child.to_s end puts <<EOS \[ REXML \] EOS rexmldoc = REXML::Document.new(str) puts "Document :" puts rexmldoc el = rexmldoc.root.elements\["title"\] print "Element :" puts el print "text :" puts el.text print "get_text :" puts el.get_text rexmldoc.root.elements.each("array/item") do |item| print "Element :" puts item print "text :" puts item.text print "get_text :" puts item.get_text end 結果 libxml はアポストロフィとダブルクォートを必要なときだけ実体名にエスケープする。 REXML は属性値は固定でアポストロフィで囲い、アポストロフィとダブルクォートは必ず実体名にエスケープする。 $ ruby testxml.rb \[ libxml-ruby \] Document : <?xml version="1.0" encoding="UTF-8"?> <root> <title>Tosshi's メモ書き</title> <array> <item attr="'"> &lt;html&gt; 'TAG" </item> <item attr="&quot;"><!\[CDATA\[ CDATA &lt;html&gt; &apos;TAG&qout; <>"' \]\]></item> </array> </root> Node :<title>Tosshi's メモ書き</title> content :Tosshi's メモ書き child.to_s:Tosshi's メモ書き Node :<item attr="'"> &lt;html&gt; 'TAG" </item> content : <html> 'TAG" child.to_s: &lt;html&gt; 'TAG" Node :<item attr="&quot;"><!\[CDATA\[ CDATA &lt;html&gt; &apos;TAG&qout; <>"' \]\]></item> content : CDATA &lt;html&gt; &apos;TAG&qout; <>"' child.to_s:<!\[CDATA\[ CDATA &lt;html&gt; &apos;TAG&qout; <>"' \]\]> \[ REXML \] Document : <?xml version='1.0' encoding='UTF-8'?> <root> <title>Tosshi&apos;s メモ書き</title> <array> <item attr='&apos;'> &lt;html&gt; &apos;TAG&quot; </item> <item attr='&quot;'><!\[CDATA\[ CDATA &lt;html&gt; &apos;TAG&qout; <>"' \]\]></item> </array> </root> Element :<title>Tosshi&apos;s メモ書き</title> text :Tosshi's メモ書き get_text :Tosshi&apos;s メモ書き Element :<item attr='&apos;'> &lt;html&gt; &apos;TAG&quot; </item> text : <html> 'TAG" get_text : &lt;html&gt; &apos;TAG&quot; Element :<item attr='&quot;'><!\[CDATA\[ CDATA &lt;html&gt; &apos;TAG&qout; <>"' \]\]></item> text : CDATA &lt;html&gt; &apos;TAG&qout; <>"' get_text : CDATA &lt;html&gt; &apos;TAG&qout; <>"'

2008年1月11日 · Toshimitsu Takahashi

Suica 履歴の残額表示が使えないので、各運賃を算出するガジェットを作ってみた。

お勤めの人は会社で交通費の精算をやると思うんですね。 モバイル Suica を利用してるとネットでも JR東日本:モバイルSuica>会員メニュー 履歴を見られて便利なんですが、各乗車の運賃が出ないでその降車時の残額しか出ないのがいただけない。 ということで、SF利用履歴のページの表の部分をコピペするだけで運賃算出してくれる Google ガジェットを作ってみました。 ポイントと仕様 各項目のスペースは全角、区切りは半角なのでパースは楽。 この手のツールは対象の出力のしかたが変わってしまうと動かなくなるから寿命が短いかも。 先頭の列定義の行があっても無視するようにした。 キヨスク等での買い物分は出力し、チャージ分は出さないようにしている。 変換ボタンを押さなくても、テキストエリアからフォーカスが移ったときにコンバートするようにしている(textarea の onchange の動きがイマイチだったため)。 Content のソース 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 <script type="text/javascript"> <!-- String.prototype.trim = function() { return this.replace(/^\\s+|\\s+$/g, ''); }; String.prototype.getLines = function() { var lines = this.split("\\n"); for (var i=lines.length-1; i>=0; i--) { if (lines\[i\].trim().length == 0) { lines.splice(i, 1); } } return lines; }; function line2map(line) { var c = line.split(' '); if (c\[1\] == "物販") c\[2\] = c\[1\]; return { date: c\[0\], dept:c\[2\], arrv:c\[4\], acc: c\[5\].substr(1).replace(',',"") }; } function outtable(input) { try { var lines = input.getLines(); if (lines\[0\].indexOf('月/日') \> -1) lines.shift(); var i = lines.length - 1; var pre_acc = line2map(lines\[i\]).acc; var out = ""; while (--i >= 0) { if (lines\[i\].replace(' ',"").length == 0) continue; var item = line2map(lines\[i\]); if (item.dept.length > 0) { out += "<tr><td>" + item.date + "</td><td>" + item.dept + "</td><td>" out += item.arrv + "</td><td>" + (pre_acc - item.acc) + "</tr>"; } pre_acc = item.acc; } return '<table cellspacing="0" style="font-size:10.5pt" width="300">' + out + '</table>'; } catch(err) { return null; } } function chg(evt) { var textIn = document.getElementById('textIn'); var ret = outtable(textIn.value); if (ret != null) document.getElementById('textOut').innerHTML = ret; } function firstFocus(obj) { obj.value=''; obj.style.color='#000'; obj.onfocus = null; } //--> </script> <div id="content_div" style="border-bottom:2px solid #474;padding-top;3px;"> <table style="width:100%;" cellspacing="0"> <tr> <td><textarea id="textIn" style="float:left;color:gray;font-size:10pt;width:100%;height:75px" onfocus="firstFocus(this)" onchange="chg()" >SF(電子マネー)利用履歴をペースト</textarea></td> <td width="40"><button style="float:left;width:40px;height:75px;" onclick="chg()">変換</button></td> </tr> </table> <div id="textOut" style="border-top:2px solid #474;margin-top:3px;padding-top;3px;clear:left;height:108px;overflow:scroll"></div> </div>

2008年1月8日 · Toshimitsu Takahashi

Ruby の REXML と RSS Maker で Amazon で売れてるオライリー本のフィードを簡単に作る

使用したライブラリ open-uri rexml/document rss/maker RSS Parser ※ We retire raa.ruby-lang.org という Amazon Web Service を簡単に使えるライブラリも存在するが、単にリストを取得するだけなので今回は見送った。 コード RSS 2.0 で出力する。RSS::Maker.make(version) で引数にバージョンを入れて指定する。 Description にイメージと著者、出版日、価格を入れている。Author は複数タグあるため、カンマで結合。 同じようなものを仕事で Java で作ったことがあったが、Ruby などの Light Weight 言語の手軽さを知ってしまうと戻れない。 結果: http://feed.tilfin.net/amazon/oreilly-bestseller.xml 下記のコードでは、ファイル書き出しをコメントアウトして、CGIとしての動作を有効にさせている。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #!/usr/bin/env ruby # # Amazon O'Relly Sales Ranking # Rss feed # ################################# require 'open-uri' require 'rexml/document' require 'rss/maker' param = { 'Service' => 'AWSECommerceService', 'AWSAccessKeyId' => '☆アクセスキーID☆', 'AssociateTag' => '☆アソシエイトID☆', 'Operation' => 'ItemSearch', 'SearchIndex' => 'Books', 'ResponseGroup' => 'Medium', 'Sort' => 'salesrank', 'Publisher' => 'オライリー' } params = param.map do |key, value| "#{URI.encode(key)}=#{URI.encode(value)}" end.join("&") doc = nil open('http://webservices.amazon.co.jp/onca/xml?' + params) { |resp| doc = REXML::Document.new(resp) } rss = RSS::Maker.make("2.0") do |maker| maker.channel.title = "O'Reilly ベストセラー (Amazon)" maker.channel.description = "O'Reilly の Amazon.co.jp のセールストップ 10 を紹介" maker.channel.link = "http://feed.tilfin.net/amazon/orelly-bestseller.xml" number = 0 doc.elements.each("/ItemSearchResponse/Items/Item") do |item| itmat = item.elements\["ItemAttributes"\] number += 1 entry = maker.items.new_item entry.title = number.to_s + '. ' + itmat.elements\["Title"\].text entry.link = item.elements\["DetailPageURL"\].text desc = nil item.elements.each("MediumImage") { |img| desc = <<EOS <img src="#{img.elements\["URL"\].text}" width="#{img.elements\["Width"\].text}" height="#{img.elements\["Height"\].text}"><br> EOS } desc += itmat.elements.each("Author") { |a| a.text }.join(", ") + " (著)" desc += "<br>発売日:" + itmat.elements\["PublicationDate"\].text.gsub(/-/, '/') desc += "<br>" + itmat.elements\["ListPrice/FormattedPrice"\].text entry.description = desc entry.date = Time.now end end print "Content-Type:application/rss+xml\\r\\n\\r\\n" print rss #open("oreilly-bestseller.xml", "w") { |out| \# out.print rss #} #``` ※IE7だと application/rss だけではフィードだと認識されなかった。

2008年1月3日 · Toshimitsu Takahashi

REXML

Ruby の XML ライブラリ REXML を試す。(REXML - Home) Rubyクックブック ―エキスパートのための応用レシピ集 を買ったが、REXML については書かれていない。オリジナルの Ruby Cookbook (Cookbooks (O’Reilly)) には REXML が一章使われて説明されているらしい。 #!/usr/bin/env ruby require “rexml/document” include REXML xml = «EOS メモ 日本語 ENGLISH EOS doc = Document.new xml doc.elements.each("/records/record") do |el| el.elements.each("item") do |item| puts item item.elements.each("title") { |e| puts e.text } item.elements.each("title\[1\]") { |e| puts e } item.elements.each("title\[2\]") { |e| puts e.text } item.elements.each("title\[@lang='ja'\]") { |e| puts e.text } item.elements.each("title\[@lang='en'\]") { |e| puts e } end end puts doc.root.elements\["memo"\].text 実行結果 ...

2007年12月31日 · Toshimitsu Takahashi

ビルドツール Jam

http://freetype.sourceforge.net/jam/index.html:tile が OCRopus のインストールで必要になったので、入れた。 https://sourceforge.net/project/showfiles.php?group_id=3157 から ftjam をダウンロードする。 $ gunzip -c ftjam-2.5.2-linux-i386-glibc6.tar.gz | tar xvf - $ sudo cp jam /usr/local/bin/ Official Site: Jam | Perforce

2007年12月22日 · Toshimitsu Takahashi