progressbar for urllib.urlretrieve
地震で大変。ライフラインが止まってしまいました。困った困った。
urllib.urlretrieveにはreport_hook引数が用意されていて、callableを渡すとダウンロード状況をコールバックして知らせてくれます。シグネチャはこんな感じです。
report_hook(blocks_read, block_size, total_byte)
total_byteはHTTPヘッダにcontent-lengthが無い場合-1です。
ブロックを読み出すごとにコールバックされるのでその都度ターミナルなりGUIに出力すればurlretrieveのダウンロード状況を表示できます。今回は前に作ったプログレスバークラスを修正してurlretrieve向けのプログレスバークラスを作りました。
実行するとpython.orgからPython2.7のソースを落とします。
# coding: utf-8 import urllib class ProgressBar: def __init__(self, whole, length=30, ch='#', nch=' ', callback=lambda n:n): self.whole = whole self.length = length self.ch = ch self.nch = nch self.callback = callback self.current = None def update(self, current): self.current = current self.callback(self) def __repr__(self): ret = '' end = self.current / float(self.whole) x = int(end * self.length) p = int(end * 100.0) ret = ''.join(['[', self.ch * x, self.nch * (self.length - x), '] %d%%%c' % (p, '\n\r'[0 if p == 100 else 1]) ]) return ret def __call__(self, blkr, blks, totals): self.whole = totals idx = 1 if blks * blkr > totals else 0 self.update([blks * blkr, totals][idx]) def callback(progressbar): print repr(progressbar), url = 'http://www.google.com/images/srpr/nav_logo37.png' # without content-length url = 'http://s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif' # with content-length url = 'http://python.org/ftp/python/2.7.1/Python-2.7.1.tgz' # a bit large file out = './' + url[url.rindex('/') + 1:] urllib.urlretrieve(url, out, ProgressBar(None, callback=callback))
ところでエントリの下書き中にセッションが切れたらしく「下書き保存」を押したらブログトップに飛ばされて下書きが全部消えたので文章がなげやりに。
webインタフェースで編集するとアクシデントで下書きが全部消える事が多いからもうwebインタフェースから編集するのはやめよう・・・