グッジョブ

2005年07月31日(日) 10:46 この記事をクリップ!

 

歴史をねじ曲げる?
日本も反論すればできるじゃん。

ついでに、「過去が過去が・・・」という国に対して「元寇が!」「百済が、高句麗が!」とでも言ってやってくれ。

 Djangoチュートリアルその2

2005年07月30日(土) 09:32 この記事をクリップ!

 

Djangoチュートリアルその2の日本語訳とりあえず完了

チュートリアル1にはあまり驚きがなかった(まぁ、ORは巷にあふれているから)のだけれど、チュートリアル2には結構驚かされた。Railsも同様なのかもしれないけど、管理者画面が自動でできたり、管理者画面は容易にカスタマイズできたり(外部キーの画面への反映も素敵)する。
まぁ、とにかくチュートリアル2を見てくださいな。

 booklog

2005年07月28日(木) 10:37 この記事をクリップ!

 

amazonのアフィリエイトメールで、booklog.jpというサービスが何かの大賞だというメールが来た。
なんとなく本棚を作ってみたんだけど、これはおもしろい。

del.icio.usやbloglinesもおもしろいと思ったけど、本やCDで人がつながるのはかなり楽しい。
しかも、SNSみたいになんかのグループっていうのに参加する必要がなくて、他の人の本棚と勝手につながるだけで面倒がない。
誰かからの反応が無くて楽しくないというのが無いのも、本棚ならでは。
恐ろしいのは同じ本を持っている人の本は欲しくなるってこと。amazon直結だし

残念ながら実家独身時代と違って本が買えないんだけど。。。

 PSPのWebブラウザ

2005年07月27日(水) 11:43 この記事をクリップ!

 

PSPにWebブラウザが搭載されるアップデートが出たのでアップデート実行。
電池残量が足りなかったり、無線LANアクセスポイントのMACアドレス設定を忘れていたり(したつもりでいた)して四苦八苦したけど、無事にファームのアップデート完了。
ちなみにメモリスティックの空き容量が16MB以上必要(アップデート後は削除していい)。

で、肝心のブラウザだけど、「かなりいい」です。

びっくりしたことにタブブラウザです。
□ボタンを押しながらアナログスティック?でスクロールをするのですが、その際に画面の上部に3色の帯が表示されているのですが、何のためのものか始めはわかりませんでした。
後で気づいたのですが、現在のタブ(確認していませんがおそらく3つまで)の色が他の2色より長く表示されます。
タブを切り替えるには「□ボタン+LかR」です。

レンダリングは、少し遅いですがきれいです(フォントがきれいというべきか)。
Safari(OSX)かIE(Windows)のどちらよりかときかれたら、Safari!と言っても過言ではない。

CSSもJavaScriptもオッケーのようです(bloglinesもちょっと画面の狭さ故の難はありますが、閲覧可能です)。

少しさわっていて使いにくい、あるいは問題と感じた点は、現時点では下記の2点だけ。
  • 任意のテキストを選択・コピーできない(URLとか、コピーペーストしたいじゃん)
  • bloglinesと別タブでちょっと大きなページを開いたらメモリが足りませんと表示された(けど、きちんと表示はできた。謎)
「嫁がニュースサイトやゲームの攻略サイトをチェックするくらいなら、PSPで十分」というレベル。

今度はAjaxを確認してみよう。

 Djangoと日本語とか

2005年07月25日(月) 22:15 この記事をクリップ!

 

とりあえず、Djangoのチュートリアル1をやってみた。

UNICODE設定のPostgreSQL8.03とPython2.3.5、Psycopg1.19の組み合わせで、O/R部分も日本語が通った。試してみたのは、saveとget_object(xx__exact="ほげ")。部分一致も試してみないと。

チュートリアルそのままだと、datetime.now()の値をsaveしようとするとTIME_ZONEが指定されていないというエラーがでたため、チュートリアル訳にdatetime.uctnow()で回避できる旨を追記。

meta.DateTimeFieldは、timestamp with time zoneのSQLを生成するようだ。

Django、今のところなかなかいい感じ。

 Django

2005年07月25日(月) 04:09 この記事をクリップ!

 

PythonのWebアプリケーションフレームワークDjangoというのがちょっと話題らしい。
Ruby on Railsに流れるな!Djangoを使え!という感じだとか。

