r110 - in /debtorrent/trunk: DebTorrent/ConfigDir.py DebTorrent/launchmanycore.py TODO btlaunchmany.py

camrdale-guest at users.alioth.debian.org camrdale-guest at users.alioth.debian.org
Fri Jun 15 01:21:00 UTC 2007


Author: camrdale-guest
Date: Fri Jun 15 01:21:00 2007
New Revision: 110

URL: http://svn.debian.org/wsvn/debtorrent/?sc=1&rev=110
Log:
Cache torrent files and the list of running torrents and resume properly when restarted.

Modified:
    debtorrent/trunk/DebTorrent/ConfigDir.py
    debtorrent/trunk/DebTorrent/launchmanycore.py
    debtorrent/trunk/TODO
    debtorrent/trunk/btlaunchmany.py

Modified: debtorrent/trunk/DebTorrent/ConfigDir.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/DebTorrent/ConfigDir.py?rev=110&op=diff
==============================================================================
--- debtorrent/trunk/DebTorrent/ConfigDir.py (original)
+++ debtorrent/trunk/DebTorrent/ConfigDir.py Fri Jun 15 01:21:00 2007
@@ -396,9 +396,9 @@
         
         """
         
-        t = tohex(t)
         if v == -1:
             v = max(self.getTorrentVariations(t))   # potential exception
+        t = tohex(t)
         if v:
             t += '.'+str(v)
         try:
@@ -427,12 +427,12 @@
         
         """
 
+        if v == -1:
+            try:
+                v = max(self.getTorrentVariations(t))+1
+            except:
+                v = 0
         t = tohex(t)
-        if v == -1:
-            try:
-                v = max(self.getTorrentVariations(t))+1
-            except:
-                v = 0
         if v:
             t += '.'+str(v)
         try:

Modified: debtorrent/trunk/DebTorrent/launchmanycore.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/DebTorrent/launchmanycore.py?rev=110&op=diff
==============================================================================
--- debtorrent/trunk/DebTorrent/launchmanycore.py (original)
+++ debtorrent/trunk/DebTorrent/launchmanycore.py Fri Jun 15 01:21:00 2007
@@ -144,7 +144,8 @@
 
         d = BT1Download(self.display, self.finished, self.error,
                         controller.exchandler, self.doneflag, config, response,
-                        hash, myid, self.rawserver, controller.listen_port)
+                        hash, myid, self.rawserver, controller.listen_port, 
+                        self.controller.configdir)
         self.d = d
 
     def start(self):
@@ -287,6 +288,8 @@
     @ivar config: the configuration parameters
     @type Output: unknown
     @ivar Output: the displayer instance to use
+    @type configdir: L{ConfigDir.ConfigDir}
+    @ivar configdir: the configuration and cache directory manager
     @type torrent_dir: C{string}
     @ivar torrent_dir: the directory to parse for torrent files
     @type torrent_cache: C{dictionary}
@@ -300,7 +303,7 @@
     @type stats_period: C{int}
     @ivar stats_period: the number of seconds between printing the stats for the user
     @type torrent_list: C{list} of C{string}
-    @ivar torrent_list: the list of known torrents' info hashes
+    @ivar torrent_list: the list of running torrents' info hashes
     @type downloads: C{dictionary}
     @ivar downloads: the currently running downloaders, keys are info hashes
     @type counter: C{int}
@@ -324,19 +327,22 @@
     
     """
     
-    def __init__(self, config, Output):
+    def __init__(self, config, Output, configdir):
         """Initialize the instance.
         
         @type config: C{dictionary}
         @param config: the configuration parameters
         @type Output: unknown
         @param Output: the displayer instance to use
+        @type configdir: L{ConfigDir.ConfigDir}
+        @param configdir: the configuration and cache directory manager
         
         """
         
         try:
             self.config = config
             self.Output = Output
+            self.configdir = configdir
 
             self.torrent_dir = config['torrent_dir']
             self.torrent_cache = {}
@@ -388,7 +394,13 @@
 #            self.rawserver.add_task(self.scan, 0)
             self.rawserver.add_task(self.stats, 0)
 
+            # Restore the previous state of the downloads
+            self.unpickle(self.configdir.getState())
+            
             self.handler.listen_forever()
+
+            # Save the current state of the downloads
+            self.configdir.saveState(self.pickle())
 
             self.Output.message('shutting down')
             self.hashcheck_queue = []
@@ -396,7 +408,6 @@
                 self.Output.message('dropped "'+self.torrent_cache[hash]['path']+'"')
                 self.downloads[hash].shutdown()
             self.rawserver.shutdown()
-            # TODO: save (cache/pickle) the status of torrents for quick restart
 
         except:
             data = StringIO()
@@ -406,7 +417,6 @@
 
     def scan(self):
         """Scan the torrent directory for changes."""
-        # TODO: on startup scan the torrentcache for old torrents
         self.rawserver.add_task(self.scan, self.scan_period)
                                 
         r = parsedir(self.torrent_dir, self.torrent_cache,
@@ -502,18 +512,21 @@
         self.downloads[hash].shutdown()
         del self.downloads[hash]
         
-    def add(self, hash, data):
+    def add(self, hash, data, save_cache = True):
         """Start a new torrent running.
         
         @type hash: C{string}
         @param hash: the info hash of the torrent
         @type data: C{dictionary}
         @param data: various info about the torrent, including the metainfo
