More work on the queue torrent plugin and plugins in general.

This commit is contained in:
Andrew Resch 2007-08-10 08:15:02 +00:00
parent 78e225526c
commit 13fc181fa2
10 changed files with 896 additions and 1005 deletions

View File

@ -112,6 +112,10 @@ class Core(dbus.service.Object):
"""
log.info("Adding torrent: %s", filename)
torrent_id = self.torrents.add(filename, filedump)
# Run the plugin hooks for 'post_torrent_add'
self.plugins.run_post_torrent_add(torrent_id)
if torrent_id is not None:
# Emit the torrent_added signal
self.torrent_added(torrent_id)
@ -123,6 +127,8 @@ class Core(dbus.service.Object):
def remove_torrent(self, torrent_id):
log.debug("Removing torrent %s from the core.", torrent_id)
if self.torrents.remove(torrent_id):
# Run the plugin hooks for 'post_torrent_remove'
self.plugins.run_post_torrent_remove(torrent_id)
# Emit the torrent_removed signal
self.torrent_removed(torrent_id)
@ -153,35 +159,6 @@ class Core(dbus.service.Object):
status = pickle.dumps(status)
return status
## 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.torrents.queue.top(torrent_id):
self.torrent_queue_changed()
@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.torrents.queue.up(torrent_id):
self.torrent_queue_changed()
@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.torrents.queue.down(torrent_id):
self.torrent_queue_changed()
@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.torrents.queue.bottom(torrent_id):
self.torrent_queue_changed()
# Signals
@dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge",
signature="s")
@ -201,12 +178,6 @@ class Core(dbus.service.Object):
"""Emitted when a torrent has been removed from the core"""
log.debug("torrent_remove signal emitted")
@dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge",
signature="")
def torrent_queue_changed(self):
"""Emitted when a torrent queue position is changed"""
log.debug("torrent_queue_changed signal emitted")
@dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge",
signature="s")
def torrent_paused(self, torrent_id):

View File

@ -41,6 +41,9 @@ log = logging.getLogger("deluge")
class PluginManager:
def __init__(self):
# Set up the hooks dictionary
self.hooks = {"post_torrent_add": []}
# This will load any .eggs in the plugins folder inside the main
# deluge egg.. Need to scan the local plugin folder too.
@ -54,10 +57,35 @@ class PluginManager:
egg = pkg_env[name][0]
egg.activate()
modules = []
for name in egg.get_entry_map("deluge.plugin"):
entry_point = egg.get_entry_info("deluge.plugin", name)
for name in egg.get_entry_map("deluge.plugin.core"):
entry_point = egg.get_entry_info("deluge.plugin.core", name)
cls = entry_point.load()
instance = cls()
instance = cls(self)
self.plugins[name] = instance
log.info("Load plugin %s", name)
def __getitem__(self, key):
return self.plugins[key]
log.info("Plugins loaded: %s", self.plugins)
def register_hook(self, hook, function):
"""Register a hook function with the plugin manager"""
try:
self.hooks[hook].append(function)
except KeyError:
log.warning("Plugin attempting to register invalid hook.")
def run_post_torrent_add(self, torrent_id):
log.debug("run_post_torrent_add")
try:
for function in self.hooks["post_torrent_add"]:
function(torrent_id)
except:
pass
def run_post_torrent_remove(self, torrent_id):
log.debug("run_post_torrent_remove")
try:
for function in self.hooks["post_torrent_remove"]:
function(torrent_id)
except:
pass

View File

@ -39,19 +39,14 @@ import deluge.libtorrent as lt
log = logging.getLogger("deluge")
class Torrent:
def __init__(self, filename, handle, queue):
def __init__(self, filename, handle):
# Set the filename
self.filename = filename
# Set the libtorrent handle
self.handle = handle
# Set the queue this torrent belongs too
self.queue = queue
# Set the torrent_id for this torrent
self.torrent_id = str(handle.info_hash())
def __del__(self):
self.queue.remove(self.torrent_id)
def get_state(self):
"""Returns the state of this torrent for saving to the session state"""
return (self.torrent_id, self.filename)
@ -91,8 +86,7 @@ class Torrent:
"num_peers": status.num_peers,
"num_seeds": status.num_seeds,
"total_wanted": status.total_wanted,
"eta": self.get_eta(),
"queue": self.queue[self.torrent_id]
"eta": self.get_eta()
}
# Create the desired status dictionary and return it

View File

@ -40,7 +40,6 @@ import deluge.libtorrent as lt
import deluge.common
from deluge.config import Config
from deluge.core.torrent import Torrent
from deluge.core.torrentqueue import TorrentQueue
from deluge.core.torrentmanagerstate import TorrentManagerState, TorrentState
# Get the logger
@ -53,7 +52,6 @@ class TorrentManager:
self.session = session
# Create the torrents dict { torrent_id: Torrent }
self.torrents = {}
self.queue = TorrentQueue()
def __getitem__(self, torrent_id):
"""Return the Torrent with torrent_id"""
@ -103,11 +101,9 @@ class TorrentManager:
log.warning("Unable to save torrent file: %s", filename)
# Create a Torrent object
torrent = Torrent(filename, handle, self.queue)
torrent = Torrent(filename, handle)
# Add the torrent object to the dictionary
self.torrents[torrent.torrent_id] = torrent
# Add the torrent to the queue
self.queue.append(torrent.torrent_id)
return torrent.torrent_id
def remove(self, torrent_id):
@ -146,8 +142,6 @@ class TorrentManager:
def save_state(self):
"""Save the state of the TorrentManager to the torrents.state file"""
state = TorrentManagerState()
# Grab the queue from TorrentQueue
state.queue = self.queue.queue
# Create the state for each Torrent and append to the list
for (key, torrent) in self.torrents:
t = TorrentState(torrent.get_state())

View File

@ -1,136 +0,0 @@
#
# torrentqueue.py
#
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@gmail.com>
#
# 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 remove(self, torrent_id):
"""Removes torrent_id from the list"""
self.queue.remove(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

View File

@ -31,9 +31,116 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
class QueuePlugin:
def __init__(self):
print "queue plugin init!"
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
from torrentqueue import TorrentQueue
# Get the logger
log = logging.getLogger("deluge")
class QueueCorePlugin(dbus.service.Object):
def __init__(self, plugin, path="/org/deluge_torrent/Plugin/Queue"):
# Get the pluginmanager reference
self.plugin = plugin
# Setup DBUS
bus_name = dbus.service.BusName("org.deluge_torrent.Deluge",
bus=dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, path)
# Instantiate the TorrentQueue object
self.queue = TorrentQueue()
# Register core hooks
self.plugin.register_hook("post_torrent_add", self.post_torrent_add)
self.plugin.register_hook("post_torrent_remove",
self.post_torrent_remove)
log.info("Queue plugin initialized..")
def test(self):
print "queue plugin test!"
## Hooks for core ##
def post_torrent_add(self, torrent_id):
if torrent_id is not None:
self.queue.append(torrent_id)
def post_torrent_remove(self, torrent_id):
if torrent_id is not None:
self.queue.remove(torrent_id)
## Queueing functions ##
@dbus.service.method(dbus_interface="org.deluge_torrent.Deluge.Queue",
in_signature="s", out_signature="")
def queue_top(self, torrent_id):
log.debug("Attempting to queue %s to top", torrent_id)
try:
# If the queue method returns True, then we should emit a signal
if self.queue.top(torrent_id):
self.torrent_queue_changed()
except KeyError:
log.warning("torrent_id: %s does not exist in the queue",
torrent_id)
@dbus.service.method(dbus_interface="org.deluge_torrent.Deluge.Queue",
in_signature="s", out_signature="")
def queue_up(self, torrent_id):
log.debug("Attempting to queue %s to up", torrent_id)
try:
# If the queue method returns True, then we should emit a signal
if self.queue.up(torrent_id):
self.torrent_queue_changed()
except KeyError:
log.warning("torrent_id: %s does not exist in the queue",
torrent_id)
@dbus.service.method(dbus_interface="org.deluge_torrent.Deluge.Queue",
in_signature="s", out_signature="")
def queue_down(self, torrent_id):
log.debug("Attempting to queue %s to down", torrent_id)
try:
# If the queue method returns True, then we should emit a signal
if self.queue.down(torrent_id):
self.torrent_queue_changed()
except KeyError:
log.warning("torrent_id: %s does not exist in the queue",
torrent_id)
@dbus.service.method(dbus_interface="org.deluge_torrent.Deluge.Queue",
in_signature="s", out_signature="")
def queue_bottom(self, torrent_id):
log.debug("Attempting to queue %s to bottom", torrent_id)
try:
# If the queue method returns True, then we should emit a signal
if self.queue.bottom(torrent_id):
self.torrent_queue_changed()
except KeyError:
log.warning("torrent_id: %s does not exist in the queue",
torrent_id)
@dbus.service.method(dbus_interface="org.deluge_torrent.Deluge.Queue",
in_signature="", out_signature="as")
def get_queue(self):
"""Returns the queue list.
"""
log.debug("Getting queue list")
return self.queue.queue
## Signals ##
@dbus.service.signal(dbus_interface="org.deluge_torrent.Deluge.Queue",
signature="")
def torrent_queue_changed(self):
"""Emitted when a torrent queue position is changed"""
log.debug("torrent_queue_changed signal emitted")

View File

@ -43,7 +43,7 @@ setup(
author=__author__,
packages=["queue"],
entry_points="""
[deluge.plugin]
Queue = queue:QueuePlugin
[deluge.plugin.core]
Queue = queue:QueueCorePlugin
"""
)

View File

@ -66,6 +66,15 @@ def get_core():
log.debug("Got core proxy object..")
return core
def get_core_plugin(plugin):
"""Get the core plugin object and return it"""
log.debug("Getting core plugin %s from DBUS..", plugin)
bus = dbus.SessionBus()
proxy = bus.get_object("org.deluge_torrent.Deluge",
"/org/deluge_torrent/Plugin/" + plugin)
core = dbus.Interface(proxy, "org.deluge_torrent.Deluge." + plugin)
return core
def add_torrent_file(torrent_files):
"""Adds torrent files to the core
Expects a list of torrent files
@ -106,7 +115,7 @@ def resume_torrent(torrent_ids):
def queue_top(torrent_ids):
"""Attempts to queue all torrent_ids to the top"""
log.debug("Attempting to queue to top these torrents: %s", torrent_ids)
core = get_core()
core = get_core_plugin("Queue")
for torrent_id in torrent_ids:
core.queue_top(torrent_id)

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,7 @@ log = logging.getLogger("deluge")
# Initializes the columns for the torrent_view
(TORRENT_VIEW_COL_UID,
TORRENT_VIEW_COL_QUEUE,
#TORRENT_VIEW_COL_QUEUE,
TORRENT_VIEW_COL_STATUSICON,
TORRENT_VIEW_COL_NAME,
TORRENT_VIEW_COL_SIZE,
@ -60,7 +60,7 @@ TORRENT_VIEW_COL_PEERS,
TORRENT_VIEW_COL_DOWNLOAD,
TORRENT_VIEW_COL_UPLOAD,
TORRENT_VIEW_COL_ETA,
TORRENT_VIEW_COL_RATIO) = range(15)
TORRENT_VIEW_COL_RATIO) = range(14)
class TorrentView:
def __init__(self, window):
@ -71,9 +71,9 @@ class TorrentView:
self.torrent_view = self.window.main_glade.get_widget("torrent_view")
## TreeModel setup ##
# UID, Q#, Status Icon, Name, Size, Progress, Message, Seeders, Peers,
# UID, Status Icon, Name, Size, Progress, Message, Seeders, Peers,
# DL, UL, ETA, Share
self.torrent_model = gtk.ListStore(str, int, gtk.gdk.Pixbuf, str,
self.torrent_model = gtk.ListStore(str, gtk.gdk.Pixbuf, str,
long, float, str, int, int, int, int, int, int, int, float)
## TreeView setup ##
@ -82,9 +82,9 @@ class TorrentView:
self.torrent_view.set_reorderable(True)
self.torrent_view.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.queue_column = columns.add_text_column(
self.torrent_view, "#",
TORRENT_VIEW_COL_QUEUE)
# self.queue_column = columns.add_text_column(
# self.torrent_view, "#",
# TORRENT_VIEW_COL_QUEUE)
self.name_column = columns.add_texticon_column(
self.torrent_view,
_("Name"),
@ -138,8 +138,8 @@ class TorrentView:
self.peer_column.set_sort_column_id(TORRENT_VIEW_COL_CONNECTED_PEERS)
# Set the default sort column to the queue column
self.torrent_model.set_sort_column_id(TORRENT_VIEW_COL_QUEUE,
gtk.SORT_ASCENDING)
# self.torrent_model.set_sort_column_id(TORRENT_VIEW_COL_QUEUE,
# gtk.SORT_ASCENDING)
### Connect Signals ###
# Connect to the 'button-press-event' to know when to bring up the
@ -156,15 +156,15 @@ class TorrentView:
# This function is used for the foreach method of the treemodel
def update_row(model, path, row, user_data):
torrent_id = self.torrent_model.get_value(row, 0)
status_keys = ["queue", "progress", "state", "num_seeds",
status_keys = ["progress", "state", "num_seeds",
"num_peers", "download_payload_rate", "upload_payload_rate",
"eta"]
status = functions.get_torrent_status(self.core, torrent_id,
status_keys)
# Set values for each column in the row
self.torrent_model.set_value(row, TORRENT_VIEW_COL_QUEUE,
status["queue"]+1)
# self.torrent_model.set_value(row, TORRENT_VIEW_COL_QUEUE,
# status["queue"]+1)
self.torrent_model.set_value(row, TORRENT_VIEW_COL_PROGRESS,
status["progress"]*100)
self.torrent_model.set_value(row, TORRENT_VIEW_COL_STATUS,
@ -190,15 +190,16 @@ class TorrentView:
def add_row(self, torrent_id):
"""Adds a new torrent row to the treeview"""
# Get the status and info dictionaries
status_keys = ["queue", "name", "total_size", "progress", "state",
status_keys = ["name", "total_size", "progress", "state",
"num_seeds", "num_peers", "download_payload_rate",
"upload_payload_rate", "eta"]
status = functions.get_torrent_status(self.core, torrent_id,
status_keys)
# Insert the row with info provided from core
self.torrent_model.insert(status["queue"], [
#self.torrent_model.insert(status["queue"], [
self.torrent_model.append([
torrent_id,
status["queue"]+1,
# status["queue"]+1,
None,
status["name"],
status["total_size"],