とりあえず、インストール方法チュートリアルの一つ目(三つある)を日本語化してみた。

 振舞駆動開発

2005年07月20日(水) 22:31 この記事をクリップ!

 

XPではテストファーストで開発を行うことを、TDD(Test Driven Development)と呼ぶ。
生きてまさんや、アジャイルの人の一部はBDD(Behaviour Driven Development)という考え方にしたらよいのではないかと提唱中。
現場ではテストというものは開発後にテスターが行うという認識が未だに強いので、名前を変えようと言うのが趣旨。

主にテストメソッドの名前を次のように変えようということらしい(生きてまさんはドキュメントまで出るといいなと夢想中みたい)。

TDD:testXXXValidUser  (XXXはメソッド名)
BDD:shouldAllowValidUser

テストファーストにアレルギーのない現場にいる身としては、testがshouldに見た目的に代わり「テスト」という対外的なものいいから「仕様」とい う対外的ないいわけに変えられる、ということよりも"test"から"should"に変わったことで「どのメソッドにどういう条件の入力や状態を渡した 際のテスト」から「どういう状態の物はどうされるべき」という仕様として非常にわかりやすい名前が付くであろう事が想定されることこそが利点に思える。

われわれのテストの名前付けに問題があるのかもしれないが、テストメソッドの名前+メソッド内のアサーションの双方を見ないと1年前に書いたテストの内容がわからないことが多い。
#次に出てくる問題は、アサーションではなくメソッド名で仕様を表す英語を現場の全員が記述できるかという部分だが、それは置いておく。。。

eclipseで完全に回る実装が現れるまで現場で使うことは出来ないけど(勝手に実装しろ?いやいや)、またこれで一つ開発フローが改善されるような気がする。

 ヴィンちゃん

2005年07月20日(水) 11:23 この記事をクリップ!

 

おいおい、ヴィンちゃん。
ゲーム中に寝るなよっ!
ジゴロウと違って妙に気になる。。。

 なぜ今ソーシャルブックマークか?

2005年07月20日(水) 02:11 この記事をクリップ!

 

C O U L D:タグパラダイスさんでShadowsという期待できそうなサービスが紹介されていた。
要は最近はやりのソーシャルブックマークなのだが、ブックマークした人の評価がサービス内の検索で利用されるという特徴を持っている。

オンラインブックマーク自体は、結構昔から存在していたけれど、Blink.com等の古株はサービス停止しているものがおおいようだ。
netscooterやShareStage等はソーシャル的な機能を当時から持ち合わせていたはずだし、機能的に今より劣っているものでは無い。
簡単にブックマークするためのブックマークレットもちゃんとあったし。

決定的に当時のサービスと現代のサービスで違うのは、次のようなものだと勝手に考える。
  • カテゴリという言葉をタグという言葉に置き換えた(階層型ではなくなった)
  • 回線やインターネット普及率が上がった
  • インターネット広告がある程度お金になるようになった
  • APIが公開され、ハッカー(クラッカーではない)達が喜んでツールを作った
  • UI・機能がシンプルになった
  • 他人のブックマークを認証無しで参照できるようになった(隠さなくなった。隠すことも出来る)
太字にした部分が実は重要だったのではないかと、さらに勝手に考える。

「隠さなくなった」という部分は、SNSが少しはやっている現状から考えると面白いんだけど、要は個人自体があまり重要でないので隠さなくても良いのだと思う。
ブックマークは、個人というよりはあるブックマークの固まりを形作っているユーザというレベルでよいのだから、隠す必要がない。そもそも個人情報をとっていないところが多い
個人情報をとらなくて良くなったのはグーグル等のコンテンツ連動を容易にする広告技術の発展のおかげかな。
UI・機能についてはdel.icio.usなんかは機能しか存在しないといっても間違いではないと思う。
#装飾はタグの大きさくらいでしょ。タグの大きさも機能としてデザインされた物だし。

Shadowの何が楽しみかというと、評価によって検索結果からゴミが減らせる可能性があるという点です。

 DBTestCase

2005年07月18日(月) 09:52 この記事をクリップ!

 

私は普段XP(eXtreme Programming)にて開発を行っています。

XPでの開発はテストファーストが基本ですが、アプリケーションの中心にデータベースがいるため、テスト作成の大部分はテストデータ準備コードの記 述に割り当てられていました。

