Fix some clean config dir issues.

Moved some auth stuff to `deluge.common` because they're also used on the GTK UI.
Now, if a user starts deluge in classic mode and tries to change it to client/daemon mode, he see's a dialog stating that the current session will be stopped. If he answers no, nothing is done, the classic mode pref is set back as it was. If he answers yes, all components are stopped and client is disconnected. At this stage the user can open the connection manager to start the daemon and connect.
If the user starts in client/daemon mode and switches to classic mode he see's a dialog stating that deluge must be restarted.
The GTK UI connection manager now loads it's default config with the localclient username and password. If not present in the auth file, the auth file will be recreated.
This commit is contained in:
Pedro Algarvio 2011-04-27 22:06:13 +01:00
commit 9fa8748432
7 changed files with 132 additions and 71 deletions

View file

@ -631,3 +631,43 @@ class VersionSplit(object):
v1 = [self.version, self.suffix or 'z', self.dev] v1 = [self.version, self.suffix or 'z', self.dev]
v2 = [ver.version, ver.suffix or 'z', ver.dev] v2 = [ver.version, ver.suffix or 'z', ver.dev]
return cmp(v1, v2) return cmp(v1, v2)
# Common AUTH stuff
AUTH_LEVEL_NONE = 0
AUTH_LEVEL_READONLY = 1
AUTH_LEVEL_NORMAL = 5
AUTH_LEVEL_ADMIN = 10
AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL
def create_auth_file():
import stat, configmanager
auth_file = configmanager.get_config_dir("auth")
# Check for auth file and create if necessary
if not os.path.exists(auth_file):
fd = open(auth_file, "w")
fd.flush()
os.fsync(fd.fileno())
fd.close()
# Change the permissions on the file so only this user can read/write it
os.chmod(auth_file, stat.S_IREAD | stat.S_IWRITE)
def create_localclient_account():
import configmanager, random
auth_file = configmanager.get_config_dir("auth")
if not os.path.exists(auth_file):
create_auth_file()
try:
from hashlib import sha1 as sha_hash
except ImportError:
from sha import new as sha_hash
fd = open(auth_file, "w")
fd.write(":".join([
"localclient",
sha_hash(str(random.random())).hexdigest(),
str(AUTH_LEVEL_ADMIN)
]) + '\n')
fd.flush()
os.fsync(fd.fileno())
fd.close()

View file

