■ このページについて ■
パソコン関係の雑記。ソフトからハードまでまんべんなく。
2001年が最盛期で、「テキストだけで90KB」もザラ。
一時期おとなしくなったけど、管理のCGI化によって息を吹き返し中。
2003.4.2.Wed
あなたが今見ている、このページが置いてあるサーバー。俺が使っているレンタルサーバー。半年探し続け、ようやく見つけたレンタルサーバー。ナウでヤングなレンタルサーバー。女の子のためのちょっとHなレンタルサーバー。人に薦めるのがちょっぴり恥ずかしいレンタルサーバー。会社名が素で赤面クラスなため、もう「Velvet」という会社名として扱っているレンタルサーバー。
それでいて、これ以上の条件はなさそうな、至高のレンタルサーバー。
私はエキスパートプラン。どのディレクトリでもCGI使い放題。Perl・Ruby・PHP・SSI、なんでもござれ。.htaccess も .htpasswd も使えてあたり前。サーバーマシンのCPUは余裕のギガヘルツ。しかも少人数制。ディスク容量は無敵の200MB。さらにはサブドメインが標準付属。おまけにメールサーバーは IMAP 対応。ついでに商用利用可。あまつさえ同人絵に限ってはエロOKなんて前代未聞の規約。(最後のは別にメリットになってないんですが)
さて、How match ?
答えは年10000円=月833円。(普通、これだけの条件を要求すると3〜4倍は取られます)
そんなある日っていうか今日、至高のレンタルサーバーからメールが届いた。内容は「プラン撤廃のお知らせ」。なんでも、従来のライト・スタンダード・エキスパートといったプラン制度が、4月14日で廃止されるそうで。それに伴い、価格やディスク容量も変更される、と。なまじ条件が良いだけに、これって嫌な予感がするよね。しない?
変更後の価格はライトプランと同額。
変更後の容量はエキスパートプランと同量。
さて、How match ?
答えは年3000円=月250円。
すなわち、怒涛の値下げ。つぅか7割引ですよ?
(ちなみにライトプランの人は同額でエキスパートプランを使えることになります)
あぁん!もう一生ついて行きます!
…とは素直に喜ばない、疑い深い私。肝心のクォリティ(特にスピード面)が落ちては意味ないのよね。ましてや、損益分岐点を割ってしまっては元も子もないのよね(潰れるから)。値下げはもちろん歓迎だけど、その辺がちょっと気になります。サービスが落ちるくらいなら、従来の価格の方がいいんだけど。「安かろう悪かろう」を地で行くYah○○BBみたいなのは困るよ。どうせなら吉野家にしてほしいな。
至高のレンタルサーバー、lolipop。頑張ってください。ぴろあきは応援してますよ。真剣な顔で。ここはsiteCTSの新天地なのですから。
2003.4.5.Sat
普段からDOMだのDHTMLだのとスクリプトを組んでいると、どうも「ブラウザのシェア」に対する判断の境界がぼやけてくる。Netscape6&7 が1割にも満たないドマイナーなブラウザだなんてこれっぽちも思ってないし、Opera はIE・Netscape とシェアを分かち合う、普及レベルに達したブラウザである…なんて思っている。
こういった誤認識はどのように扱えばいいのだろう?
2003.4.6.Sun
前々から疑問に思ってたんだけど、なんで ECMAScript には getElementsByClassName()
ってメソッドはないのだろう。getElementsByTagName()
とか getElementsByName()
はあるのに、これがないのは不思議極まりない。特定要素のクラスを一括変更…とかやりたい時、便利だと思うんだけどなぁ。
…というわけで作ってみた。「指定した class
の要素を配列で取得」するメソッド。
document.getElementsByClassName = function (c, t) {
t = this.getElementsByTagName(t ? t : "*");
for (var i = 0, r = new Array(), l = t.length; i < l; i++)
if (t[i].className == c)
r[r.length] = t[i];
return r;
}
document.getElementsByClassName("cName", "a");
とすると、<a class="cName">
の要素を配列で返却。第2引数を省略すると、全要素が対象。
当然ながら getElementsByTagName()
に対応してないといけないので、IE5以降・Netscape6以降・Opera6以降でしか動かぬ。でもIE4なら document.all.tags()
という同じ機能のメソッドがあるから、ほんのちょっと直すだけで対応できる。(当サイトのスクリプトはIE4を対象外にしてるので必要なかったり)
そういえば、まだ getElementsByName()
を憶えたての頃、これと同じような感じで「getElementsById()
はないのかにょう?」などと思ってたなぁ。指定したIDの要素を配列で取得…って、HTMLをさっぱりわかってない証拠ですな。(IDはその文書中でユニークでないといけないので、sがあってはいけないよ)
※これはクラスのメソッドとして実装してるので、実際には↓となっている。
//class="class1 class2"みたいな「多重クラス」にも対応した正規表現版
sakura.prototype.classes = function (c, t) {
var reg = new RegExp("(^| )" + c + "( |$)");
var i = 0, r = new Array(), t = this.tags(t ? t : "*"), l = t.length;
for (; i < l; i++)
if (t[i].className.match(reg))
r[r.length] = t[i];
return r;
}
2003.4.7.Mon
1月20日に作った「ローカルサーバー接続時でもIEから直接ファイルを開ける拡張コンテキスト」が、どうも使いにくいのでリファイン。これは右クリックメニューに登録しておき、選択するとIEからページのURLを取得してローカルファイルのパスに整形し、お好みのテキストエディタで開く…というスクリプト。サーバー側のページを見ている時でも直でファイルを開けるので、とても便利。
しかし、当サイトはデフォルトインデックスに index.html を使用してない関係上、URLが http://127.0.0.1/transient/scn/psn/ みたいにファイル名がない時、「このディレクトリのデフォルトインデックスは 03-2.html である」という情報を得られないのである。たとえ AnHTTPd が .htaccess に対応してたとしても無理。
ほとんどは「そのディレクトリ名と同じファイル名」であり、abc ディレクトリのデフォルトインデックスは abc.html になってるんだけど、必ずそういうわけではないのが痛いところで。(パ奮みたいなコンテンツでは、デフォルトインデックスを abc.html で固定すると、バックナンバーを作った時に古い記事のURIが変わってしまうので)
つまるところ、どこかにファイル名の情報を書かないといけない。どこに書くかと言えば、当然 abc.html に書くのが一番確実で早い。これをスクリプトで拾えばいい。(スクリプト本体に設定を書く手もあるけど、これは頭の悪い方法だ)
しかし、HTMLにそんな無意味情報を書く場所が見つからない。「ValidなHTML」はとにかく面倒くさいのだ。
ようやく見つけた場所、そこは <meta>
要素。「ファイル名」はメタな情報と言えるから、用途としては Valid だろう。都合の良いことに、name
属性の動作が定義されてない。HTML lint もエラーを出さないし、そういえば WWWC も <meta name="WWWC" content="更新情報">
を使っている。HTTP ヘッダに余計な情報が入ってしまうが、問題はないはずだ。
…決まりだな。
<meta name="filename" content="abc.html">
この1行をファイルに入れておき、
window.external.manuArguments.document.getElementsByName("filename")[0].content;
として拾えばいい。さらに、<meta name="filename">
がない時はエラーになるので、例外処理(try catch
構文)を使って「エラーが起きたら index.html を開く」とした。index.html もない時は…知らぬ。
また、Webサーバー側のページを見ている時でも直接ファイルを開けるようにした。ローカルとサーバーのディレクトリ構造が同じである必要があるが、違う人もそうそういないのでは。もちろん、該当しないページで実行した時は普通に view-source:
で開くので、標準の「ソースの表示」はやや不要になる。(CGIやSSIの出力結果を見る時に必要)
<script type="text/jscript">
//設定関数
function initialize(ServerList) {
//開こうとするURLが下のサーバーリストにある時、以下の設定を適用
//それ以外やローカルの時は関係なし(そのまま view-source: で開けるので)
//ローカルファイルとみなすサーバーのリスト
//サーバーとローカルのフォルダ構成が同じでないと正常に動かない
ServerList["127.0.0.1"] = 1; //サーバーが http://127.0.0.1/ の場合
ServerList["cts.velvet.jp"] = 1;
//ServerList["www.MyServer.ad.jp"] = 1; //サーバーが http://www.MyServer.ad.jp/ の場合
//開こうとするファイルが上記のサーバーだった場合、サーバー名の部分を DocumentRoot に置換する
//フォルダの区切りは \ でなく / を使用
DocumentRoot = "F:";
//DocumentRoot = "C:/My Documents/MyWebSite"; //トップページがあるフォルダのパス(最後に / は入れない)
//例:http://127.0.0.1/abc/top.html → C:/My Documents/MyWebSite/abc/top.html に置換してファイルを開く
//ソースを表示するテキストエディタのパス
//フォルダの区切りは \ でなく / を使用
EditorPath = "C:/Apps/Hidemaru/Hidemaru.exe";
//EditorPath = "C:/Windows/notepad.exe";
//デフォルトのファイル名(デフォルトインデックス)
//ファイルに<meta name="filename" content="ファイル名">がある時はそっちが優先
DefaultIndex = "index.html";
//注意
//URLが http://127.0.0.1/abc/ のように「ファイル名がない」場合、上記の DefaultIndex を補完します。
//DefaultIndex のファイルがない時は正常に動きません。
//.htaccess などでデフォルトインデックスを変更している場合、HTMLのソースに
//<meta name="filename" content="page.html">
//を入れておくと、DefaultIndex の代わりに page.html を補完するようになります。
//DefaultIndexも<meta>も両方ある時は、<meta>が優先されます。
//ファイルがCGIの時の注意
//CGIでHTMLを出力する時は、
//<meta name="filename" content="perl.cgi">
//のように<meta>も出力しておくと対応できます。
//なお、<meta>タグの name の値は好みに応じてカスタマイズできます。
MetaTagNameAttributeValue = "filename";
return ServerList;
}
//本体関数
function viewSrc(svr, ext) {
var l = ext.location, p = ext.location.href;
if (svr[l.host]) {
p = new String(p.match(/[^?#]+/));
if (p.charAt(p.length -1) == "/") {
//ここが今回話題の部分
try {
p += ext.document.getElementsByName(MetaTagNameAttributeValue)[0].content;
} catch(e) {
p += DefaultIndex;
}
}
p = p.replace("http://" + l.host, DocumentRoot);
(new ActiveXObject("Shell.Application")).ShellExecute(EditorPath, p);
} else
l.href = "view-source:" + l.href;
}
var DocumentRoot, EditorPath, DefaultIndex, MetaTagNameAttributeValue;
viewSrc(initialize([]), window.external.menuArguments);
</script>
毎度のことながら、コメントがバラまく気満々であることをうかがわせる。もちろんそんな予定はないのだけど。(レジストリをいじらにゃならんので素人の手には負えない)
2003.4.13.Sun
2002.11.8に作成を始めた ExpContext に、ようやくまっとうなインターフェイスを作ってやった。また、3回に1回は動かないという手法上のバグも改善され、10回に1回まで軽減された。
右クリックメニューから実行されたスクリプトは、ウィンドウなどのコンテナを持たない純粋なスクリプトである。処理が終わり次第、即刻消え去ってしまう。従って、ExpContext のようなインターフェイスを与えるためには、そこからさらにウィンドウを開き、external
オブジェクトをうまく渡してやらないといけない。これがどうもうまくいかないのである。なんか良いアイデアはないものだろうか。
で、下のふたつは新しく追加された機能で、いずれもサイト管理用である。
今のところ、ExpContext が開いてる時に、さらに ExpContext を開こうとするとエラーが起きるのだが、これは解決するべきだろうか。window.onblur = window.close;
でも仕こむか?
ExpContext.htm(ウィンドウを開く踏み台) ExpContext.html(本体)
2003.4.15.Tue
久しぶりに騙る機会に恵まれたので、お得意の長文でメールの返信に JavaScript のことなど延々と書いたのだ。10KBは余裕で書いただろうか。このパチョ奮闘記で好きなだけ書いてるように見えるが、反応を期待してるわけでもなければ、話の通じる人が見る可能性もないコレは、所詮 "独り言" でしかない。一応「書いたら満足、あとは知らぬ」であるのだけど、やはり一方通行よりゃ双方向の方が良いに越したこたぁない。
うむ。なかなかの出来だ。
しかし、これをすぐに送るような真似はしない。なにせ相手は知らない人。一晩二晩は寝かせ、じっくり推敲するのである。礼儀を通したメールには、礼儀を通した返信をしなければならない。
次の日。nPOPQ を起動すると、昨日書いたメールがどこにもない。送信箱にもないし、保存箱にもない。あたり前だが受信箱にもない。おやおや。
nPOPQ では外部エディタを設定し、メール本文は秀丸で書いている。言うまでもなく、使い慣れたエディタの方が書きやすいからだ。そこで注意するべきは、必ず秀丸を先に閉じないといけないことである。nPOPQ は秀丸の終了を検知して内容を更新するため、先に閉じてしまうと書いたメールが更新されないまま消えてしまうのだ。
うむ。そういえば…。
なに、こういう時に備え、秀丸には自動バックアップが付いている。焦る必要などどこにもない。なんと便利なエディタなのだろう。
ところが、バックアップフォルダを探してもお目当てのファイルがない。nPOPQ が秀丸へ渡す時に作る一時ファイル名は特殊なので、簡単に見つかるはずなのだけど。おかしい。おかしい。焦る必要が出てきた。
まさかと思って秀丸の設定を確認してみると、…そこにはお決まりのオチが隠されていた。一応 grep でHDの全検索も施したが、徒労に終わった。
こうして、多くの時間を費やして書き上げたメールは、0と1の狭間へと失われた。データを失うことの悲劇を何度も味わい、「ディジタルの弱点」を何度も痛感し、バックアップは念入りにやっている俺でも、こういう事態は回避できない。これだからディジタルは嫌なのだ。
頑張って書き直しはしたものの、あれだけの量を復元するのは不可能であり、なにより気力の時点で以前を超えるものは書けなかった。
まことにしょんぼりである。
2003.4.18.Fri
4.13にバージョンアップしたばっかの ExpContext を、さらに作り直し。構造上のバグがまだ残っていて、どうにも気分が悪いからだ。3.16で言ってたような「骨格の時点で間違えてる」類いのバグなので、もう根っこから組みなおす必要がある。(といっても、まだ規模がちっちゃいので苦労しなかったけど)
external
オブジェクトを渡す 今までこのようなプロセスだったのだけど、4. で external
オブジェクトをうまく渡せないことが多かったのである。というか、どう考えても 3. が美しくない。
そこで、これを
external
オブジェクトを渡す…というプロセスに改良。HTMLを JavaScript で書き出すのは面倒くさいので避けたかったのだけど、致し方ない。スクリプト本体は外部ファイルにし、別途ロードすることにした。これにより、「起動用・本体」という2ファイル構成から、「起動用・スクリプト・表示用CSS」の3ファイル構成となった。(本体はスクリプトから生成される)
結果、バグは見事に改善し、待機用の無駄処理もなくなって軽快に動くようになった。よしよし。
2003.4.21.Mon
過去(2001年末あたり)、siteCTSにはインデックスサーチという機能があった。トップの index.html に引数を渡してやることで、目的のページへオートジャンプさせるものだ。
実例:http://cts.creasus.net/public/index.html?dir=snp&anc=011216
この機能はファイル名などが変更されても柔軟に対処できるという大きなメリットがあったが、JavaScript を使って実現しているため、非対応ブラウザだったり機能がオフだったりすると無効になる、致命的な欠点があった。それがゆえに、ほとんど使われることはなかった。
そんな苦い想い出から1年半。状況は変わった。siteCTSはCGIの使えるサーバーへ移転し、俺も少しはPerlを使えるようになった。
ご存知の通り、CGIはブラウザに依存しないので、JavaScript のような欠点がない。インデックスサーチのようにブラウザ依存では困る機能は、まさにCGIの独壇場なのだ。
このパチョ奮闘記では、過去記事へのリンクが頻繁にある。しかし今見ている Transient Edition のパチョ奮闘記には、2002年1月以前の記事がないため、バックナンバーの参照はすべてリニューアル前のサイト(Public Edition)へ連れて行く。
が、リニューアル後の Valid Edition では、すべての記事が収められる。つまり、通常であれば全部のリンクを Valid Edition 用に修正しないといけない。ここにインデックスサーチを使うことで、
#index.cgiの一部
#2001年〜2002年1月
if ($sY eq '01' || ("$sY$sM" eq '0201')) {
if ("$sY$sM" eq '0101') { #2001年1月の記事は存在しない
&err('&shortIndexSearch().snp.date.failed');
}
$e = 'public'; #Public Edition
$c = 'snp'; #コンテンツ
$f = "$sY$sM/_$sY$sM.html"; #ファイルのパス
if ($sD ne '') {
$a = int($sD); #日付アンカー
}
}
この部分をちょちょっと修正するだけでいいのだ。画期的ではないか。
インデックスサーチCGIは、http://cts.creasus.net/index.cgi にある。さらに、.htaccess でこれをデフォルトインデックスに設定している。index.html を使ってないので、誰かがリンクする時に index.html を慣習的に付けてしまった場合、警告画面が待っている。
また、index.cgi は、引数がなければ現行版のトップページにリダイレクトするし、?index
を与えれば歴代siteCTSの選択画面を出力する。
こういう色々な機能を <a href="/?xxx">
だけで簡単に使えるのだから、まことに便利と言う他ない。サブドメイン付きのサーバーならでは、である。
<a href="/">
とやると、「ルートからのパス」になる。<a href="http://cts.creasus.net/">
と同じ意味。<a href="/aaa/bbb.html">
なら <a href="http://cts.creasus.net/aaa/bbb.html">
と同じ意味。<a href="/?xxx">
<a href="http://cts.creasus.net/index.cgi?xxx">
2003.4.30.Wed
付属品も揃い、2002.12.19に失敗したノートパソコンのセットアップをやっとこ完了。とにかく次から次へとトラブルが起きて、やたらめったら苦労してしまった。これだから古いパソコンは嫌いなんだ。
主なセットアップ内容
…と、なんとかうまくいって良かった良かった。メインPCとして雪子ちゃんがいる以上、ネットに接続できなかったらゴミだからなぁ。