モックオブジェクトではデータベースの正しさについてのテストができませんので、何とかして、あるロジックで処理する直前」のデータが必要となるのです。

テストの要件を満たす準備データの検討に時間がかかるのは仕方ない(それがテストファーストというものでしょ)としても、そ の考え出したデータの投入ロジック記述に大きく時間がかかってしまっていました。
#特にロジックのデータ永続化にORツールを使用しているため、余計に時間がかかります。

DBTestCaseは、エクセルベースで検討した準備データをDBにインサートし、テスト後にデリートするためのツールです。

具体的には、テーブルとエクセルのシートを対応させ、インサートは左のシートから(シート内は上から)順にインサートをし、デリートは右のシートから(シート内は下から)順にデリートしていくユーティリティです。
インサートとデリートで順序が違うのはFKの影響でデータが消せないことを防ぐためです。自分自身を参照しているテーブルでもインサートができればデリートできるはずです。

  • 準備

http://sourceforge.jp/projects/dbtestcaseからdbTestCase-0.1.2-src.zipをダウンロードします。
#ソース版にもバイナリが含まれているのでせっかくですからソース版をダウンロードします。
ダウンロードしたファイルを解凍すると、出てきたフォルダの直下に dbTestCase-0.1.2.jar というファイルがあるはずです。 このjarファイルがDBTestCaseのライブラリになります。 また、src/libの中にDBTestCaseが必要とするライブラリが入っていますので、各jarにクラスパスを通してください。
  • テーブルの指定の仕方

エクセルのシート名をテーブル名と同じにする必要があります。
全てのシートが順にパースされていきますので、不要なシートは削除しておく必要があります。
下記のようなエクセルの場合、TABLE_AとTABLE_Bというテーブルに対して処理が行われます。
TestAData.xls
  • データの設定の仕方

テーブルに対応したシートにデータを設定します。
シートの一行目に左から詰めて(順番は関係ありません)カラム名を設定していきます。
二行目からはデータの行になります。 空の行は認められませんが、(一行目を含め)背景色をつけたりコメントを追加したりしても問題ありません。
#またオートフィルタ等POIで正しく読めない機能は使用できません。POIに制限されます。

実際の開発での使用には、「シーケンスを使用せずにデータを設定していくのでテスト環境に関してはシーケンスオブジェクトを1000等から開始し、テストデータは1000未満を設定する」等の取り決めが必要でした。
  • 削除キーの指定の仕方

カラム名をBOLDにするだけです。 エクセルのサンプル画像を見てください。
TABLE_BというシートのA1にCOLUMN_AというBOLD文字列がみえるでしょう。
このBOLD文字列のカラム名に対して設定されているデータを削除キーとしてデータを削除します。
  • コードの基本

net.yher2.junit.db.DBTestCaseというabstractクラスを継承してテストのベースクラスを作成します。
このクラスは、各データベースや接続テクノロジに対応したjava.sql.Connectionを設定可能なようにabstractクラスになっています。
package net.everes.junk;

import java.sql.Connection;
import java.sql.SQLException;

import net.yher2.junit.db.DBTestCase;

public class DBTestSampleBase extends DBTestCase {
protected Connection getConnection() throws SQLException {
//ここにデータベースのコネクションを返すロジックを記述。
return null;
}
}
次に上記クラスを継承した各テストクラスを作成します。
Classpathのオブジェクトにエクセルへのパスを設定し、prepare/clearに渡すことによってデータのインサート/デリートが行われます。
package net.everes.junk;

import net.yher2.commons.io.Classpath;

/**
* 実際のテストクラス
* @author makoto
*
*/
public class DBTestSampleA extends DBTestSampleBase {
private Classpath testDataAPath = null;
private Classpath testDataBPath = null;

/**
* 各テストに必要なデータを用意します。
*/
protected void setUp() throws Exception {
super.setUp();
//クラスパスの通った場所からのエクセルファイルへのパスを設定します。
testDataAPath = new Classpath("test/data/TestAData.xls");
testDataBPath = new Classpath("test/data/TestBData.xls");
prepare(testDataAPath);
prepare(testDataBPath);
}

protected void tearDown() throws Exception {
super.tearDown();

clear(testDataBPath);
clear(testDataAPath);
}

public void testSampleA() throws Exception {
//テストコードを記述
}
}
  • 特殊な使用例

