diff --git a/deluge/core/core.py b/deluge/core/core.py index 3ee9b8ed5..86033b3db 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -53,6 +53,7 @@ import deluge.libtorrent as lt from deluge.config import Config import deluge.common from deluge.core.torrent import Torrent +from deluge.core.torrentqueue import TorrentQueue # Get the logger log = logging.getLogger("deluge") @@ -70,6 +71,8 @@ class Core(dbus.service.Object): # A dictionary containing hash keys to Torrent objects self.torrents = {} + # Instantiate the TorrentQueue + self.queue = TorrentQueue() # Setup DBUS bus_name = dbus.service.BusName("org.deluge_torrent.Deluge", @@ -133,32 +136,62 @@ class Core(dbus.service.Object): torrent = Torrent(handle) # Store the Torrent object in the dictionary - self.torrents[handle.info_hash()] = torrent + self.torrents[str(handle.info_hash())] = torrent + + # Add the torrent id to the queue + self.queue.append(str(handle.info_hash())) # Emit the torrent_added signal self.torrent_added(str(handle.info_hash())) - @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", - in_signature="s", out_signature="") - def add_torrent_url(self, _url): - """Adds a torrent from url to the libtorrent session - """ - log.info("Adding torrent: %s", _url) - torrent = Torrent(url=_url) - self.session.add_torrent(torrent.torrent_info, - self.config["download_location"], - self.config["compact_allocation"]) - @dbus.service.method("org.deluge_torrent.Deluge") def shutdown(self): log.info("Shutting down core..") self.loop.quit() + + ## Queueing functions ###### + @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", + in_signature="s", out_signature="") + def queue_top(self, torrent_id): + # If the queue method returns True, then we should emit a signal + if self.queue.top(torrent_id): + self.torrent_queue_top() + # Store the new torrent position in the torrent object + self.torrents[torrent_id].set_position(self.queue[torrent_id]) + + @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", + in_signature="s", out_signature="") + def queue_up(self, torrent_id): + # If the queue method returns True, then we should emit a signal + if self.queue.up(torrent_id): + self.torrent_queue_up() + # Store the new torrent position in the torrent object + self.torrents[torrent_id].set_position(self.queue[torrent_id]) + + @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", + in_signature="s", out_signature="") + def queue_down(self, torrent_id): + # If the queue method returns True, then we should emit a signal + if self.queue.down(torrent_id): + self.torrent_queue_down() + # Store the new torrent position in the torrent object + self.torrents[torrent_id].set_position(self.queue[torrent_id]) + + @dbus.service.method(dbus_interface="org.deluge_torrent.Deluge", + in_signature="s", out_signature="") + def queue_bottom(self, torrent_id): + # If the queue method returns True, then we should emit a signal + if self.queue.bottom(torrent_id): + self.torrent_queue_bottom() + # Store the new torrent position in the torrent object + self.torrents[torrent_id].set_position(self.queue[torrent_id]) + # Signals @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", signature="s") - def torrent_added(self, torrentid): + def torrent_added(self, torrent_id): """Emitted when a new torrent is added to the core""" log.debug("torrent_added signal emitted") @@ -167,3 +200,27 @@ class Core(dbus.service.Object): def torrent_add_failed(self): """Emitted when a new torrent fails addition to the session""" log.debug("torrent_add_failed signal emitted") + + @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", + signature="s") + def torrent_queue_top(self, torrent_id): + """Emitted when a torrent is queued to the top""" + log.debug("torrent_queue_top signal emitted") + + @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", + signature="s") + def torrent_queue_up(self, torrent_id): + """Emitted when a torrent is queued up""" + log.debug("torrent_queue_up signal emitted") + + @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", + signature="s") + def torrent_queue_down(self, torrent_id): + """Emitted when a torrent is queued down""" + log.debug("torrent_queue_down signal emitted") + + @dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge", + signature="s") + def torrent_queue_bottom(self, torrent_id): + """Emitted when a torrent is queued to the bottom""" + log.debug("torrent_queue_bottom signal emitted") diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 4897ba468..55ebfe9e7 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -37,4 +37,8 @@ class Torrent: def __init__(self, handle): # Set the libtorrent handle self.handle = handle + + def set_position(self, position): + """Store the torrents queue position""" + self.position = position diff --git a/deluge/core/torrentqueue.py b/deluge/core/torrentqueue.py new file mode 100644 index 000000000..3e09cadcb --- /dev/null +++ b/deluge/core/torrentqueue.py @@ -0,0 +1,132 @@ +# +# torrentqueue.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 + +# Get the logger +log = logging.getLogger("deluge") + +class TorrentQueue: + def __init__(self): + log.debug("TorrentQueue init..") + self.queue = [] + + def __getitem__(self, torrent_id): + """Return the queue position of the torrent_id""" + return self.queue.index(torrent_id) + + def append(self, torrent_id): + """Append torrent_id to the bottom of the queue""" + log.debug("Append torrent %s to queue..", torrent_id) + self.queue.append(torrent_id) + + def prepend(self, torrent_id): + """Prepend torrent_id to the top of the queue""" + log.debug("Prepend torrent %s to queue..", torrent_id) + self.queue.insert(0, torrent_id) + + def up(self, torrent_id): + """Move torrent_id up one in the queue""" + if torrent_id not in self.queue: + # Raise KeyError if the torrent_id is not in the queue + raise KeyError + + log.debug("Move torrent %s up..", torrent_id) + # Get the index of the torrent_id + index = self.queue.index(torrent_id) + + # Can't queue up if torrent is already at top + if index is 0: + return False + + # Pop and insert the torrent_id at index - 1 + self.queue.insert(index - 1, self.queue.pop(index)) + + return True + + def top(self, torrent_id): + """Move torrent_id to top of the queue""" + if torrent_id not in self.queue: + # Raise KeyError if the torrent_id is not in the queue + raise KeyError + + log.debug("Move torrent %s to top..", torrent_id) + # Get the index of the torrent_id + index = self.queue.index(torrent_id) + + # Can't queue up if torrent is already at top + if index is 0: + return False + + # Pop and prepend the torrent_id + self.prepend(self.queue.pop(index)) + + return True + + def down(self, torrent_id): + """Move torrent_id down one in the queue""" + if torrent_id not in self.queue: + # Raise KeyError if torrent_id is not in the queue + raise KeyError + + log.debug("Move torrent %s down..", torrent_id) + # Get the index of the torrent_id + index = self.queue.index(torrent_id) + + # Can't queue down of torrent_id is at bottom + if index is len(self.queue) - 1: + return False + + # Pop and insert the torrent_id at index + 1 + self.queue.insert(index + 1, self.queue.pop(index)) + + return True + + def bottom(self, torrent_id): + """Move torrent_id to bottom of the queue""" + if torrent_id not in self.queue: + # Raise KeyError if torrent_id is not in the queue + raise KeyError + + log.debug("Move torrent %s to bottom..", torrent_id) + # Get the index of the torrent_id + index = self.queue.index(torrent_id) + + # Can't queue down of torrent_id is at bottom + if index is len(self.queue) - 1: + return False + + # Pop and append the torrent_id + self.append(self.queue.pop(index)) + + return True