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)