2012-06-08 31 views
2

Wget的打印出的速度信息以一種非常清楚的方式,其中該速度被示出和刷新而文件被下載到stdout,並在整個屏幕中條滾動。我想在Python程序中複製這種輸出。這怎麼可能?如何在linux終端上重現wget-like速度界面?

我認爲curses庫應該能夠做到這一點;這就是我想出了: -

import curses, time 

class Speeder(object): 
    """Show and refresh time and download speed in a curses interface.""" 
    t1 = 0. # start time 
    t = 0. # current time 
    tf = 0. # end time 
    def start(self, filename=None): 
     """Start timer""" 
     self.t1 = self.t = time.time() 
     curses.use_env(True) 
     curses.initscr() 
     self.win = curses.newwin(4, 0) 
     if filename is not None: 
      self.win.addnstr(filename, 50) 
      self.win.refresh() 

    def update(self, rbytes): 
     """Refresh speed.""" 
     t = time.time() 
     td = t - self.t 
     self.t = t 
     speed = rbytes/td 
     self.win.addstr(0,54,str('{0:.02f} B/s'.format(speed))) 
     self.win.refresh() 

    def end(self): 
     """End timer""" 
     self.tf = time.time() 
     curses.endwin() 


try: 
    speed = Speeder() 
    speed.start(filename='foo.bar') 
    for i in xrange(10): 
     time.sleep(0.5) 
     speed.update(200) 
finally: 
    speed.end() 

的問題是,它佔據了整個窗口,我只真正需要的線路在同一時間。我寧願不把所有的命令行歷史都推回到終端窗口之上。如果我錯了,請糾正我,但我現在認爲curses應用程序總是佔用整個終端窗口。

所以我看看ttytermios模塊,但是我找不到任何正在做我想做的事情的例子。

最後,我碰到a blog post這可以通過寫一些特殊字符sys.stdout來做到的。運用自己的代碼,以我的調速裝置類,我想出了這個: -

import sys 
class Speeder(object): 
    """Show and refresh time and download speed.""" 
    t1 = 0. # start time 
    t = 0. # current time 
    tf = 0. # end time 
    def start(self, filename=None): 
     """Start timer""" 
     self.t1 = self.t = time.time() 
     if filename is not None: 
      sys.stdout.write('\r\x1b[K' + filename.ljust(50)) 
      sys.stdout.flush() 

    def update(self, rbytes): 
     """Refresh speed.""" 
     t = time.time() 
     td = t - self.t 
     self.t = t 
     speed = '{0} B/s'.format(rbytes/td) 
     sys.stdout.write("\r\x1b[K" + speed.rjust(65)) 
     sys.stdout.flush() 

    def end(self): 
     """End timer""" 
     self.tf = time.time() 
     sys.stdout.write('\n') 

這有更少的代碼,這是我喜歡的,但TBH我沒有一個線索,這是怎麼回事,或者如何修改它只更新部分行,類似於curses.addstr函數。目前,文件名被空白覆蓋。我當然可以修改這個類來每次從python構建整個行,但我想了解這一點,以便根據自己的需要進行調整。

作者說,這是可能只在VT100終端。所以我想這隻會在Unix終端上工作呢?這很好,但是有沒有Unix終端,這不會工作?

是否有關於這個問題更好的文檔,或更復雜的實施例(例如,更新多條線路,多箇中的一個線路,或單個字符上的線),優選爲Python?這看起來不像Python的一個特性,但是tty,這就是爲什麼我猜測我找不到任何東西。是否有一個手冊頁或我應該閱讀的東西?

回答

3

上面的代碼是使用ANSI轉義碼:​​3210。我認爲這是您在嘗試搜索您找到的代碼時要查找的文檔。

+0

感謝您的鏈接。絕對是我很快會讀的東西。 –

+0

謝謝,我現在開始欣賞ANSI轉義代碼,並想出瞭如何移動光標。在後面的'update'方法中替換轉義碼,用'\ 033 [15D「'讓我把光標移回15個字符。然後我可以覆蓋已經存在的內容。繁榮! –

+0

爲您提供幫助找到最簡單解決方案的正確答案。 –

2

你可能想看看Blessings,這似乎是你想要什麼:

祝福電梯數的詛咒的限定性假定,它使你的代碼漂亮,太

+0

祝福看起來真棒!它特別提供的示例代碼!感謝您的建議 –

+0

不久前,它在/ r/Python中隨機彈出時被認爲是相同的;) – mensi