2009年6月29日月曜日

ハードディスク買った

外部電源の外付けハードディスクだと、つなぐのが面倒でバックアップをサボりがちだったので、
バスパワーで動くUSB接続のハードディスクをさがしていた。

ちょうど、来月分の生協のチラシにHDPS-U500がのっていたので、これでいいかな?と思っていたら、
土曜日に寄った川崎のヨドバシで同じものがポイント20%還元になってた(ポイント分引けば9000円切ってる)ので買ってしまった。

8G/残りでパーティションを分けて、8Gの方からTrueImage(Home 10)を起動できるようにした。
手順は簡単で、TrueImage が起動する USB-HDD ( USB メモリ ) の作り方をそのままやればできた。
基本的にWindows上でバックアップするけど、復旧のこと考えるとこうしておいた方が安心。
(私の環境は1スピンドルでUSBが3ポート。USB光学ドライブはUSBを2ポートふさいでしまうので、HDDをつなぐと全部埋まる)



2009年6月23日火曜日

2009年6月4日木曜日

pygmentsの出力したhtmlにスタイルを埋め込む

ここでソース張っても色とかつけるのが大変なので、pygmentsのhtml出力とcssを結合するスクリプトを書いてみた。

embedstyle.py

import sys
from xml.etree.ElementTree import ElementTree
import cssutils
from cssutils.css import CSSRule

css = cssutils.parseFile(sys.argv[2])
rules = dict([(x.selectorText, x.style.cssText.replace('\n', '')) for x in css.cssRules if x.type == CSSRule.STYLE_RULE])

tree =  ElementTree(file=open(sys.argv[1]))
for elem in tree.getiterator():
    c = elem.get('class', None)
    if c:
        style = rules.get('.'+c, None)
        if style:
            elem.attrib['style'] = style
tree.write(sys.stdout)


使用例
スタイル生成→HTML出力→結合


pygmentize -f html -S colorful > test.css
pygmentize -o embedstyle.html embedstyle.py
python embedstyle.py pkglist.html test.css > out.html


これで出力したのがこのページのコード



ubuntu/debianのインストール済みパッケージリストを整形して出力する

ディスクの空きがちょっと減ってきたので、サイズが大きいパッケージを知りたくて作ってみた。

python-aptとprettytable使ってます。


#!/usr/bin/python


import apt
from prettytable import PrettyTable

pt = PrettyTable(["package", "version", "size"])
pt.set_field_align("package", "l")
pt.set_field_align("version", "r")
pt.set_field_align("size", "r")
pt.set_padding_width(1)

SizeToStr = apt.SizeToStr

for v in sorted([x.installed for x in apt.cache.Cache() if x.isInstalled], key=lambda v: v.installed_size):
    pt.add_row((v.package.name, v.version, SizeToStr(v.installed_size)))

print pt


出力


+----------------------------------------------------------+------------------------------------------+-------+
|                         package                          |                 version                  |  size |
+----------------------------------------------------------+------------------------------------------+-------+
| adobe-certs                                              |                                 1.0.8210 |     0 |
| adobeair1.0                                              |                               1.5.1.8210 |     0 |
| tweetdeckfast.f9107117265db7542c1a806c8db837742ce14c21.1 |                                     0.22 |     0 |
| gnuplot                                                  |                                  4.2.5-2 | 20.5k |
| uim                                                      |                                1:1.5.3-1 | 20.5k |
(省略)
| texlive-latex-extra-doc                                  |                    2007.dfsg.17-2ubuntu1 |  110M |
| openoffice.org-core                                      |                         1:3.1.0-3ubuntu2 |  113M |
| llvm-dev                                                 |                 2.5+svn20090504-0ubuntu1 |  117M |
| ghc6                                                     |                          6.10.3-2ubuntu1 |  148M |
+----------------------------------------------------------+------------------------------------------+-------+



2009年6月3日水曜日

print >>sys.stderrによる出力をloggingで出したい

sys.stderrにメッセージを出力しているモジュールがあって、それを書き換えずに何とかしたいので考えてみた。

とりあえずうまくいったけど、いいのかわからない。
(追記
すっかり忘れてたけど、sys.stderrをほかの変数で参照してたらだめだった。当たり前なんだけど…
別モジュールで、from sys import stderrなら
モジュール名.stderrを書き換えればOK)

import sys
import logging
from StringIO import StringIO

class redir(object):
  def __init__(self, f):
    self.f = f
    self.eol = True
  def write(self, buf):
    if buf == '\n':
      if self.eol:
        self.f('')
      else:
        self.eol = True
    else:
      self.eol = False
      self.f(buf)

print >>sys.stderr, "hoge"
logging.basicConfig(filename='hoge.log', level=logging.DEBUG)
sys.stderr = redir(logging.error)
print >>sys.stderr, "hoge1"
print >>sys.stderr
print >>sys.stderr, "hoge2"

これで、最初の出力(hoge)はstderrに、以降の出力(hoge1,改行のみ,hoge2)はhoge.logに出力される。


調べ方メモ
6.6. The print statementを見て、出力先のオブジェクトにwriteが必要なことと、(必要なときは)最後に'\n'がくることはわかった。
writeに渡されるバッファに最後の改行が含まれているのか、改行だけ別に呼ばれるのか気になるので調べてみた。

適当な関数を作って、disで調べた。

>>> import dis
>>> def f():
...  print >>None, None,
...
>>> def fln():
...  print >>None, None
...
>>> def fnl():

...  print >>None

...

>>> dis.dis(f)

  2           0 LOAD_CONST               0 (None)

              3 DUP_TOP

              4 LOAD_CONST               0 (None)

              7 ROT_TWO

              8 PRINT_ITEM_TO

              9 POP_TOP

             10 LOAD_CONST               0 (None)

             13 RETURN_VALUE

>>> dis.dis(fln)
  2           0 LOAD_CONST               0 (None)
              3 DUP_TOP
              4 LOAD_CONST               0 (None)
              7 ROT_TWO
              8 PRINT_ITEM_TO
              9 PRINT_NEWLINE_TO
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE
>>> dis(fnl)
  2           0 LOAD_CONST               0 (None)
              3 PRINT_NEWLINE_TO
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE
>>>

たぶん、PRINT_ITEM_TOがデータの出力で、PRINT_NEWLINE_TOは改行であろうことはわかる。
改行付きのprintがPRINT_ITEM_TOと、PRINT_NEWLINE_TOと二つに分かれているので、2回に分けてwriteが呼ばれそうなこともわかる。
ともかく、PRINT_ITEM_TOとPRINT_NEWLINE_TOは間違いなくキーワードなので調べると、PRINT_ITEM_TOPRINT_NEWLINE_TOは拡張版print statementで使われるのがわかる。それぞれ出力を行う命令なので、writeが二度呼ばれるものとして扱ってよさそう。

素直にそのままloggingすると、最後の改行までログに残ってしまうので邪魔。ただ、単純に'\n'だけ渡されたときに無視するようにすると、改行だけのやつ(fnlみたいなやつ)は捨てられてしまうので(ログに出すことしか考えていないので、許容できる場面もあると思うけど)簡単に対応しておく。

  • 前回の出力が改行じゃないときは無視(PRINT_ITEM_TO->PRINT_NEWLINE_TOで呼ばれる場合)
  • それ以外は空文字列を出力