r286 - in branches/rewrite: . src
Otavio Salvador
partial-mirror-devel@lists.alioth.debian.org
Wed, 10 Nov 2004 16:20:43 -0700
Author: otavio
Date: Wed Nov 10 16:20:42 2004
New Revision: 286
Modified:
branches/rewrite/ (props changed)
branches/rewrite/src/DisplayInfo.py
branches/rewrite/src/Download.py
Log:
r213@nurf: otavio | 2004-11-10T23:19:40.486144Z
Reimplement DisplayInfo in new way, proposed by Enrico.
Modified: branches/rewrite/src/DisplayInfo.py
==============================================================================
--- branches/rewrite/src/DisplayInfo.py (original)
+++ branches/rewrite/src/DisplayInfo.py Wed Nov 10 16:20:42 2004
@@ -1,5 +1,5 @@
# debpartial-mirror - partial debian mirror package tool
-# (c) 2004 Otavio Salvador <otavio@debian.org>
+# (c) 2004 Otavio Salvador <otavio@debian.org>, Enrico Zini <enrico@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,51 +17,81 @@
# $Id$
import sys
-import os
+from os.path import basename
-class BaseDisplayInfo:
- _info_windows = []
-
- def add(self, window):
- if window not in self._info_windows:
- self._info_windows.append(window)
-
- def remove(self, window):
- if window in self._info_windows:
- self._info_windows.remove(window)
-
- def refresh(self):
- map(lambda x: x.refresh(), self._info_windows)
-
- def done(self, file):
- pass
-
- def failed(self, file):
- pass
-
-class TextDisplayInfo(BaseDisplayInfo):
- def refresh(self):
- sys.stdout.write('\r' + (" "*80) + '\r')
- BaseDisplayInfo.refresh(self)
-
- def done(self, file):
- sys.stdout.write("\rDone: %s\n" % file)
-
- def failed(self, file):
- sys.stdout.write("\rFailed: %s\n" % file)
-
-class TextProgressBar:
- def __init__(self, min=0, max=100, text=''):
- self.min = min
- self.max = max
- self.text = text
- self.current = min
-
- def refresh(self):
- try:
- sys.stdout.write("[%s: %.2f%%]" % (os.path.basename(self.text).split('_')[0],
- self.current*100/(self.max - self.min)))
- except ZeroDivisionError:
- pass
+class StatusItem:
+ id = 0
+ def __init__(self):
+ self._properties = None
+
+ def __getitem__(self, key):
+ if key not in ['id', 'finished', 'current', 'size', 'errored']:
+ raise KeyError("%s is not allowed on StatusItem." % key)
+
+ if self._properties is None:
+ StatusItem.id += 1
+ self._properties = {'id' : StatusItem.id,
+ 'finished': False,
+ 'current' : 0,
+ 'size' : 0,
+ 'errored' : ''}
+
+ return self._properties.get(key)
+
+ def __setitem__(self, key, value):
+ if key not in ['id', 'finished', 'current', 'size', 'errored']:
+ raise KeyError("%s is not allowed on StatusItem." % key)
+
+ if self._properties is None:
+ StatusItem.id += 1
+ self._properties = {'id' : StatusItem.id,
+ 'finished': False,
+ 'current' : 0,
+ 'size' : 0,
+ 'errored' : ''}
+
+ self._properties[key] = value
+
+class BaseDisplayStatus:
+ _items = {}
+
+ def __getitem__ (self, key):
+ return self._items.get(key, None)
+
+ def start(self, url, size):
+ self._items[url] = StatusItem()
+ self._items[url]['size'] = size
+
+ def update(self, url, current):
+ self._items[url]['current'] = current
+
+ def errored(self, url, message):
+ if not self._items.has_key(url):
+ self._items[url] = StatusItem()
+ self._items[url]['errored'] = message
+
+class TextDisplayStatus(BaseDisplayStatus):
+ def start(self, url, size):
+ BaseDisplayStatus.start(self, url, size)
+ sys.stdout.write("\r" + " " * 80 + "\rGetting %d: %s\n" % (self._items[url]['id'], url))
+
+ def update(self, url, current):
+ BaseDisplayStatus.update(self, url, current)
+ if self._items[url]['current'] == self._items[url]['size']:
+ self._items[url]['finished'] = True
+ sys.stdout.write("\r" + " " * 80 + "\r")
+ for url in self._items.keys():
+ if self._items[url]['finished'] or self._items[url]['errored']:
+ continue
+ try:
+ sys.stdout.write("[%d %s: %.2f%%]" % (self._items[url]['id'],
+ basename(url).split('_')[0],
+ self._items[url]['current']*100/(self._items[url]['size'])))
+ except ZeroDivisionError:
+ pass
sys.stdout.flush()
+
+ def errored(self, url, message):
+ BaseDisplayStatus.errored(self, url, message)
+ sys.stdout.write("\r" + " " * 80 + "\rFailed: %s\n" % url)
Modified: branches/rewrite/src/Download.py
==============================================================================
--- branches/rewrite/src/Download.py (original)
+++ branches/rewrite/src/Download.py Wed Nov 10 16:20:42 2004
@@ -31,24 +31,18 @@
self.queue.append(item)
class DownloadThread(threading.Thread):
- """ Implement a Download Thread and use a DisplayInfo class to
+ """ Implement a Download Thread and use a DisplayStatus class to
notify the user about what it's currently doing."""
_Lock = threading.Lock()
- DisplayInfo = None
+ DisplayStatus = None
- def __init__(self, info = None, progress = None):
+ def __init__(self, info = None):
if info == None:
- self.DisplayInfo = TextDisplayInfo()
+ self.DisplayStatus = TextDisplayStatus()
else:
- self.DisplayInfo = info
-
- if progress == None:
- self._ProgressBar = TextProgressBar()
- else:
- self._ProgressBar = progress
+ self.DisplayStatus = info
- self.DisplayInfo.add(self._ProgressBar)
threading.Thread.__init__(self)
def run(self):
@@ -56,14 +50,14 @@
try:
url, filename = Download.queue.get_nowait()
except Empty:
- self.DisplayInfo.remove(self._ProgressBar)
+ pass
f = open(filename, "wb")
curl = pycurl.Curl()
curl.setopt(pycurl.FOLLOWLOCATION, 1)
curl.setopt(pycurl.MAXREDIRS, 5)
curl.setopt(pycurl.URL, url)
- curl.setopt(pycurl.WRITEDATA, f)
+ curl.setopt(pycurl.WRITEFUNCTION, f.write)
curl.setopt(pycurl.NOSIGNAL, 1)
curl.setopt(pycurl.CONNECTTIMEOUT, 30)
curl.setopt(pycurl.PROGRESSFUNCTION, self.progress)
@@ -72,8 +66,6 @@
self.url = url
- self._ProgressBar.text = self.url
-
# Store counter information about it
self._Lock.acquire()
DownloadQueue.counter += 1
@@ -83,13 +75,13 @@
try:
curl.perform()
except:
- self.DisplayInfo.failed(url)
+ self.DisplayStatus.errored(url, "")
curl.close()
try:
f.close()
- except IOError:
- pass
+ except IOError, e:
+ print e
# Store counter information about it
self._Lock.acquire()
@@ -97,12 +89,10 @@
self._counter = DownloadQueue.counter
self._Lock.release()
- self.DisplayInfo.done(url)
-
def progress(self, download_t, download_d, upload_t, upload_d):
- self._ProgressBar.max = download_t
- self._ProgressBar.current = download_d
- self.DisplayInfo.refresh()
+ if self.DisplayStatus[self.url] == None:
+ self.DisplayStatus.start(self.url, download_t)
+ self.DisplayStatus.update(self.url, download_d)
class Download:
""" Download queue """
@@ -110,7 +100,7 @@
""" Fetcher to use """
fetchers = []
- def __init__(self, uri, destine, max_threads=2):
+ def __init__(self, uri, destine, max_threads=3):
self.queue.put((uri, destine))
# Alloc all needed threads.