Allow changing ownership of torrents. In order to achieve this, added `deluge.core.set_torrents_owner()`, `deluge.core.get_known_accounts()`, `deluge.core.authmanager.get_known_accounts() and `deluge.core.torrent.set_owner()`. So far only the GtkUi has this fully implemented.

This commit is contained in:
Pedro Algarvio 2010-12-22 18:49:27 +00:00
parent 105cb52cb0
commit e63c33c496
6 changed files with 120 additions and 12 deletions

View File

@ -10,9 +10,12 @@
* #1247: Fix deluge-gtk from hanging on shutdown
* #995: Rewrote tracker_icons
* Make the distinction between adding to the session new unmanaged torrents and torrents loaded from state. This will break backwards compatability.
* Pass a copy of an event instead of passing the event arguments to the event handlers. This will break backwards compatability.
* Allow changing ownership of torrents.
==== GtkUI ====
* Fix uncaught exception when closing deluge in classic mode
* Allow changing ownership of torrents
==== WebUI ====
* Migrate to ExtJS 3.1

View File

@ -74,18 +74,16 @@ class AuthManager(component.Component):
:returns: int, the auth level for this user
:rtype: int
:raises AuthenticationRequired: if aditional details are required to authenticate
:raises BadLoginError: if the username does not exist or password does not match
"""
if not username:
raise AuthenticationRequired("Username and Password are required.",
username)
raise AuthenticationRequired(
"Username and Password are required.", username
)
if username and username not in self.__auth:
# Let's try to re-load the file.. Maybe it's been updated
self.__load_auth_file()
if username not in self.__auth:
raise BadLoginError("Username does not exist")
self.__test_existing_account(username)
if self.__auth[username][0] == password:
# Return the users auth level
@ -95,6 +93,21 @@ class AuthManager(component.Component):
else:
raise BadLoginError("Password does not match")
def get_known_accounts(self):
"""
Returns a list of known deluge usernames.
"""
self.__load_auth_file()
return self.__auth.keys()
def __test_existing_account(self, username):
if username not in self.__auth:
# Let's try to re-load the file.. Maybe it's been updated
self.__load_auth_file()
if username not in self.__auth:
raise BadLoginError("Username does not exist")
def __create_localclient_account(self):
"""
Returns the string.

View File

@ -55,6 +55,7 @@ import deluge.common
import deluge.component as component
from deluge.event import *
from deluge.error import *
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.core.torrentmanager import TorrentManager
from deluge.core.pluginmanager import PluginManager
from deluge.core.alertmanager import AlertManager
@ -579,6 +580,25 @@ class Core(component.Component):
"""Sets the path for the torrent to be moved when completed"""
return self.torrentmanager[torrent_id].set_move_completed_path(value)
@export(AUTH_LEVEL_ADMIN)
def set_torrents_owner(self, torrent_ids, username):
"""Set's the torrent owner.
:param torrent_id: the torrent_id of the torrent to remove
:type torrent_id: string
:param username: the new owner username
:type username: string
:raises DelugeError: if the username is not known
"""
if username not in self.authmanager.get_known_accounts():
raise DelugeError("Username \"%s\" is not known." % username)
if isinstance(torrent_ids, basestring):
torrent_ids = [torrent_ids]
for torrent_id in torrent_ids:
self.torrentmanager[torrent_id].set_owner(username)
return None
@export
def get_path_size(self, path):
"""Returns the size of the file or folder 'path' and -1 if the path is
@ -801,3 +821,7 @@ class Core(component.Component):
"""
return lt.version
@export(AUTH_LEVEL_ADMIN)
def get_known_accounts(self):
return self.authmanager.get_known_accounts()

View File

@ -211,12 +211,13 @@ class Torrent(object):
for (key, value) in options.items():
if OPTIONS_FUNCS.has_key(key):
OPTIONS_FUNCS[key](value)
self.options.update(options)
def get_options(self):
return self.options
def set_owner(self, account):
self.owner = account
def set_max_connections(self, max_connections):
self.options["max_connections"] = int(max_connections)

View File

@ -100,6 +100,10 @@ class MenuBar(component.Component):
self.torrentmenu = self.torrentmenu_glade.get_widget("torrent_menu")
self.menu_torrent = self.window.main_glade.get_widget("menu_torrent")
self.menuitem_change_owner = gtk.MenuItem(_("Change Ownership"))
self.torrentmenu_glade.get_widget("options_torrent_menu").append(self.menuitem_change_owner)
# Attach the torrent_menu to the Torrent file menu
self.menu_torrent.set_submenu(self.torrentmenu)
@ -199,10 +203,21 @@ class MenuBar(component.Component):
if not self.config["classic_mode"]:
self.window.main_glade.get_widget("separatormenuitem").show()
self.window.main_glade.get_widget("menuitem_quitdaemon").show()
# Show the Torrent menu because we're connected to a host
self.menu_torrent.show()
# Hide the change owner submenu until we get the accounts back from the
# demon.
self.menuitem_change_owner.set_visible(False)
# Get Known accounts to allow chaning ownership
client.core.get_known_accounts().addCallback(self._on_known_accounts)
def stop(self):
log.debug("MenuBar stopping")
self.menuitem_change_owner.remove_submenu()
for widget in self.change_sensitivity:
self.window.main_glade.get_widget(widget).set_sensitive(False)
@ -212,6 +227,7 @@ class MenuBar(component.Component):
self.window.main_glade.get_widget("separatormenuitem").hide()
self.window.main_glade.get_widget("menuitem_quitdaemon").hide()
def update_menu(self):
selected = component.get('TorrentView').get_selected_torrents()
if not selected or len(selected) == 0:
@ -465,3 +481,54 @@ class MenuBar(component.Component):
for item in items:
getattr(self.window.main_glade.get_widget(item), attr)()
def _on_known_accounts(self, known_accounts):
log.debug("_on_known_accounts: %s", known_accounts)
if len(known_accounts) <= 1:
return
self.menuitem_change_owner.set_visible(True)
self.change_owner_submenu = gtk.Menu()
self.change_owner_submenu_items = {}
maingroup = gtk.RadioMenuItem(None, None)
self.change_owner_submenu_items[None] = gtk.RadioMenuItem(maingroup)
for account in known_accounts:
self.change_owner_submenu_items[account] = item = gtk.RadioMenuItem(maingroup, account)
self.change_owner_submenu.append(item)
item.connect("toggled", self._on_change_owner_toggled, account)
self.change_owner_submenu.show_all()
self.change_owner_submenu_items[None].set_active(True)
self.change_owner_submenu_items[None].hide()
self.menuitem_change_owner.connect("activate", self._on_change_owner_submenu_active)
self.menuitem_change_owner.set_submenu(self.change_owner_submenu)
def _on_known_accounts_fail(self, reason):
self.menuitem_change_owner.set_visible(False)
def _on_change_owner_submenu_active(self, widget):
log.debug("_on_change_owner_submenu_active")
selected = component.get("TorrentView").get_selected_torrents()
if len(selected) > 1:
self.change_owner_submenu_items[None].set_active(True)
return
torrent_owner = component.get("TorrentView").get_torrent_status(selected[0])["owner"]
for account, item in self.change_owner_submenu_items.iteritems():
item.set_active(account == torrent_owner)
def _on_change_owner_toggled(self, widget, account):
log.debug("_on_change_owner_toggled")
update_torrents = []
selected = component.get("TorrentView").get_selected_torrents()
for torrent_id in selected:
torrent_status = component.get("TorrentView").get_torrent_status(torrent_id)
if torrent_status["owner"] != account:
update_torrents.append(torrent_id)
if update_torrents:
log.debug("Setting torrent owner \"%s\" on %s", account, update_torrents)
client.core.set_torrents_owner(update_torrents, account)

View File

@ -197,7 +197,8 @@ class TorrentView(listview.ListView, component.Component):
# Register the columns menu with the listview so it gets updated
# accordingly.
self.register_checklist_menu(
self.window.main_glade.get_widget("menu_columns"))
self.window.main_glade.get_widget("menu_columns")
)
# Add the columns to the listview
self.add_text_column("torrent_id", hidden=True)
@ -253,15 +254,14 @@ class TorrentView(listview.ListView, component.Component):
### Connect Signals ###
# Connect to the 'button-press-event' to know when to bring up the
# torrent menu popup.
self.treeview.connect("button-press-event",
self.on_button_press_event)
self.treeview.connect("button-press-event", self.on_button_press_event)
# Connect to the 'key-press-event' to know when the bring up the
# torrent menu popup via keypress.
self.treeview.connect("key-release-event", self.on_key_press_event)
# Connect to the 'changed' event of TreeViewSelection to get selection
# changes.
self.treeview.get_selection().connect("changed",
self.on_selection_changed)
self.on_selection_changed)
self.treeview.connect("drag-drop", self.on_drag_drop)
self.treeview.connect("key-press-event", self.on_key_press_event)