@ -42,17 +42,14 @@ import logging
import deluge.component as component import deluge.component as component
import deluge.configmanager as configmanager import deluge.configmanager as configmanager
from deluge.common import (AUTH_LEVEL_ADMIN, AUTH_LEVEL_NONE, AUTH_LEVEL_NORMAL,
AUTH_LEVEL_READONLY, AUTH_LEVEL_DEFAULT,
create_auth_file, create_localclient_account)
from deluge.error import AuthManagerError, AuthenticationRequired, BadLoginError from deluge.error import AuthManagerError, AuthenticationRequired, BadLoginError
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
AUTH_LEVEL_NONE = 0
AUTH_LEVEL_READONLY = 1
AUTH_LEVEL_NORMAL = 5
AUTH_LEVEL_ADMIN = 10
AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL
AUTH_LEVELS_MAPPING = { AUTH_LEVELS_MAPPING = {
'NONE': AUTH_LEVEL_NONE, 'NONE': AUTH_LEVEL_NONE,
'READONLY': AUTH_LEVEL_READONLY, 'READONLY': AUTH_LEVEL_READONLY,
@ -218,28 +215,13 @@ class AuthManager(component.Component):
self.__load_auth_file() self.__load_auth_file()
def __create_localclient_account(self):
"""
Returns the string.
"""
# We create a 'localclient' account with a random password
try:
from hashlib import sha1 as sha_hash
except ImportError:
from sha import new as sha_hash
self.__auth["localclient"] = Account(
"localclient",
sha_hash(str(random.random())).hexdigest(),
AUTH_LEVEL_ADMIN
)
def __load_auth_file(self): def __load_auth_file(self):
save_and_reload = False save_and_reload = False
auth_file = configmanager.get_config_dir("auth") auth_file = configmanager.get_config_dir("auth")
# Check for auth file and create if necessary # Check for auth file and create if necessary
if not os.path.exists(auth_file): if not os.path.exists(auth_file):
self.__create_auth_file() create_auth_file()
self.__create_localclient_account() create_localclient_account()
self.write_auth_file() self.write_auth_file()
auth_file_modification_time = os.stat(auth_file).st_mtime auth_file_modification_time = os.stat(auth_file).st_mtime
@ -295,7 +277,7 @@ class AuthManager(component.Component):
self.__auth[username] = Account(username, password, authlevel) self.__auth[username] = Account(username, password, authlevel)
if "localclient" not in self.__auth: if "localclient" not in self.__auth:
self.__create_localclient_account() create_localclient_account()
self.write_auth_file() self.write_auth_file()
if save_and_reload: if save_and_reload:
@ -303,14 +285,3 @@ class AuthManager(component.Component):
self.write_auth_file() self.write_auth_file()
self.__auth_modification_time = auth_file_modification_time self.__auth_modification_time = auth_file_modification_time
def __create_auth_file(self):
auth_file = configmanager.get_config_dir("auth")
# Check for auth file and create if necessary
if not os.path.exists(auth_file):
fd = open(auth_file, "w")
fd.flush()
os.fsync(fd.fileno())
fd.close()
# Change the permissions on the file so only this user can read/write it
os.chmod(auth_file, stat.S_IREAD | stat.S_IWRITE)

View file

@ -54,7 +54,9 @@ class Daemon(object):
if os.path.isfile(deluge.configmanager.get_config_dir("deluged.pid")): if os.path.isfile(deluge.configmanager.get_config_dir("deluged.pid")):
# Get the PID and the port of the supposedly running daemon # Get the PID and the port of the supposedly running daemon
try: try:
(pid, port) = open(deluge.configmanager.get_config_dir("deluged.pid")).read().strip().split(";") (pid, port) = open(
deluge.configmanager.get_config_dir("deluged.pid")
).read().strip().split(";")
pid = int(pid) pid = int(pid)
port = int(port) port = int(port)
except ValueError: except ValueError:
@ -93,7 +95,10 @@ class Daemon(object):
else: else:
# This is a deluged! # This is a deluged!
s.close() s.close()
raise deluge.error.DaemonRunningError("There is a deluge daemon running with this config directory!") raise deluge.error.DaemonRunningError(
"There is a deluge daemon running with this config "
"directory!"
)
# Initialize gettext # Initialize gettext
try: try:

View file

@ -515,6 +515,7 @@ class DaemonClassicProxy(DaemonProxy):
self.__daemon.core.eventmanager.register_event_handler(event, handler) self.__daemon.core.eventmanager.register_event_handler(event, handler)
def disconnect(self): def disconnect(self):
self.connected = False
self.__daemon = None self.__daemon = None
def call(self, method, *args, **kwargs): def call(self, method, *args, **kwargs):

View file

@ -407,7 +407,10 @@ def get_localhost_auth():
:rtype: tuple :rtype: tuple
""" """
auth_file = deluge.configmanager.get_config_dir("auth") auth_file = deluge.configmanager.get_config_dir("auth")
if os.path.exists(auth_file): if not os.path.exists(auth_file):
from deluge.common import create_localclient_account
create_localclient_account()
for line in open(auth_file): for line in open(auth_file):
if line.startswith("#"): if line.startswith("#"):
# This is a comment line # This is a comment line
@ -429,4 +432,3 @@ def get_localhost_auth():
if username == "localclient": if username == "localclient":
return (username, password) return (username, password)
return ("", "")

View file

@ -33,6 +33,7 @@
# #
# #
import os
import gtk import gtk
import pkg_resources import pkg_resources
import time import time
@ -56,11 +57,6 @@ log = logging.getLogger(__name__)
DEFAULT_HOST = "127.0.0.1" DEFAULT_HOST = "127.0.0.1"
DEFAULT_PORT = 58846 DEFAULT_PORT = 58846
DEFAULT_CONFIG = {
"hosts": [(hashlib.sha1(str(time.time())).hexdigest(), DEFAULT_HOST,
DEFAULT_PORT, "localclient", "")]
}
HOSTLIST_COL_ID = 0 HOSTLIST_COL_ID = 0
HOSTLIST_COL_HOST = 1 HOSTLIST_COL_HOST = 1
HOSTLIST_COL_PORT = 2 HOSTLIST_COL_PORT = 2
@ -99,15 +95,11 @@ class ConnectionManager(component.Component):
def __init__(self): def __init__(self):
component.Component.__init__(self, "ConnectionManager") component.Component.__init__(self, "ConnectionManager")
self.gtkui_config = ConfigManager("gtkui.conf") self.gtkui_config = ConfigManager("gtkui.conf")
self.config = ConfigManager("hostlist.conf.1.2", DEFAULT_CONFIG)
self.config.run_converter((0, 1), 2, self.__migrate_config_1_to_2)
self.running = False self.running = False
# Component overrides # Component overrides
def start(self): def start(self):
pass self.config = self.__load_config()
def stop(self): def stop(self):
# Close this dialog when we are shutting down # Close this dialog when we are shutting down
@ -117,6 +109,26 @@ class ConnectionManager(component.Component):
def shutdown(self): def shutdown(self):
pass pass
def __load_config(self):
auth_file = deluge.configmanager.get_config_dir("auth")
if not os.path.exists(auth_file):
from deluge.common import create_localclient_account
create_localclient_account()
localclient_username, localclient_password = get_localhost_auth()
DEFAULT_CONFIG = {
"hosts": [(
hashlib.sha1(str(time.time())).hexdigest(),
DEFAULT_HOST,
DEFAULT_PORT,
localclient_username,
localclient_password
)]
}
config = ConfigManager("hostlist.conf.1.2", DEFAULT_CONFIG)
config.run_converter((0, 1), 2, self.__migrate_config_1_to_2)
return config
# Public methods # Public methods
def show(self): def show(self):
""" """

View file

@ -546,6 +546,8 @@ class Preferences(component.Component):
except ImportError: except ImportError:
from sha import new as sha_hash from sha import new as sha_hash
classic_mode_was_set = self.gtkui_config["classic_mode"]
# Get the values from the dialog # Get the values from the dialog
new_core_config = {} new_core_config = {}
new_gtkui_config = {} new_gtkui_config = {}
@ -666,8 +668,10 @@ class Preferences(component.Component):
self.glade.get_widget("txt_tray_password").get_text()).hexdigest() self.glade.get_widget("txt_tray_password").get_text()).hexdigest()
if passhex != "c07eb5a8c0dc7bb81c217b67f11c3b7a5e95ffd7": if passhex != "c07eb5a8c0dc7bb81c217b67f11c3b7a5e95ffd7":
new_gtkui_config["tray_password"] = passhex new_gtkui_config["tray_password"] = passhex
new_gtkui_config["classic_mode"] = \
self.glade.get_widget("chk_classic_mode").get_active() new_gtkui_in_classic_mode = self.glade.get_widget("chk_classic_mode").get_active()
new_gtkui_config["classic_mode"] = new_gtkui_in_classic_mode
new_gtkui_config["show_rate_in_title"] = \ new_gtkui_config["show_rate_in_title"] = \
self.glade.get_widget("chk_show_rate_in_title").get_active() self.glade.get_widget("chk_show_rate_in_title").get_active()
@ -763,6 +767,32 @@ class Preferences(component.Component):
# Re-show the dialog to make sure everything has been updated # Re-show the dialog to make sure everything has been updated
self.show() self.show()
if classic_mode_was_set==True and new_gtkui_in_classic_mode==False:
def on_response(response):
if response == gtk.RESPONSE_NO:
# Set each changed config value in the core
self.gtkui_config["classic_mode"] = True
client.core.set_config({"classic_mode": True})
client.force_call(True)
# Update the configuration
self.core_config.update({"classic_mode": True})
self.glade.get_widget("chk_classic_mode").set_active(True)
else:
client.disconnect()
if client.is_classicmode():
component.stop()
dialog = dialogs.YesNoDialog(
_("Attention"),
_("Your current session will be stopped. Continue?")
)
dialog.run().addCallback(on_response)
elif classic_mode_was_set==False and new_gtkui_in_classic_mode==True:
dialog = dialogs.InformationDialog(
_("Attention"),
_("You must now restart the deluge UI")
)
dialog.run()
def hide(self): def hide(self):
self.glade.get_widget("port_img").hide() self.glade.get_widget("port_img").hide()
self.pref_dialog.hide() self.pref_dialog.hide()