業務用のデータベース設計には、インサートやアップデートの際にトリガーで別テーブルにもデータをインサートするようなものがあります。
そのような場合には、エクセルを複数に分けることで対処することができます。
インサート用のエクセルと別に、トリガーでインサートされるテーブルのデータを削除するためだけのエクセルを用意し、インサート用のエクセルデータ削除前 に利用するのです。

  • junit以外のテクノロジとDBTestCaseを使用する

net.yher2.junit.db.TestDataManagerを使用します。
TestDataManagerにjava.sql.Connectionを設定し、DBTestCaseと同様にprepare/clearによってデータのインサート/デリートを行うことができます。

 今週のサクサクパーサー

2005年07月14日(木) 13:04 この記事をクリップ!

 

今週のsakusakuというページを勝手にパースしてみました。
プログラムはPython,Java,Ruby,PHPで書き、最終的にはhttpに乗せてRSSとして「本日ないしは明日のトピック」を配信するところまでをやってみようと思っています。
現在 Zope版のみパッケージ化ができています。sakusaku_zope.tar.gz
今回は、ネット越しにHTMLを取得して今日・明日のコンテンツを配列にするところまでです。

Python


Pythonは2.3.5を使用しました。japanese_codecsが必要かもしれません。
HTMLのパース自体は標準のクラスを用いて行うことが可能でした。
Pythonのクラスやライブラリは思想の一貫性があり非常に推測しやすいので素敵です。
# -*- coding: UTF-8 -*-
###########################################################################
# Copyright 2005 everes.net
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###########################################################################
from HTMLParser import HTMLParser
from datetime import date
import urllib

class SakusakuParser(HTMLParser):
sakusaku = None

def setCharset(self, encoding):
self.sakusaku = SakusakuWeek(encoding)
self.sakusaku.clearData()

def getSakusakuWeek(self):
return self.sakusaku

def handle_data(self, data):
self.sakusaku.parseData(data)

def handle_starttag(self, tag, attrs):
self.sakusaku.startTag(tag, attrs)

def handle_endtag(self, tag):
self.sakusaku.endTag(tag)

class SakusakuWeek:
weekContents = []
contentsArea = -1
divCount = 0
today = None
tmp_content = ""

def __init__(self, encoding):
self.charset = encoding
weekContents = []

def clearData(self):
weekContents = []
contentsArea = -1
divCount = 0
today = None
tmp_content = ""

def getContents(self):
return self.content

def getToday(self):
self.today = date.today()
result = self.weekContents[self.today.weekday()].split('●')
return result[1:len(result) - 1]

def getTomorrow(self):
self.today = date.today()
result = self.weekContents[self.today.weekday() + 1].split('●')
return result[1:len(result) - 1]

def parseData(self, data):
if self.isContentsArea():
data = unicode(data, self.charset).encode("UTF-8")
data = data.strip(" ¥t¥r¥n")
if data:
self.tmp_content += data

def startTag(self, tag, attrs):
if tag == 'div':
for i in range(len(attrs)):
if attrs[i][0] == 'style':
if attrs[i][1] == 'margin:10px':
self.setContentsArea(1)
self.div()

def endTag(self, tag):
if tag == 'div':
self.endDiv()

def isContentsArea(self):
return self.contentsArea == 1

def setContentsArea(self, mode):
if mode == 1:
self.contentsArea = 1
self.divCount = 0
else:
self.weekContents.append(self.tmp_content)
self.tmp_content = ""
self.contentsArea = -1

def div(self):
if self.isContentsArea():
self.divCount += 1

def endDiv(self):
if self.isContentsArea():
self.divCount -= 1
if self.divCount == 0:
self.setContentsArea(-1)

class Sakusaku:
sakusaku = None

def feed(self):
url = "http://www.tvk-yokohama.com/saku2/week.html"
data = urllib.urlopen( url )
charset = data.headers.getparam('charset')
if charset == None:
charset = 'japanese.shift_jis'
parser = SakusakuParser()
parser.setCharset(charset)
parser.feed( data.read() )
self.sakusaku = parser.getSakusakuWeek()


def getToday(self):
self.feed()
return self.sakusaku.getToday()

def getTomorrow(self):
self.feed()
return self.sakusaku.getTomorrow()

def main():
sakusaku = Sakusaku()
try:
content = sakusaku.getToday()
except IndexError,e:
content = ["None","Holiday"]