-        
-        """
-        
-        # TODO: save the torrent file to the torrent cache
-        self.torrent_cache.setdefault(hash, data)
+        @type save_cache: C{boolean}
+        @param save_cache: whether to save the torrent metainfo to the cache
+        
+        """
+        
+        if save_cache:
+            self.configdir.writeTorrent(data['metainfo'], hash)
+        self.torrent_cache[hash] = data
         c = self.counter
         self.counter += 1
         x = ''
@@ -702,3 +715,54 @@
         """
         
         self.Output.exception(s)
+
+    def pickle(self):
+        """Save the current state of the downloads to a writable state.
+        
+        Pickled data format::
+    
+            d['torrent cache'] = {info hash: C{dictionary}, ...}
+                        Contains the cached data for all running torrents, keys are 
+                        the torrent's info hash, and the data is all the data
+                        saved in L{torrent_cache}. There is also a new key added
+                        "paused" for torrent's that were running but paused.
+
+        @rtype: C{dictionary}
+        @return: the saved state of the current downloads
+        
+        """
+        
+        d = {}
+        for hash in self.torrent_list:
+            d[hash] = {}
+            for k in self.torrent_cache[hash].keys():
+                if k != 'metainfo':
+                    d[hash][k] = self.torrent_cache[hash][k]
+            if not self.downloads[hash].d.unpauseflag.isSet():
+                d[hash]['paused'] = 1
+        return {'torrent cache': d}
+
+    def unpickle(self, data):
+        """Restore the current state of the downloads.
+        
+        Reads the list of previosuly running torrents, loads their metainfo
+        from the cache and starts the downloads running. Also pauses the
+        download if it was previously paused.
+        
+        @type data: C{dictionary}
+        @param data: the saved state of the previously running downloads downloads
+        
+        """
+        
+        if data is None:
+            return
+        
+        d = data['torrent cache']
+        for hash in d:
+            paused = d[hash].pop('paused', False)
+            metainfo = self.configdir.getTorrent(hash)
+            if metainfo:
+                d[hash]['metainfo'] = metainfo
+                self.add(hash, d[hash], False)
+                if paused:
+                    self.downloads[hash].d.Pause()

Modified: debtorrent/trunk/TODO
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/TODO?rev=110&op=diff
==============================================================================
--- debtorrent/trunk/TODO (original)
+++ debtorrent/trunk/TODO Fri Jun 15 01:21:00 2007
@@ -24,6 +24,16 @@
 Instead of a per-module DEBUG setting, implement a program-wide debug level,
 set by a configuration option. Each level would print differing amounts of 
 debug information to the output/log.
+
+
+Different forms of HTTP Downloading may open too many connections
+
+There are a lot of different ways for the program to download from a mirror,
+including the HTTPDownloader for pieces (one per torrent), the HTTPCache
+downloader (one per program), etc... Most are threaded, and could end up
+opening a lot of connections to a single mirror. A better implementation 
+would be to manage these connections all in one place, so that they can be
+controlled together and a max number of connections could be set.
 
 
 Make the URL download better

Modified: debtorrent/trunk/btlaunchmany.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/btlaunchmany.py?rev=110&op=diff
==============================================================================
--- debtorrent/trunk/btlaunchmany.py (original)
+++ debtorrent/trunk/btlaunchmany.py Fri Jun 15 01:21:00 2007
@@ -168,7 +168,7 @@
         print 'error: ' + str(e) + '\nrun with no args for parameter explanations'
         exit(1)
 
-    LaunchMany(config, HeadlessDisplayer())
+    LaunchMany(config, HeadlessDisplayer(), configdir)
     if Exceptions:
         print '\nEXCEPTION:'
         print Exceptions[0]




More information about the Debtorrent-commits mailing list