diff --git a/deluge/core/core.py b/deluge/core/core.py index 609fdd778..109e96b71 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -182,12 +182,16 @@ class Core(dbus.service.Object): gobject.idle_add(self._shutdown) @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", - in_signature="say", out_signature="b") - def add_torrent_file(self, filename, filedump): + in_signature="ssay", out_signature="b") + def add_torrent_file(self, filename, save_path, filedump): """Adds a torrent file to the libtorrent session This requires the torrents filename and a dump of it's content """ - torrent_id = self.torrents.add(filename, filedump) + if save_path == "": + save_path = None + + torrent_id = self.torrents.add(filename, filedump=filedump, + save_path=save_path) # Run the plugin hooks for 'post_torrent_add' self.plugins.run_post_torrent_add(torrent_id) @@ -201,8 +205,8 @@ class Core(dbus.service.Object): return False @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", - in_signature="s", out_signature="b") - def add_torrent_url(self, url): + in_signature="ss", out_signature="b") + def add_torrent_url(self, url, save_path): log.info("Attempting to add url %s", url) # Get the actual filename of the torrent from the url provided. @@ -221,7 +225,7 @@ class Core(dbus.service.Object): return False # Add the torrent to session - return self.add_torrent_file(filename, filedump) + return self.add_torrent_file(filename, save_path, filedump) @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", in_signature="s", out_signature="") diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 082abf474..2a248650b 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -38,7 +38,7 @@ import deluge.common class Torrent: """Torrent holds information about torrents added to the libtorrent session. """ - def __init__(self, filename, handle, compact): + def __init__(self, filename, handle, compact, save_path): # Set the filename self.filename = filename # Set the libtorrent handle @@ -49,6 +49,8 @@ class Torrent: self.total_uploaded = 0 # Set the allocation mode self.compact = compact + # Where the torrent is being saved to + self.save_path = save_path # The tracker status self.tracker_status = "" @@ -59,7 +61,8 @@ class Torrent: def get_state(self): """Returns the state of this torrent for saving to the session state""" status = self.handle.status() - return (self.torrent_id, self.filename, self.compact, status.paused) + return (self.torrent_id, self.filename, self.compact, status.paused, + self.save_path) def get_eta(self): """Returns the ETA in seconds for this torrent""" diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index 04dbbdd17..d61057e32 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -47,11 +47,12 @@ from deluge.core.torrent import Torrent from deluge.log import LOG as log class TorrentState: - def __init__(self, torrent_id, filename, compact, paused): + def __init__(self, torrent_id, filename, compact, paused, save_path): self.torrent_id = torrent_id self.filename = filename self.compact = compact self.paused = paused + self.save_path = save_path class TorrentManagerState: def __init__(self): @@ -117,7 +118,8 @@ class TorrentManager: """Returns a list of torrent_ids""" return self.torrents.keys() - def add(self, filename, filedump=None, compact=None, paused=False): + def add(self, filename, filedump=None, compact=None, paused=False, + save_path=None): """Add a torrent to the manager and returns it's torrent_id""" log.info("Adding torrent: %s", filename) @@ -160,6 +162,10 @@ class TorrentManager: torrent_filedump = lt.bdecode(filedump) handle = None + # Make sure we have a valid download_location + if save_path is None: + save_path = self.config["download_location"] + # Make sure we are adding it with the correct allocation method. if compact is None: compact = self.config["compact_allocation"] @@ -167,7 +173,7 @@ class TorrentManager: try: handle = self.session.add_torrent( lt.torrent_info(torrent_filedump), - self.config["download_location"], + save_path, resume_data=fastresume, compact_mode=compact, paused=paused) @@ -179,7 +185,8 @@ class TorrentManager: return None # Create a Torrent object - torrent = Torrent(filename, handle, compact) + torrent = Torrent(filename, handle, compact, + save_path) # Add the torrent object to the dictionary self.torrents[torrent.torrent_id] = torrent @@ -187,7 +194,7 @@ class TorrentManager: handle.set_max_connections(self.max_connections) handle.set_max_uploads(self.max_uploads) - log.debug("Attemping to save torrent file: %s", filename) + log.debug("Attempting to save torrent file: %s", filename) # Test if the torrentfiles_location is accessible if os.access( os.path.join(self.config["torrentfiles_location"]), os.F_OK) \ @@ -303,7 +310,7 @@ class TorrentManager: # Try to add the torrents in the state to the session for torrent_state in state.torrents: self.add(torrent_state.filename, compact=torrent_state.compact, - paused=torrent_state.paused) + paused=torrent_state.paused, save_path=torrent_state.save_path) def save_state(self): """Save the state of the TorrentManager to the torrents.state file""" diff --git a/deluge/ui/functions.py b/deluge/ui/functions.py index 3c894f67e..1bd5d0a5f 100644 --- a/deluge/ui/functions.py +++ b/deluge/ui/functions.py @@ -85,7 +85,7 @@ def add_torrent_file(torrent_files): f = open(torrent_file, "rb") # Get the filename because the core doesn't want a path. (path, filename) = os.path.split(torrent_file) - result = core.add_torrent_file(filename, f.read()) + result = core.add_torrent_file(filename, str(), f.read()) f.close() if result is False: # The torrent was not added successfully. @@ -96,7 +96,7 @@ def add_torrent_url(torrent_url): core = get_core() from deluge.common import is_url if is_url(torrent_url): - result = core.add_torrent_url(torrent_url) + result = core.add_torrent_url(torrent_url, str()) if result is False: # The torrent url was not added successfully. log.warning("Torrent %s was not added successfully.", torrent_url) diff --git a/deluge/ui/gtkui/glade/main_window.glade b/deluge/ui/gtkui/glade/main_window.glade index 80b78d6b8..6e9aaca04 100644 --- a/deluge/ui/gtkui/glade/main_window.glade +++ b/deluge/ui/gtkui/glade/main_window.glade @@ -348,6 +348,286 @@ 1 2 10 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 + 10 + 15 + 15 + + + True + 7 + 2 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + PANGO_WRAP_WORD_CHAR + + + 1 + 2 + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + <b>Path:</b> + True + + + + + 1 + 2 + + + + + True + 0 + + + 1 + 2 + 6 + 7 + + + + + + True + 0 + + + 1 + 2 + 5 + 6 + + + + + + True + 0 + True + PANGO_WRAP_WORD_CHAR + + + 1 + 2 + 4 + 5 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 0 + 1 + <b>Name:</b> + True + + + + + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b>Next Announce:</b> + True + + + + + 6 + 7 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b>Tracker Status:</b> + True + + + + + 5 + 6 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b>Tracker:</b> + True + + + + + 4 + 5 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b>Total Size:</b> + True + + + + + 2 + 3 + GTK_FILL + + + + + True + 0 + True + PANGO_WRAP_WORD_CHAR + + + 1 + 2 + + + + + + True + 0 + + + 1 + 2 + 2 + 3 + + + + + + True + 0 + + + 1 + 2 + 3 + 4 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b># of files:</b> + True + + + + + 3 + 4 + GTK_FILL + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Torrent Info</b> + True + + + label_item + + + + + 1 + 2 + GTK_FILL + + True @@ -380,277 +660,18 @@ 4 5 - - True - 0 - - - 1 - 2 - - - - + True 0 + True + PANGO_WRAP_WORD_CHAR 3 4 - - - - - True - 0 - - - 1 - 2 - 1 - 2 - - - - - True - 0 - - - 3 - 4 - 1 - 2 - - - - - True - 0 - - - 1 - 2 - 2 - 3 - - - - - True - 0 - - - 3 - 4 - 2 - 3 - - - - - True - 0 - - - 1 - 2 - 3 - 4 - - - - - True - 0 - - - 3 - 4 - 3 - 4 - - - - - True - 5 - - - True - 0 - <b>Downloaded:</b> - True - - - - - - - True - 5 - - - True - 0 - <b>Uploaded:</b> - True - - - - - 1 - 2 - - - - - True - 5 - - - True - 0 - <b>Seeders:</b> - True - - - - - 2 - 3 - - - - - True - 5 - - - True - 0 - <b>Share Ratio:</b> - True - - - - - 3 - 4 - - - - - True - 15 - 5 - - - True - 0 - <b>Speed:</b> - True - - - - - 2 - 3 - - - - - True - 15 - 5 - - - True - 0 - <b>Speed:</b> - True - - - - - 2 - 3 - 1 - 2 - - - - - True - 15 - 5 - - - True - 0 - <b>Peers:</b> - True - - - - - 2 - 3 - 2 - 3 - - - - - True - 15 - 5 - - - True - 0 - <b>ETA:</b> - True - - - - - 2 - 3 - 3 - 4 - - - - - True - 0 - 1 - <b>Pieces:</b> - True - - - 4 - 5 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - - - - - 1 - 2 4 5 + @@ -677,18 +698,277 @@ - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + + + + + 1 + 2 + 4 + 5 + + + + + True + 0 + 1 + <b>Pieces:</b> + True + + + 4 + 5 + + + + + True + 15 + 5 + + + True + 0 + <b>ETA:</b> + True + + + + + 2 + 3 + 3 + 4 + + + + + True + 15 + 5 + + + True + 0 + <b>Peers:</b> + True + + + + + 2 + 3 + 2 + 3 + + + + + True + 15 + 5 + + + True + 0 + <b>Speed:</b> + True + + + + + 2 + 3 + 1 + 2 + + + + + True + 15 + 5 + + + True + 0 + <b>Speed:</b> + True + + + + + 2 + 3 + + + + + True + 5 + + + True + 0 + <b>Share Ratio:</b> + True + + + + + 3 + 4 + + + + + True + 5 + + + True + 0 + <b>Seeders:</b> + True + + + + + 2 + 3 + + + + + True + 5 + + + True + 0 + <b>Uploaded:</b> + True + + + + + 1 + 2 + + + + + True + 5 + + + True + 0 + <b>Downloaded:</b> + True + + + + + + True 0 - True - PANGO_WRAP_WORD_CHAR 3 4 - 4 - 5 - + 3 + 4 + + + + + True + 0 + + + 1 + 2 + 3 + 4 + + + + + True + 0 + + + 3 + 4 + 2 + 3 + + + + + True + 0 + + + 1 + 2 + 2 + 3 + + + + + True + 0 + + + 3 + 4 + 1 + 2 + + + + + True + 0 + + + 1 + 2 + 1 + 2 + + + + + True + 0 + + + 3 + 4 + + + + + True + 0 + + + 1 + 2 @@ -718,266 +998,6 @@ GTK_FILL - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 10 - 10 - 15 - 15 - - - True - 6 - 2 - 2 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b># of files:</b> - True - - - - - 2 - 3 - GTK_FILL - - - - - True - 0 - - - 1 - 2 - 2 - 3 - - - - - - True - 0 - - - 1 - 2 - 1 - 2 - - - - - - True - 0 - True - PANGO_WRAP_WORD_CHAR - - - 1 - 2 - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Total Size:</b> - True - - - - - 1 - 2 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Tracker:</b> - True - - - - - - - 3 - 4 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Tracker Status:</b> - True - - - - - - - 4 - 5 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Next Announce:</b> - True - - - - - 5 - 6 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 0 - 1 - <b>Name:</b> - True - - - - - GTK_FILL - - - - - True - 0 - True - PANGO_WRAP_WORD_CHAR - - - 1 - 2 - 3 - 4 - - - - - - True - 0 - - - 1 - 2 - 4 - 5 - - - - - - True - 0 - - - 1 - 2 - 5 - 6 - - - - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Torrent Info</b> - True - - - label_item - - - - - 1 - 2 - GTK_FILL - -