for i in range(len(content)):
print ' %s' % content[i]

if __name__ == "__main__":
main()


Java


Javaも標準のライブラリのみで実装が可能です(swingパッケージですが)。
LLな言語ではないのですが、普段仕事で使用しているのでつい作ってしまいました。
仕事で使っていてこのコードは恥ずかしいのですが、もうJavaはおもしろくはないので手抜きです。
/**************************************************************************
Copyright 2005 everes.net
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**************************************************************************/
package net.everes.junk;

import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.DTD;
import javax.swing.text.html.parser.DocumentParser;
import javax.swing.text.html.parser.TagElement;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.MutableAttributeSet;
public class SakusakuCallback extends HTMLEditorKit.ParserCallback {
List weekContents;
boolean contentsArea;
int today;
int tomorrow;
String tmpContent;
int divCount = 0;
public SakusakuCallback() {
super();
weekContents = new ArrayList();
contentsArea = false;
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
today = calendar.get(Calendar.DAY_OF_WEEK) - 2;
tomorrow = calendar.get(Calendar.DAY_OF_WEEK) - 1;
tmpContent = "";
}

public void handleText(char[] data, int pos) {
if(contentsArea) {
tmpContent += new String(data);
}
}

public void handleStartTag(HTML.Tag tag, MutableAttributeSet attrs, int pos) {
if(tag.equals(HTML.Tag.DIV)) {
if(!contentsArea) {
Enumeration enumeration = attrs.getAttributeNames();
while(enumeration.hasMoreElements()) {
Object obj = enumeration.nextElement();
String name = "" + obj;
if(name.equals("style")) {
Object value = attrs.getAttribute(obj);
if(value.toString().equals("margin:10px")) {
contentsArea = true;
divCount = 0;
}
}
}
}
findDiv();
}
}
public void handleEndTag(HTML.Tag tag, int pos) {
if(tag.equals(HTML.Tag.DIV)) {
findEndDiv();
}
}

public String[] getToday() throws ArrayIndexOutOfBoundsException {
String tmp = weekContents.get(today).replaceAll(" ¥t¥r¥n","");
String[] result = tmp.split("●");
String[] contents = new String[result.length];
for(int i = 0;i < result.length;i++) {
contents[i] = result[i];
}
return contents;
}

private void findDiv() {
if(contentsArea) {
divCount += 1;
}
}

private void findEndDiv() {
if(contentsArea) {
divCount -= 1;
}
if(contentsArea) {
if(divCount == 0) {
contentsArea = false;
weekContents.add(tmpContent);
tmpContent = "";
}
}
}

public List getContents() {
return this.weekContents;
}

public static void main(String[] args) {
try {
URL url = new URL("http", "www.tvk-yokohama.com", "/saku2/week.html");
HttpURLConnection request = (HttpURLConnection) url.openConnection();
ParserDelegator parser = new ParserDelegator();
HTMLEditorKit.ParserCallback sakusaku = new SakusakuCallback();
parser.parse(new InputStreamReader(request.getInputStream()), sakusaku, true);
String[] result = ((SakusakuCallback)sakusaku).getToday();
for(String day: result) {
System.out.println(day);
}
} catch (Exception e) {
e.printStackTrace();
}
}

}

Ruby


現場の若いのにやるように進めながら先に作ってしまいました(シャアサクくんは見ないでね)。
残念ながらRAAというライブラリ群にあったHTMLパーサでは「今週のサクサク」はパースできませんでした。アトリビュートがクォートされていないとこけてしまいます。
いい感じに動くHTMLパーサがありましたので、それを使ってやってみました。
#ただし、パーサはストリームを求めているのにHTTPでストリームを返すやり方が発見できず。。。ま、仕方ないですが。
Rubyでおもしろかったのは、無名クラスの作り方です。
下記のコードではパーサのクラスを継承して作っていますが、Ruby的にはクラスをインスタンス化してからインスタンスのメソッドを書き換えることができるようです。
実際には恐ろしくて使えませんが、Rubyはやばそうだと思わせるに十分でした。
###########################################################################
# Copyright 2005 everes.net
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###########################################################################
require 'simplehtmlparse' #http://arika.org/archive/?C=M;O=A
require 'net/http'
require 'date'
require 'nkf'

class Sakusaku < SimpleHtmlParse
weekContents = Array.new
contentsArea = 0
divCount = 0
tmpString = ""

