EVがなんだか知らないけど、ファイル選択ダイアログで表示されないバグが直ったって言うからありがたい。早速入れよう。しかし、今週は早いね。
2ログビューア(7)-そろそろちゃんとした形にする、その前に
ちょっとずつ形にするべくコードは書いているのだが、今のところ断片的なものしかできていないので、今回はコードを晒すんじゃなくていくつかメモ を。
- リスト
- perlでいうarray。
- 配列に順にアクセスするには
for attr in list: print attr
- 添え字
first_attr = list[0]
- 辞書(dictionary)
- いわゆる連想配列
- キーと値をセットで取り出して処理するには
for k, v in dict.iteritems(): print "%s = %s" % ( k, v )
- キーから値を取得
value = dict['key']
- printf的なもの
- pythonでなんていうのかは知らないけど。要するに
print "%s = %s" % ( k, v )
他にもやり方は色々あるようだけど、とりあえずはこれで。+で繋ぐよりはスマートだし。
- 正規表現
- なんつーか、perlやphpと随分と作法が違うのでとっつきにくく感じるが、さっさと慣れてしまおう。
- →正規表現 HOWTO
- osモジュール
- 環境変数の取得は
os.getenv(key)
ってな感じで。
タグ
sshでログインした時のpromptを変更する
さくらインターネットさんは、スタンダードプラン以上だとsshログインも可能になるんですが、デフォルトのpromptが
%
なので、見づらかった。ので「プロンプト表示の変更」を参考にして~/.cshrcに以下の記述を追加した。
$vi ~/.cshrc
if ($?prompt) then
の後に
set prompt = "[$USER@`hostname -s` %/]$ "
保存して↓を実行。
$source ~/.cshrc
実行後のprompt表示。
[mattz@www1486 /home/mattz/www/w]$
非常に見易くなった。
2ログビューア(6)-Class化の続き
続き
poptotype3.pyの中身
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' read.cgi ''' import sys sys.path.append('/home/mattz/lib/python') from read2ch import read2ch import codecs fout = codecs.getwriter('shift_jisx0213')(sys.stdout) thread = read2ch( 'handygame', '1211373877' ) title = thread.getThreadTitle() count = thread.getResCount() print 'Content-Type: text/html;charset;Shift_JIS' print fout.write('''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content='text/html; charset="Shift_JIS"'> <title>%s</title> </head> <body><h1>%s</h1><dl> %s </dl></body></html> ''' % (title, title, thread.getFormatedReses( range(count))))
んでもって、read2ch.pyの中身
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 2ちゃんねるの.datファイルを扱うクラス 0.0.1 prototype版 ''' import codecs,re line_end_br = re.compile( '((<br>)?\s*)+$' ) normal_br = re.compile( '\s*<br>' ) ''' 1行分のログとレス番号からdt要素とdd要素を生成する TODO: 本文中のURLと思われる文字列をリンクする処理 アンカーと思われる文字列に対する処理 IDの有無/強制/任意などの対応 日付関係の処理 ''' def formatRes( rstr, rnum ): ar = re.split( '<>', rstr ) resFormat = u"<dt id='t-%d'>%d : 名前:%s %s</dt><dd id='d-%d'>%s<br><br></dd>\n" name = '<b>%s</b>' % ( ar[0] ) if ar[1]: name = '<a href="mailto:%s">%s</a>' % ( ar[1], name ) return resFormat % ( rnum, rnum, name, ar[2], rnum, normal_br.sub( '<br>', line_end_br.sub( "", ar[3])) ) class read2ch: base_dir = '/home/mattz/data/2channel/' resAll = [] def __init__( self, board, thread ): self.board = board self.thread = thread self.dat = "%s%s/%s.dat" % ( self.base_dir, board, thread ) self.idx = "%s%s/%s.idx" % ( self.base_dir, board, thread ) fres = codecs.open( self.dat, 'r', 'shift_jisx0213', 'strict' ) for line in fres: self.resAll.append( line ) fres.close() fres = codecs.open( self.idx, 'r', 'shift_jisx0213', 'strict' ) lines = re.split( '>', fres.readline() ); self.title = lines[0] self.standDate = lines[4] self.resCount = lines[5] fres.close() def getDataFilename( self ): return self.dat def getThreadTitle( self ): return self.title def getFormatedReses( self, num ): ret = '' for n in num: ret += formatRes( self.resAll[n], n + 1 ) return ret def getResCount( self ): return int( self.resCount )
細かい中身のことは書かない。
タグ
build 10005が非常に重い件
メモリの余裕があり、非proxy環境で、メールがIMAP4な自宅環境では非常に軽快。しかしながら、メモリ半分、proxy接続、メールはPOP3というオフィス環境に来ると、頻繁にプチフリーズする。もっとも、Operaに限った話ではなくて、マイコンピュータのアイコンをダブルクリックして、Explorerが開くま でに10秒近くかかると言う、微妙なPC環境であり、基本的にメモリが足りないのは明白なのだが、にしても、ちょっと困る。
POP3サーバに問合せに行っているとき、Opera linkにSyncしに行っているとき、イントラなサーバのRSSフィードを取りに行っているとき。それぞれにOperaが固まる。結構泣ける。仕方がないのでメールとSyncは手動でやっているのだが、なんだかなぁ。
タグ
2ログビューア(5)-Class化する
いきなり級が上がる感じがするが、一応僕もperlやphpはそれなりにやってきてるし、今更分岐だループだを細かく勉強する必要もないので、これまでに書いたコードを元に、ログビューア関係のロジックをClass化してしまう作戦。
まずは「さくらのレンタルサーバ」で Python 外部モジュールを使う 改訂版 の記述を元に、ここまで書く。
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' read.cgi ''' import sys,codecs sys.path.append('/home/mattz/lib/python') from read2ch import read2ch
それとは別に/home/mattz/lib/python/read2ch.pyというファイルを用意。
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 2ちゃんねるの.datファイルを扱うクラス ''' class read2ch:
ホントは中身の方も結構書いてあって、スレ固定だし、htmlの体も為してなくて、かつ付加機能も一切ないけど、一応表示だけできるようになってる。と言ってもそんな簡単でもなかったので、その辺のことをこの後のエントリに書いていきます。今日のところはこの辺で。
タグ
2ログビューア(4)-「㌧問題」に対応する
細かい原理はよく分からない(要はshift_jisには「㌧」だの「㍉」だのは含まれてないってことなんだろうけど)のだが、ログファイル自体は「shift_jisx0213」で読み込み、出力は「utf-8」で行うようにすることで、エラーも起きず、「㌧」も表示されるようになった。前回との相違点については強調にしてあるが、要するに↑に書いたようなことだ。
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' ㌧を含むsjisファイルを読み込んで整形して出力する ''' import re import sys import codecs def parseRes( res, n ): # 特に変更はないので省略 print 'Content-Type: text/html;charset;utf-8' print print ''' <html> <head><title>prototype2</title> <meta http-equiv="Content-Type" content='text/html; charset="utf-8"' /> </head> <body> <dl> ''' fout = codecs.getwriter('utf-8')(sys.stdout) fres = codecs.open( './sjis.txt', 'r', 'shift_jisx0213', 'strict' ) # 以降も変更はないので省略
→実行結果がかつてはリンクされていました。
追記
冷静になって考えてみたら、shift_jisx0213で読み込んでshift_jisx0213で出力するってので、ぱっと見の出力はShift_JISになるな。ケータイのこと考えるとその方がいい気がした。
タグ
2ちゃんねるログビューアを作成する(3)
「㌧」のことは置いといて、(1)と(2)を組み合わせてみた。細かいことは後から考えよう。
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 2ちゃんねるログを読み込んで整形してhtmlとして出力する ''' import re import sys import codecs def parseRes( res, n ): ar = re.split( '<>', res ) num = str(n) ret = '<dt id=\'dt' + num + '\'>' + num + u': 名前:<span class="name">' if ar[1]: ret += '<a href="mailto:' + ar[1] + '">' ret += ar[0] if ar[1]: ret += '</a>' ret += '</span> ' + ar[2] ret += '</dt>\n<dd id=\'dd' + num + '\'>' ret += ar[3] + '</dd>\n' return ret print 'Content-Type: text/html;charset;Shift_JIS' print print ''' <html> <head><title>prototype</title> <meta http-equiv="Content-Type" content='text/html; charset="Shift_JIS"' /> </head> <body> <dl> ''' fout = codecs.getwriter('shift_jis')(sys.stdout) log = codecs.open('1111198050.dat', 'r', 'shift_jis', 'ignore' ) res = 1; for line in log: fout.write( parseRes( line, res ) ) res += 1 print '
タグ
2ちゃんねるログビューアを作成する(2)
今日は先に書いたコードから。「Pythonで日本語を使う」を参考に、Shift_JISで保存されている.datファイルを読み込んで、そのまま標準出力に出す。つもりだった。
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' Shift_JISのファイルを読み込んで出力する。 ''' import sys import codecs fout = codecs.getwriter('shift_jis')(sys.stdout) log = codecs.open('1111198050.dat', 'r', 'shift_jis') # 実際にはフルパス for line in log: fout.write( line )
とりあえず、コンソールから実行してみたところ、途中までは問題なく出力されるのだが、ある行を処理するところで、エラーメッセージ。が出て中断 してしまう。
UnicodeDecodeError: 'shift_jis' codec can't decode bytes in position 158-159: illegal multibyte sequence
引っかかっている文字は「㌧」。この手の文字は2ちゃんねるでは頻繁に使われるしなぁ。どうしたらいいんだろ?とりあずここ読んで勉強するわ。
追記
codecs.open()
のところで、'ignore'
オプションをつけてやれば、ファイルの最後までは処理されるようにはなった。けど、解決にはなってない。なってはいないけどここまでの経過として修正版
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' Shift_JISのファイルを読み込んで出力する。 ''' import sys import codecs fout = codecs.getwriter('shift_jis')(sys.stdout) log = codecs.open('1111198050.dat', 'r', 'shift_jis', 'ignore' ) print 'Content-Type: text/plain;charset;shift_jis' print for line in log: fout.write( line )
→実行結果がかつてはリンクされていました。
タグ
2ちゃんねるログビューアを作成する(1)
とりあえずの目標である、CHPログビューアの移植に向けての第一歩。
まずは1行分のログをparseして整形して返す関数を作ってみる。
- とりあえず文字コードのことは忘れるために全部asciiにしてしまえ。
- jsでレスポップアップとか入れるためにも、各要素にidだけは振っておく。とはいいながらもその辺の処理は後回しだ。pythonでの正規表現の使い方とかさっぱり分からんし(splitだけは使ったが)。
今日学んだこと。
- 関数は先に定義するもののようだ。
- 文字列の連結は"+"。
- int型の変数はいきなり連結は出来ないみたいだ。まぁ、いずれsprintfに相当するものが出てくるだろうから、コレについてはほっとく。
- 今日書いたコード。
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 2ちゃんねるログ形式の1行をparseして整形する。 ''' import re def parseRes( res, n ): ar = re.split( '<>', res ) num = str(n) ret = '<dt id=\'dt' + num + '\'>' + num + ': 名前:<span class="name">' if ar[1]: ret += '<a href="mailto:' + ar[1] + '">' ret += ar[0] if ar[1]: ret += '</a>' ret += '</span> ' + ar[2] ret += '</dt>\n<dd id=\'dd' + num + '\'>' ret += ar[3] + '</dd>\n' return ret print 'Content-Type: text/html;charset;utf-8' print res1 = 'name<>sage<>05/03/19 11:07:30 ID:???<> body1 <>thread title' res2 = 'no name<>sage<>05/03/19 11:15:37 ID:???<> <a href="../test/read.cgi/board/0000000000/1"' res2 += ' target="_blank">>>1</a> <br> body 2 <>' print parseRes( res1, 1 ) print parseRes( res2, 2 )
実行結果がかつてはリンクされていました。
次はテキストファイルを読み込む辺り。の前にShift_JIS問題を何とかしよう。後ではまるかもしれないし。