From 7ca17a3922d8f8a5009f3bf0345e1b98ffd91391 Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Sun, 22 Jul 2007 03:01:38 +0000 Subject: [PATCH] Changed the way adding torrents is done. The core is now sent the torrent file data and saves it's own copy of the torrent file. Start of receiving signals in the UI. --- deluge/common.py | 4 ++ deluge/core/core.py | 72 ++++++++++++++++++++++++++++++------ deluge/core/torrent.py | 10 ++--- deluge/ui/gtkui/functions.py | 12 +++++- deluge/ui/gtkui/gtkui.py | 4 ++ deluge/ui/gtkui/signals.py | 66 +++++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 deluge/ui/gtkui/signals.py diff --git a/deluge/common.py b/deluge/common.py index 36e249496..4daa2aeef 100644 --- a/deluge/common.py +++ b/deluge/common.py @@ -59,6 +59,10 @@ def get_default_download_dir(): """Returns the default download directory""" return os.environ.get("HOME") +def get_default_torrent_dir(): + """Returns the default torrent directory""" + return os.path.join(get_config_dir(), "torrentfiles") + ## Formatting text functions def estimate_eta(total_size, total_done, download_rate): diff --git a/deluge/core/core.py b/deluge/core/core.py index 05b2a07c6..3ee9b8ed5 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -32,6 +32,7 @@ # statement from all source files in the program, then also delete it here. import logging +import os.path try: import dbus, dbus.service @@ -57,18 +58,27 @@ from deluge.core.torrent import Torrent log = logging.getLogger("deluge") DEFAULT_PREFS = { - "listen_ports": [6881, 6891], + "compact_allocation": True, "download_location": deluge.common.get_default_download_dir(), - "compact_allocation": True + "listen_ports": [6881, 6891], + "torrentfiles_location": deluge.common.get_default_torrent_dir() } class Core(dbus.service.Object): def __init__(self, path="/org/deluge_torrent/Core"): log.debug("Core init..") + + # A dictionary containing hash keys to Torrent objects + self.torrents = {} + + # Setup DBUS bus_name = dbus.service.BusName("org.deluge_torrent.Deluge", bus=dbus.SessionBus()) dbus.service.Object.__init__(self, bus_name, path) + + # Get config self.config = Config("core.conf", DEFAULT_PREFS) + # Setup the libtorrent session and listen on the configured ports log.debug("Starting libtorrent session..") self.session = lt.session() @@ -81,20 +91,52 @@ class Core(dbus.service.Object): self.loop = gobject.MainLoop() self.loop.run() - # Exported Methods @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", - in_signature="s", out_signature="") - def add_torrent_file(self, _filename): + in_signature="say", out_signature="") + def add_torrent_file(self, filename, filedump): """Adds a torrent file to the libtorrent session + This requires the torrents filename and a dump of it's content """ - log.info("Adding torrent: %s", _filename) - torrent = Torrent(filename=_filename) - self.session.add_torrent(torrent.torrent_info, - self.config["download_location"], + log.info("Adding torrent: %s", filename) + + # Convert the filedump data array into a string of bytes + filedump = "".join(chr(b) for b in filedump) + + # Bdecode the filedata sent from the UI + torrent_filedump = lt.bdecode(filedump) + try: + handle = self.session.add_torrent(lt.torrent_info(torrent_filedump), + self.config["download_location"], self.config["compact_allocation"]) + except RuntimeError: + log.warning("Error adding torrent") + + if not handle or not handle.is_valid(): + # The torrent was not added to the session + # Emit the torrent_add_failed signal + self.torrent_add_failed() + return + + # Write the .torrent file to the torrent directory + log.debug("Attemping to save torrent file: %s", filename) + try: + f = open(os.path.join(self.config["torrentfiles_location"], + filename), + "wb") + f.write(filedump) + f.close() + except IOError: + log.warning("Unable to save torrent file: %s", filename) + + # Create a Torrent object + torrent = Torrent(handle) + + # Store the Torrent object in the dictionary + self.torrents[handle.info_hash()] = torrent + # Emit the torrent_added signal - self.torrent_added() + self.torrent_added(str(handle.info_hash())) @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", in_signature="s", out_signature="") @@ -115,7 +157,13 @@ class Core(dbus.service.Object): # Signals @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", - signature="") - def torrent_added(self): + signature="s") + def torrent_added(self, torrentid): """Emitted when a new torrent is added to the core""" log.debug("torrent_added signal emitted") + + @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", + signature="") + def torrent_add_failed(self): + """Emitted when a new torrent fails addition to the session""" + log.debug("torrent_add_failed signal emitted") diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index c9c5d6019..4897ba468 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -34,9 +34,7 @@ import deluge.libtorrent as lt class Torrent: - def __init__(self, filename=None, url=None): - # Load the torrent file - if filename is not None: - torrent_file = lt.bdecode(open(filename, 'rb').read()) - self.torrent_info = lt.torrent_info(torrent_file) - + def __init__(self, handle): + # Set the libtorrent handle + self.handle = handle + diff --git a/deluge/ui/gtkui/functions.py b/deluge/ui/gtkui/functions.py index 750e0e210..f06e8f332 100644 --- a/deluge/ui/gtkui/functions.py +++ b/deluge/ui/gtkui/functions.py @@ -32,6 +32,7 @@ # statement from all source files in the program, then also delete it here. import logging +import os.path try: import dbus, dbus.service @@ -71,7 +72,16 @@ def add_torrent_file(): """Opens a file chooser dialog and adds any files selected to the core""" at_dialog = AddTorrentDialog() torrent_files = at_dialog.run() + if torrent_files is None: + log.debug("No torrent files selected..") + return log.debug("Attempting to add torrent files: %s", torrent_files) core = get_core() for torrent_file in torrent_files: - core.add_torrent_file(torrent_file) + # Open the .torrent file for reading because we need to send it's + # contents to the core. + f = open(torrent_file, "rb") + # Get the filename because the core doesn't want a path. + (path, filename) = os.path.split(torrent_file) + core.add_torrent_file(filename, f.read()) + f.close() diff --git a/deluge/ui/gtkui/gtkui.py b/deluge/ui/gtkui/gtkui.py index 62e231983..dfd64fcff 100644 --- a/deluge/ui/gtkui/gtkui.py +++ b/deluge/ui/gtkui/gtkui.py @@ -40,6 +40,7 @@ import gettext import pkg_resources from mainwindow import MainWindow +from signals import Signals # Get the logger log = logging.getLogger("deluge") @@ -60,6 +61,9 @@ class GtkUI: # Initialize the main window self.main_window = MainWindow() + # Start the signal receiver + self.signal_receiver = Signals() + # Show the main window self.main_window.show() diff --git a/deluge/ui/gtkui/signals.py b/deluge/ui/gtkui/signals.py new file mode 100644 index 000000000..90ba2a654 --- /dev/null +++ b/deluge/ui/gtkui/signals.py @@ -0,0 +1,66 @@ +# +# signals.py +# +# Copyright (C) 2007 Andrew Resch ('andar') +# +# Deluge is free software. +# +# You may redistribute it and/or modify it under the terms of the +# GNU General Public License, as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# deluge is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# +# In addition, as a special exception, the copyright holders give +# permission to link the code of portions of this program with the OpenSSL +# library. +# You must obey the GNU General Public License in all respects for all of +# the code used other than OpenSSL. If you modify file(s) with this +# exception, you may extend this exception to your version of the file(s), +# but you are not obligated to do so. If you do not wish to do so, delete +# this exception statement from your version. If you delete this exception +# statement from all source files in the program, then also delete it here. + +import logging + +try: + import dbus, dbus.service + dbus_version = getattr(dbus, "version", (0,0,0)) + if dbus_version >= (0,41,0) and dbus_version < (0,80,0): + import dbus.glib + elif dbus_version >= (0,80,0): + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) + else: + pass +except: dbus_imported = False +else: dbus_imported = True + +import pygtk +pygtk.require('2.0') +import gtk, gtk.glade + +import functions +from deluge.config import Config + +# Get the logger +log = logging.getLogger("deluge") + +class Signals: + def __init__(self): + core = functions.get_core() + core.connect_to_signal("torrent_added", self.torrent_added_signal) + + def torrent_added_signal(self, torrentid): + log.debug("torrent_added signal received..") + log.debug("torrent id: %s", torrentid)