def initialize(io)
super(io)
@weekContents = Array.new
@divCount = 0
@tmpString = ""
end

def begin_tag(name, attribute, orig_text)
if(name == "DIV")
if(attribute.has_key? "STYLE")
if(attribute["STYLE"] == "margin:10px")
@contentsArea = 1
@divCount = 0
end
end
if(@contentsArea == 1)
@divCount += 1
end
end
end

def end_tag(name, attribute)
if(@contentsArea == 1)
if(name == "DIV")
@divCount -= 1
if(@divCount == 0)
@weekContents << @tmpString
@tmpString = ""
@contentsArea = 0
end
end
end
end

def text(orig_text)
if(@contentsArea == 1)
tmp = orig_text.chomp.gsub(/¥t¥s /,'')
if(tmp != '')
@tmpString << orig_text.gsub(/¥t¥s/,'')
end
end
end

def getWeekContents()
return @weekContents
end

def getToday()
dt = Date::today
today = dt.wday - 1
return getContents(today)
end

def getTomorrow()
dt = Date::today
tomorrow = dt.wday
return getContents(tomorrow)
end

def getContents(dayofweek)
tmp = @weekContents[dayofweek].split('●')
tmp.delete_at(0)
return tmp
end

end

Net::HTTP.version_1_2
body = Net::HTTP.get('www.tvk-yokohama.com', '/saku2/week.html', 80)
f = open("week_tmp.html","w+")
f.puts(NKF.nkf('-w',body))
f.close()

f = open("week_tmp.html")

sakusaku = Sakusaku.new(f)
sakusaku.parse

f.close()
begin
result = sakusaku.getTomorrow
result.each {|x| puts x}
rescue
puts "holiday"
end

php


phpは挫折しました。
標準のXML関数はHTMLのパースができません(XHTMLならできる)。
仕方なくごちゃごちゃなPEARも見てみましたが、標準と同様でした(そのあたりの思想の欠如もphpが好きでない理由です)。
世の中にライブラリも見あたりません。
phpのHTMLパーサは、知人が作っている(まだ未公開)ので作りたくありません。
知人はあっという間にphpでサクサクパーサを作りました。
結論としてphp(というか言語を取り巻く環境)は嫌いです。
以下、書き途中でがっかりしたコード。
// php 挫折(;o;) phpのXML関数ではXHTML以外はパースできず、他に良さそうなパーサも見つからず。。。

function beginTag($psr, $name, $attributes) {
print "start" . $name . "¥n";
}

function endTag($psr, $name) {
print "end:" . $name . "¥n";
}

function text($psr, $data) {
print $data;
}

function getSakusakuData() {
$URL = "http://www.tvk-yokohama.com/saku2/week.html";

$buff = "";
$fp = fopen($URL,"r");
while ( !feof($fp) ) {
$buff .= fgets($fp,4096);
}
fclose($fp);
$buff = mb_convert_encoding($buff, "UTF-8", "Shift_JIS");
return $buff;
}

$data = getSakusakuData();
$parser = xml_parser_create();
xml_set_element_handler($parser, "begintag", "endTag");
xml_set_character_data_handler($parser, "text");
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
xml_parse($parser, $data);
xml_parser_free($parser);

 Realm認証のカスタマイズ

2005年07月12日(火) 09:37 この記事をクリップ!

 

J2EEではアプリケーションサーバにビルトインされた認証のアルゴリズムがあります。
例えばtomcatにはダイアログベース(レスポンスコード403をブラウザに返す)ものとフォームベース(ユーザ・パスワードの入力画面を返す)ものが用意されています。
ただし、あるURIに対して参照する権限を有しているかどうかという種類の認証アルゴリズムなので、
そのままでは利用できない局面が存在します。

一つの認証文字列(ユーザ・パスワードの組み合わせ)で、複数の権限グループあるいは一つの権限グループに複数の立場で属している場合には、デフォルトのままでは対処不能です。

