diff options
| -rw-r--r-- | module/Plugin.py | 7 | ||||
| -rw-r--r-- | module/file_list.py | 12 | ||||
| -rw-r--r-- | module/gui/MainWindow.py | 19 | ||||
| -rw-r--r-- | module/gui/connector.py | 20 | ||||
| -rwxr-xr-x | module/network/Request.py | 130 | ||||
| -rw-r--r-- | pyLoadCore.py | 9 | ||||
| -rwxr-xr-x | pyLoadGui.py | 16 | 
7 files changed, 186 insertions, 27 deletions
| diff --git a/module/Plugin.py b/module/Plugin.py index 3285ae8dd..7e6ca4e35 100644 --- a/module/Plugin.py +++ b/module/Plugin.py @@ -85,8 +85,11 @@ class Plugin():          if re.search(r"(?!http://).*\.(dlc|ccf|rsdf|txt)", self.parent.url):              return exists(self.parent.url)          header = self.req.load(self.parent.url, just_header=True) -        if re.search(r"HTTP/1.1 404 Not Found", header): -            return False +        try: +            if re.search(r"HTTP/1.1 404 Not Found", header): +                return False +        except: +            pass          return True      def get_file_url(self): diff --git a/module/file_list.py b/module/file_list.py index 1d3b1a68f..f156e2c0d 100644 --- a/module/file_list.py +++ b/module/file_list.py @@ -350,6 +350,15 @@ class File_List(object):              pyfile.package = pypack              pypack.files.append(pyfile)              packager.file_list.data[key][n] = pypack +         +        def resetFileStatus(packager, fileid): +            packager.file_list.lock.acquire() +            try: +                key, n, pyfile, pypack, pid = packager._getFileFromID(fileid) +                pyfile.init() +                pyfile.status.type = None +            finally: +                packager.file_list.lock.release()         #oooops, duplicate?          def removeFileFromPackage(packager, id, pid): @@ -380,6 +389,9 @@ class PyLoadFile():          self.core = file_list.core          self.package = None          self.filename = "n/a" +        self.init() +     +    def init(self):          self.active = False          pluginName = self._get_my_plugin()          if pluginName: diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index f72ad97de..837125263 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -153,6 +153,9 @@ class MainWindow(QMainWindow):          self.tabs["collector"]["l"].addWidget(groupPackage, 0, 0)          self.tabs["collector"]["l"].addWidget(groupLinks, 0, 1)          self.connect(toQueue, SIGNAL("clicked()"), self.slotPushPackageToQueue) +        self.tabs["collector"]["package_view"].setContextMenuPolicy(Qt.CustomContextMenu) +        self.tabs["collector"]["link_view"].setContextMenuPolicy(Qt.CustomContextMenu) +        self.tabs["queue"]["view"].setContextMenuPolicy(Qt.CustomContextMenu)      def init_context(self):          """ @@ -160,8 +163,12 @@ class MainWindow(QMainWindow):          """          self.queueContext = QMenu()          self.queueContext.buttons = {} +        self.queueContext.item = (None, None)          self.queueContext.buttons["remove"] = QAction("Remove", self.queueContext) +        self.queueContext.buttons["restart"] = QAction("Restart", self.queueContext)          self.queueContext.addAction(self.queueContext.buttons["remove"]) +        self.queueContext.addAction(self.queueContext.buttons["restart"]) +        self.connect(self.queueContext.buttons["restart"], SIGNAL("triggered()"), self.slotRestartDownload)      def slotToggleStatus(self, status):          """ @@ -273,8 +280,8 @@ class MainWindow(QMainWindow):          globalPos = self.tabs["queue"]["view"].mapToGlobal(pos)          i = self.tabs["queue"]["view"].itemAt(pos)          i.setSelected(True) -        self.addFav.setData(QVariant(i)) -        self.showContext.exec_(globalPos) +        self.queueContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) +        self.queueContext.exec_(globalPos)      def slotPackageCollectorContextMenu(self, pos):          """ @@ -287,4 +294,12 @@ class MainWindow(QMainWindow):              custom context menu in link collector view requested          """          pass +     +    def slotRestartDownload(self): +        """ +            restart download action is triggered +        """ +        id, isTopLevel = self.queueContext.item +        if not id == None: +            self.emit(SIGNAL("restartDownload"), id, isTopLevel) diff --git a/module/gui/connector.py b/module/gui/connector.py index 2a1ce511e..75781ebb1 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -210,3 +210,23 @@ class connector(QThread):              self.proxy.push_package_2_queue(packid)          finally:              self.mutex.unlock() +     +    def restartPackage(self, packid): +        """ +            restart a package +        """ +        self.mutex.lock() +        try: +            self.proxy.restart_package(packid) +        finally: +            self.mutex.unlock() +     +    def restartFile(self, fileid): +        """ +            restart a file +        """ +        self.mutex.lock() +        try: +            self.proxy.restart_file(fileid) +        finally: +            self.mutex.unlock() diff --git a/module/network/Request.py b/module/network/Request.py index 7cdae7c0f..ab90044d3 100755 --- a/module/network/Request.py +++ b/module/network/Request.py @@ -15,7 +15,8 @@ import urllib  from cStringIO import StringIO  try: -    import pycurl +    #import pycurl +    raise Exception  except:      import urllib2      from Keepalive import HTTPHandler @@ -49,12 +50,22 @@ class Request:          self.auth = False          self.timeout = 5 - +         +        bufferBase = 1024 +        bufferMulti = 2 +        self.bufferSize = bufferBase*bufferMulti +        self.canContinue = False +         +        self.dl_speed = 0.0 +         +        self.speedLimitActive = False +        self.maxSpeed = 100 * 1024 +                  try:              if pycurl: self.curl = True          except:              self.curl = False - +                  if self.curl:              self.init_curl() @@ -98,6 +109,7 @@ class Request:          self.pycurl.setopt(pycurl.PROGRESSFUNCTION, self.progress)          self.pycurl.setopt(pycurl.AUTOREFERER, 1)          self.pycurl.setopt(pycurl.HEADERFUNCTION, self.write_header) +        self.pycurl.setopt(pycurl.BUFFERSIZE, self.bufferSize)          self.pycurl.setopt(pycurl.USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.10") @@ -150,6 +162,7 @@ class Request:              return self.get_rep()          else: +                          req = urllib2.Request(url, data=post)              if ref and self.lastURL is not None: @@ -159,12 +172,13 @@ class Request:                  self.add_cookies(req)                  #add cookies -            rep = self.opener.open(req) +            rep = self.opener.open(req, timeout=2)              for cookie in self.cj.make_cookies(rep, req):                  self.cookies.append(cookie) - -            output = rep.read() +             +            if not just_header: +                output = rep.read()              if rep.headers.has_key("content-encoding"):                  if rep.headers["content-encoding"] == "gzip": @@ -172,6 +186,9 @@ class Request:              self.lastEffectiveURL = rep.geturl()              self.lastURL = url +             +            if just_header: +                return rep.headers              return output @@ -232,13 +249,16 @@ class Request:              get = ""          if self.curl: -            file_temp = self.get_free_name(file_name + ".part") -            fp = open(file_temp, 'wb') +            file_temp = self.get_free_name(file_name) + ".part" +            self.fp = open(file_temp, 'wb') +            if not self.canContinue: +                self.fp.truncate() +            partSize = self.fp.tell()              self.init_curl()              self.pycurl.setopt(pycurl.URL, url) -            self.pycurl.setopt(pycurl.WRITEDATA, fp) +            #self.pycurl.setopt(pycurl.WRITEDATA, fp)              if cookies:                  self.curl_enable_cookies() @@ -254,7 +274,45 @@ class Request:              self.dl_arrived = 0              self.dl_time = time.time()              self.dl = True - +             +            self.chunkSize = 0 # only for loop to start +            self.chunkRead = 0 +            self.subStartTime = 0 +            self.maxChunkSize = 0 +             +            def restLimit(): +                subTime = time.time() - self.subStartTime +                if subTime <= 1: +                    if self.speedLimitActive: +                        return self.maxChunkSize +                    else: +                        return -1 +                else: +                    self.dl_speed = float(self.chunkRead/1024) / subTime +                     +                    self.subStartTime = time.time() +                    self.chunkRead = 0 +                    if self.maxSpeed > 0: +                        self.maxChunkSize = self.maxSpeed +                    else: +                        self.maxChunkSize = 0 +                    return 0 + +            def writefunc(buf): +                if self.abort: +                    raise AbortDownload +                chunkSize = len(buf) +                while chunkSize > restLimit() > -1: +                    time.sleep(0.05) +                self.maxChunkSize -= chunkSize +                self.fp.write(buf) +                self.chunkRead += chunkSize +                self.dl_arrived += chunkSize +                 +             +            self.pycurl.setopt(pycurl.WRITEFUNCTION, writefunc) +             +                          self.pycurl.perform()              #~ if "..." in file_name:                  #~ download_folder = dirname(file_name) + sep @@ -266,14 +324,17 @@ class Request:                          #~ file_name = file_name.replace("=?UTF-8?B?", "").replace("?=", "==")                          #~ file_name = b64decode(file_name)                      #~ file_name = download_folder + sep + file_name -                         +                     +            self.fp.close() +             +            if self.abort: +                raise AbortDownload +                          rename(file_temp, self.get_free_name(file_name))              self.dl = False              self.dl_finished = time.time() -            fp.close() -              return True          else: @@ -290,10 +351,15 @@ class Request:                  for cookie in self.cj.make_cookies(rep, req):                      self.cookies.append(cookie) - +                     +            self.dl = False              if not self.dl:                  self.dl = True -                file = open(file_name, 'wb') +                file_temp = self.get_free_name(file_name) + ".part" +                file = open(file_temp, 'wb') +                if not self.canContinue: +                    file.truncate() +                partSize = file.tell()                  conn = self.downloader.open(req, post)                  if conn.headers.has_key("content-length"): @@ -302,14 +368,37 @@ class Request:                      self.dl_size = 0                  self.dl_arrived = 0                  self.dl_time = time.time() -                for chunk in conn: -                    if self.abort: raise AbortDownload -                    self.dl_arrived += len(chunk) -                    file.write(chunk) +                 +                chunkSize = 1 +                while chunkSize > 0: +                    if self.abort: +                        break +                    chunkRead = 0 +                    if not self.speedLimitActive: +                        maxChunkSize = -1 +                    elif self.maxSpeed > 0: +                        maxChunkSize = self.maxSpeed +                    else: +                        maxChunkSize = 0 +                    subStartTime = time.time() +                    while (time.time() - subStartTime) <= 1: +                        if maxChunkSize == -1 or chunkRead <= maxChunkSize: +                            chunk = conn.read(self.bufferSize) +                            chunkSize = len(chunk) +                            file.write(chunk) +                            self.dl_arrived += chunkSize +                            chunkRead += chunkSize +                        else: +                            time.sleep(0.05) +                    subTime = time.time() - subStartTime +                    self.dl_speed = float(chunkRead/1024) / subTime                  file.close() +                if self.abort: +                    raise AbortDownload                  self.dl = False                  self.dl_finished = time.time() +                rename(file_temp, self.get_free_name(file_name))                  return True      def write_header(self, string): @@ -328,7 +417,8 @@ class Request:      def get_speed(self):          try: -            return (self.dl_arrived / ((time.time() if self.dl else self.dl_finished)  - self.dl_time)) / 1024 +            #return (self.dl_arrived / ((time.time() if self.dl else self.dl_finished)  - self.dl_time)) / 1024 +            return self.dl_speed          except:              return 0 diff --git a/pyLoadCore.py b/pyLoadCore.py index 8ca45f2e2..232adc253 100644 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -473,7 +473,14 @@ class ServerMethods():              self.core.file_list.collector.removeFile(fid)
      def push_package_2_queue(self, id):
 -        self.core.file_list.packager.pushPackage2Queue(id)
 +        self.core.file_list.packager.pushPackage2Queue(id) +     +    def restart_package(self, packid): +        for id in self.core.file_list.packager.getPackageFiles(packid): +            self.core.file_list.packager.resetFileStatus(id) +     +    def restart_file(self, fileid): +        self.core.file_list.packager.resetFileStatus(fileid)
      #def move_urls_up(self, ids):
      #    for id in ids:
 diff --git a/pyLoadGui.py b/pyLoadGui.py index 9ff070027..997a2f781 100755 --- a/pyLoadGui.py +++ b/pyLoadGui.py @@ -107,6 +107,7 @@ class main(QObject):          self.connect(self.mainWindow, SIGNAL("setDownloadStatus"), self.slotSetDownloadStatus)          self.connect(self.mainWindow, SIGNAL("saveMainWindow"), self.slotSaveMainWindow)          self.connect(self.mainWindow, SIGNAL("pushPackageToQueue"), self.slotPushPackageToQueue) +        self.connect(self.mainWindow, SIGNAL("restartDownload"), self.slotRestartDownload)      def slotShowConnector(self):          """ @@ -380,7 +381,8 @@ class main(QObject):          """          mainWindowNode = self.parser.xml.elementsByTagName("mainWindow").item(0)          if mainWindowNode.isNull(): -            raise Exception("null") +            mainWindowNode = self.parser.xml.createElement("mainWindow") +            self.parser.root.appendChild(mainWindowNode)          stateNode = mainWindowNode.toElement().elementsByTagName("state").item(0)          geoNode = mainWindowNode.toElement().elementsByTagName("geometry").item(0)          newStateNode = self.parser.xml.createTextNode(state) @@ -399,7 +401,7 @@ class main(QObject):          """          mainWindowNode = self.parser.xml.elementsByTagName("mainWindow").item(0)          if mainWindowNode.isNull(): -            raise Exception("null") +            return          nodes = self.parser.parseNode(mainWindowNode, "dict")          state = str(nodes["state"].text()) @@ -414,6 +416,16 @@ class main(QObject):          """          self.connector.pushPackageToQueue(id) +    def slotRestartDownload(self, id, isPack): +        """ +            emitted from main window +            restart download +        """ +        if isPack: +            self.connector.restartPackage(id) +        else: +            self.connector.restartFile(id) +          class Loop(QThread):          """              main loop (not application loop) | 
