Djangoチュートリアルその2
2005年07月30日(土) 09:32
booklog
2005年07月28日(木) 10:37
amazonのアフィリエイトメールで、booklog.jpというサービスが何かの大賞だというメールが来た。
なんとなく本棚を作ってみたんだけど、これはおもしろい。
del.icio.usやbloglinesもおもしろいと思ったけど、本やCDで人がつながるのはかなり楽しい。
しかも、SNSみたいになんかのグループっていうのに参加する必要がなくて、他の人の本棚と勝手につながるだけで面倒がない。
誰かからの反応が無くて楽しくないというのが無いのも、本棚ならでは。
恐ろしいのは同じ本を持っている人の本は欲しくなるってこと。amazon直結だし。
残念ながら実家独身時代と違って本が買えないんだけど。。。
なんとなく本棚を作ってみたんだけど、これはおもしろい。
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点だけ。
今度はAjaxを確認してみよう。
電池残量が足りなかったり、無線LANアクセスポイントのMACアドレス設定を忘れていたり(したつもりでいた)して四苦八苦したけど、無事にファームのアップデート完了。
ちなみにメモリスティックの空き容量が16MB以上必要(アップデート後は削除していい)。
で、肝心のブラウザだけど、「かなりいい」です。
びっくりしたことにタブブラウザです。
□ボタンを押しながらアナログスティック?でスクロールをするのですが、その際に画面の上部に3色の帯が表示されているのですが、何のためのものか始めはわかりませんでした。
後で気づいたのですが、現在のタブ(確認していませんがおそらく3つまで)の色が他の2色より長く表示されます。
タブを切り替えるには「□ボタン+LかR」です。
レンダリングは、少し遅いですがきれいです(フォントがきれいというべきか)。
Safari(OSX)かIE(Windows)のどちらよりかときかれたら、Safari!と言っても過言ではない。
CSSもJavaScriptもオッケーのようです(bloglinesもちょっと画面の狭さ故の難はありますが、閲覧可能です)。
少しさわっていて使いにくい、あるいは問題と感じた点は、現時点では下記の2点だけ。
- 任意のテキストを選択・コピーできない(URLとか、コピーペーストしたいじゃん)
- bloglinesと別タブでちょっと大きなページを開いたらメモリが足りませんと表示された(けど、きちんと表示はできた。謎)
今度は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、今のところなかなかいい感じ。
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を使え!という感じだとか。
とりあえず、インストール方法とチュートリアルの一つ目(三つある)を日本語化してみた。
Ruby on Railsに流れるな!Djangoを使え!という感じだとか。
とりあえず、インストール方法とチュートリアルの一つ目(三つある)を日本語化してみた。
振舞駆動開発
2005年07月20日(水) 22:31
XPではテストファーストで開発を行うことを、TDD(Test Driven Development)と呼ぶ。
生きてまさんや、アジャイルの人の一部はBDD(Behaviour Driven Development)という考え方にしたらよいのではないかと提唱中。
現場ではテストというものは開発後にテスターが行うという認識が未だに強いので、名前を変えようと言うのが趣旨。
主にテストメソッドの名前を次のように変えようということらしい(生きてまさんはドキュメントまで出るといいなと夢想中みたい)。
テストファーストにアレルギーのない現場にいる身としては、testがshouldに見た目的に代わり「テスト」という対外的なものいいから「仕様」とい う対外的ないいわけに変えられる、ということよりも"test"から"should"に変わったことで「どのメソッドにどういう条件の入力や状態を渡した 際のテスト」から「どういう状態の物はどうされるべき」という仕様として非常にわかりやすい名前が付くであろう事が想定されることこそが利点に思える。
われわれのテストの名前付けに問題があるのかもしれないが、テストメソッドの名前+メソッド内のアサーションの双方を見ないと1年前に書いたテストの内容がわからないことが多い。
#次に出てくる問題は、アサーションではなくメソッド名で仕様を表す英語を現場の全員が記述できるかという部分だが、それは置いておく。。。
eclipseで完全に回る実装が現れるまで現場で使うことは出来ないけど(勝手に実装しろ?いやいや)、またこれで一つ開発フローが改善されるような気がする。
生きてまさんや、アジャイルの人の一部はBDD(Behaviour Driven Development)という考え方にしたらよいのではないかと提唱中。
現場ではテストというものは開発後にテスターが行うという認識が未だに強いので、名前を変えようと言うのが趣旨。
主にテストメソッドの名前を次のように変えようということらしい(生きてまさんはドキュメントまで出るといいなと夢想中みたい)。
TDD:testXXXValidUser (XXXはメソッド名)
BDD:shouldAllowValidUser
テストファーストにアレルギーのない現場にいる身としては、testがshouldに見た目的に代わり「テスト」という対外的なものいいから「仕様」とい う対外的ないいわけに変えられる、ということよりも"test"から"should"に変わったことで「どのメソッドにどういう条件の入力や状態を渡した 際のテスト」から「どういう状態の物はどうされるべき」という仕様として非常にわかりやすい名前が付くであろう事が想定されることこそが利点に思える。
われわれのテストの名前付けに問題があるのかもしれないが、テストメソッドの名前+メソッド内のアサーションの双方を見ないと1年前に書いたテストの内容がわからないことが多い。
#次に出てくる問題は、アサーションではなくメソッド名で仕様を表す英語を現場の全員が記述できるかという部分だが、それは置いておく。。。
eclipseで完全に回る実装が現れるまで現場で使うことは出来ないけど(勝手に実装しろ?いやいや)、またこれで一つ開発フローが改善されるような気がする。
なぜ今ソーシャルブックマークか?
2005年07月20日(水) 02:11
C O U L D:タグパラダイスさんでShadowsという期待できそうなサービスが紹介されていた。
要は最近はやりのソーシャルブックマークなのだが、ブックマークした人の評価がサービス内の検索で利用されるという特徴を持っている。
オンラインブックマーク自体は、結構昔から存在していたけれど、Blink.com等の古株はサービス停止しているものがおおいようだ。
netscooterやShareStage等はソーシャル的な機能を当時から持ち合わせていたはずだし、機能的に今より劣っているものでは無い。
簡単にブックマークするためのブックマークレットもちゃんとあったし。
決定的に当時のサービスと現代のサービスで違うのは、次のようなものだと勝手に考える。
Shadowの何が楽しみかというと、評価によって検索結果からゴミが減らせる可能性があるという点です。
要は最近はやりのソーシャルブックマークなのだが、ブックマークした人の評価がサービス内の検索で利用されるという特徴を持っている。
オンラインブックマーク自体は、結構昔から存在していたけれど、Blink.com等の古株はサービス停止しているものがおおいようだ。
netscooterやShareStage等はソーシャル的な機能を当時から持ち合わせていたはずだし、機能的に今より劣っているものでは無い。
簡単にブックマークするためのブックマークレットもちゃんとあったし。
決定的に当時のサービスと現代のサービスで違うのは、次のようなものだと勝手に考える。
- カテゴリという言葉をタグという言葉に置き換えた(階層型ではなくなった)
- 回線やインターネット普及率が上がった
- インターネット広告がある程度お金になるようになった
- APIが公開され、ハッカー(クラッカーではない)達が喜んでツールを作った
- UI・機能がシンプルになった
- 他人のブックマークを認証無しで参照できるようになった(隠さなくなった。隠すことも出来る)
「隠さなくなった」という部分は、SNSが少しはやっている現状から考えると面白いんだけど、要は個人自体があまり重要でないので隠さなくても良いのだと思う。
ブックマークは、個人というよりはあるブックマークの固まりを形作っているユーザというレベルでよいのだから、隠す必要がない。そもそも個人情報をとっていないところが多い。
個人情報をとらなくて良くなったのはグーグル等のコンテンツ連動を容易にする広告技術の発展のおかげかな。
UI・機能についてはdel.icio.usなんかは機能しか存在しないといっても間違いではないと思う。
#装飾はタグの大きさくらいでしょ。タグの大きさも機能としてデザインされた物だし。
Shadowの何が楽しみかというと、評価によって検索結果からゴミが減らせる可能性があるという点です。
DBTestCase
2005年07月18日(月) 09:52
私は普段XP(eXtreme Programming)にて開発を行っています。
XPでの開発はテストファーストが基本ですが、アプリケーションの中心にデータベースがいるため、テスト作成の大部分はテストデータ準備コードの記
述に割り当てられていました。
モックオブジェクトではデータベースの正しさについてのテストができませんので、何とかして、あるロジックで処理する直前」のデータが必要となるのです。
テストの要件を満たす準備データの検討に時間がかかるのは仕方ない(それがテストファーストというものでしょ)としても、そ
の考え出したデータの投入ロジック記述に大きく時間がかかってしまっていました。
#特にロジックのデータ永続化にORツールを使用しているため、余計に時間がかかります。
具体的には、テーブルとエクセルのシートを対応させ、インサートは左のシートから(シート内は上から)順にインサートをし、デリートは右のシートから(シート内は下から)順にデリートしていくユーティリティです。
インサートとデリートで順序が違うのは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というテーブルに対して処理が行われます。
-
データの設定の仕方
テーブルに対応したシートにデータを設定します。
シートの一行目に左から詰めて(順番は関係ありません)カラム名を設定していきます。
二行目からはデータの行になります。 空の行は認められませんが、(一行目を含め)背景色をつけたりコメントを追加したりしても問題ありません。
#またオートフィルタ等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として「本日ないしは明日のトピック」を配信するところまでをやってみようと思っています。
プログラムは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にはダイアログベース(レスポンスコード403をブラウザに返す)ものとフォームベース(ユーザ・パスワードの入力画面を返す)ものが用意されています。
ただし、あるURIに対して参照する権限を有しているかどうかという種類の認証アルゴリズムなので、
そのままでは利用できない局面が存在します。
一つの認証文字列(ユーザ・パスワードの組み合わせ)で、複数の権限グループあるいは一つの権限グループに複数の立場で属している場合には、デフォルトのままでは対処不能です。
そこで、認証後に複数の権限グループや立場から任意のものを一つ選択してもらう画面を用意することにしました。
が、J2EEにビルトインの認証機能の場合は、フォームの画面が返された後に認証に通ると、直前のリクエストデータが再ポストされます。
httpの仕様的に、一度レスポンスが返された後にはリクエストデータは消えてしまっているはずです。
どのようにすれば良いのかと、tomcatとSerurityFilterをのぞいてみました。
- tomcatでの実装
org.apache.catalina.authenticator.FormAuthenticatorで認証処理やリクエストの保存・復元を行っていました。
これをいじってしまうと、認証メカニズム自体も変更しないと変なことになってしまいそうです。 - SecurityFilterでの実装
org.securityfilter.filter.SecurityFilterで認証処理やリクエストの保存・復元を行っていました。
ただ、ServletAPI2.3のFilterを使用して実装されているので、J2EEの認証を残したまま特殊な処理を実装するのに便利そうです。
ま、思いつく通りの内容だったといえましょうか。。。
ドメインのキャラクタ
2005年07月08日(金) 12:53
Rhacophorus.net(青蛙)というドメインをとって喜ぶ知人が、青蛙の絵を週末に描くと宣言したので、
everes(つばめしじみ蝶)も負けずに(絵的には負けるんだけど)書き途中。
しかし、様々なプロジェクトに動物名や動物キャラクターをつけるのはいつ頃からなんだろう。
Pythonとかtomcatとかseesar(動物かどうかは怪しい)とかね。
オライリー製の本が自分の動物キャラと同じキャラクターで出ることをねらっているのか!?
初めてのPythonはなぜかネズミ?だぞ。
ちなみに、everesはEVEryRESourcesという命名からで、ツバメシジミという蝶の名前だということを
知ったのは取得後。
やっと最近はgoogleの日本語ページ検索でツバメシジミに勝てるようになってきた。
さて、手足をなんとかしなきゃ。
everes(つばめしじみ蝶)も負けずに(絵的には負けるんだけど)書き途中。
しかし、様々なプロジェクトに動物名や動物キャラクターをつけるのはいつ頃からなんだろう。
Pythonとかtomcatとかseesar(動物かどうかは怪しい)とかね。
オライリー製の本が自分の動物キャラと同じキャラクターで出ることをねらっているのか!?
初めてのPythonはなぜかネズミ?だぞ。
ちなみに、everesはEVEryRESourcesという命名からで、ツバメシジミという蝶の名前だということを
知ったのは取得後。
やっと最近はgoogleの日本語ページ検索でツバメシジミに勝てるようになってきた。
さて、手足をなんとかしなきゃ。
黒板おもしれー
2005年07月07日(木) 22:08
白井ヴィンセント
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と関係ない中高生たちが、何の知識もなくメールアドレスという言葉を略したらメルアドとなったのか?
試しにぐぐってみました。
ただし、ITと関係のない中高生が言い出したとしたら、グーグルというITを指標にしても無駄ですが。。
Biglobeのブログ勧誘文句に「メアドだけの簡単登録」とあって、少しほっとしました。
まだメアドが通用しているのか、あるいは古いITの人がチェックしたのかは微妙ですが。
「メルアド」というのは携帯コンテンツ屋さんが持ち込んだ略称のような気がします。
携帯系をメインにやっていたIT営業のひとから初めて耳にした記憶があります。
そういえば、ロンブーも「メルアド」っていうし、もしかしたらITと関係ない中高生たちが、何の知識もなくメールアドレスという言葉を略したらメルアドとなったのか?
試しにぐぐってみました。
- メアド:468,000 件
- メルアド:396,000 件
ただし、ITと関係のない中高生が言い出したとしたら、グーグルというITを指標にしても無駄ですが。。