そこで、認証後に複数の権限グループや立場から任意のものを一つ選択してもらう画面を用意することにしました。
が、J2EEにビルトインの認証機能の場合は、フォームの画面が返された後に認証に通ると、直前のリクエストデータが再ポストされます。
httpの仕様的に、一度レスポンスが返された後にはリクエストデータは消えてしまっているはずです。
どのようにすれば良いのかと、tomcatとSerurityFilterをのぞいてみました。

  • tomcatでの実装
    org.apache.catalina.authenticator.FormAuthenticator
    で認証処理やリクエストの保存・復元を行っていました。
    これをいじってしまうと、認証メカニズム自体も変更しないと変なことになってしまいそうです。
  • SecurityFilterでの実装
    org.securityfilter.filter.SecurityFilterで認証処理やリクエストの保存・復元を行っていました。
    ただ、ServletAPI2.3のFilterを使用して実装されているので、J2EEの認証を残したまま特殊な処理を実装するのに便利そうです。
結局、上記の2種類の実装ともリクエストURIとリクエストデータの保存にはHttpSessionを使用していました。ということは作業中にセッションが切れて、再ログインする前に再びセッションが切れた場合には作業データは失われるということか。
ま、思いつく通りの内容だったといえましょうか。。。

 ドメインのキャラクタ

2005年07月08日(金) 12:53 この記事をクリップ!

 

Rhacophorus.net(青蛙)というドメインをとって喜ぶ知人が、青蛙の絵を週末に描くと宣言したので、
everes(つばめしじみ蝶)も負けずに(絵的には負けるんだけど)書き途中。


しかし、様々なプロジェクトに動物名や動物キャラクターをつけるのはいつ頃からなんだろう。
Pythonとかtomcatとかseesar(動物かどうかは怪しい)とかね。
オライリー製の本が自分の動物キャラと同じキャラクターで出ることをねらっているのか!?
初めてのPythonはなぜかネズミ?だぞ。

ちなみに、everesはEVEryRESourcesという命名からで、ツバメシジミという蝶の名前だということを
知ったのは取得後。
やっと最近はgoogleの日本語ページ検索でツバメシジミに勝てるようになってきた。

さて、手足をなんとかしなきゃ。

 黒板おもしれー

2005年07月07日(木) 22:08 この記事をクリップ!

 

ajaxで黒板

http://blackboard.sourceforge.jp/wiki/
というajaxでできた黒板がオレンジニュースにでていたので、白井ヴェインセントを書いてみた。

と、書いていたときに別の知らない人が白井ヴィンセントに落書きを(クウリックで拡大)!!!


やべー、こりゃかなりおもしれー

 白井ヴィンセント

2005年07月06日(水) 06:21 この記事をクリップ!

 

白井ヴィンセント登場!


Z56が仕方ないことにったのは諦めて、白井ヴィンセントの活躍を楽しみにしてみる。
Z56のいない時代のサクサクを知らないので、強烈にきもかわいいZ56がいなくなったショックはやはりでかいけど。


で、試しに今日のSakusakuのメニューを右側のサイドバーに表示してみた。

PythonとZopeで今週のSakusakuを無理矢理RSS化して、RDFSummaryで再読み込みをしています。
ちょっとおもしろいので、PHP/Python/Ruby/Javaで同じ事をしたらどういうコードになるかをやってみようと思います。
PHPはHTMLパーサが無いので、知人がお手製のパーサを使って作成済み。
PythonはZopeのパッケージにした(テスト運用中)。
Rubyは若いのが学習中(遠い)。
Javaはデータの解析まで終了(Web化が面倒)。

さて、Ruby版は完成するか!?

 メールアドレスのことはメアドと略す?それともメルアド?

2005年07月05日(火) 08:46 この記事をクリップ!

 

いつごろからか、メールアドレスの略称が「メルアド」になってませんか?

Biglobeのブログ勧誘文句に「メアドだけの簡単登録」とあって、少しほっとしました。
まだメアドが通用しているのか、あるいは古いITの人がチェックしたのかは微妙ですが。

「メルアド」というのは携帯コンテンツ屋さんが持ち込んだ略称のような気がします。
携帯系をメインにやっていたIT営業のひとから初めて耳にした記憶があります。
そういえば、ロンブーも「メルアド」っていうし、もしかしたらITと関係ない中高生たちが、何の知識もなくメールアドレスという言葉を略したらメルアドとなったのか?

試しにぐぐってみました。
  • メアド:468,000 件
  • メルアド:396,000 件
まだなんとか「メアド」が優勢のようです。
ただし、ITと関係のない中高生が言い出したとしたら、グーグルというITを指標にしても無駄ですが。。

 
ponybadge

Powered by

Feedbacks

Tweets

Tags

Calendar