deluge/deluge/ui/console/modes/connectionmanager.py
bendikro 5e493f2d3f [UI] Use a shared DEFAULT_HOSTS dict in ui/common
Instead of defining a DEFAULT_HOSTS dict for each UI
use a shared dict.
2016-05-24 21:10:52 +02:00

197 lines
6.6 KiB
Python

# -*- coding: utf-8 -*-
#
# Copyright (C) 2011 Nick Lanham <nick@afternight.org>
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
""" A mode that show's a popup to select which host to connect to """
import hashlib
import logging
import time
from collections import deque
import deluge.component as component
from deluge.configmanager import ConfigManager
from deluge.ui import common as uicommon
from deluge.ui.client import Client, client
from deluge.ui.console.modes.alltorrents import AllTorrents
from deluge.ui.console.modes.basemode import BaseMode
from deluge.ui.console.modes.input_popup import InputPopup
from deluge.ui.console.modes.popup import MessagePopup, SelectablePopup
try:
import curses
except ImportError:
pass
log = logging.getLogger(__name__)
class ConnectionManager(BaseMode):
def __init__(self, stdscr, encoding=None):
self.popup = None
self.statuses = {}
self.messages = deque()
self.config = ConfigManager("hostlist.conf.1.2", uicommon.DEFAULT_HOSTS)
BaseMode.__init__(self, stdscr, encoding)
self.__update_statuses()
self.__update_popup()
def __update_popup(self):
self.popup = SelectablePopup(self, "Select Host", self.__host_selected)
self.popup.add_line("{!white,black,bold!}'Q'=quit, 'r'=refresh, 'a'=add new host, 'D'=delete host",
selectable=False)
for host in self.config["hosts"]:
if host[0] in self.statuses:
self.popup.add_line("%s:%d [Online] (%s)" % (host[1], host[2], self.statuses[host[0]]),
data=host[0], foreground="green")
else:
self.popup.add_line("%s:%d [Offline]" % (host[1], host[2]), data=host[0], foreground="red")
self.inlist = True
self.refresh()
def __update_statuses(self):
"""Updates the host status"""
def on_connect(result, c, host_id):
def on_info(info, c):
self.statuses[host_id] = info
self.__update_popup()
c.disconnect()
def on_info_fail(reason, c):
if host_id in self.statuses:
del self.statuses[host_id]
c.disconnect()
d = c.daemon.info()
d.addCallback(on_info, c)
d.addErrback(on_info_fail, c)
def on_connect_failed(reason, host_id):
if host_id in self.statuses:
del self.statuses[host_id]
for host in self.config["hosts"]:
c = Client()
hadr = host[1]
port = host[2]
user = host[3]
password = host[4]
log.debug("connect: hadr=%s, port=%s, user=%s, password=%s", hadr, port, user, password)
d = c.connect(hadr, port, user, password)
d.addCallback(on_connect, c, host[0])
d.addErrback(on_connect_failed, host[0])
def __on_connected(self, result):
component.start()
self.stdscr.erase()
at = AllTorrents(self.stdscr, self.encoding)
component.get("ConsoleUI").set_mode(at)
at.resume()
def __host_selected(self, idx, data):
for host in self.config["hosts"]:
if host[0] == data and host[0] in self.statuses:
client.connect(host[1], host[2], host[3], host[4]).addCallback(self.__on_connected)
return False
def __do_add(self, result):
hostname = result["hostname"]
try:
port = int(result["port"])
except ValueError:
self.report_message("Can't add host", "Invalid port. Must be an integer")
return
username = result["username"]
password = result["password"]
for host in self.config["hosts"]:
if (host[1], host[2], host[3]) == (hostname, port, username):
self.report_message("Can't add host", "Host already in list")
return
newid = hashlib.sha1(str(time.time())).hexdigest()
self.config["hosts"].append((newid, hostname, port, username, password))
self.config.save()
self.__update_popup()
def __add_popup(self):
self.inlist = False
self.popup = InputPopup(self, "Add Host (up & down arrows to navigate, esc to cancel)", close_cb=self.__do_add)
self.popup.add_text_input("Hostname:", "hostname")
self.popup.add_text_input("Port:", "port")
self.popup.add_text_input("Username:", "username")
self.popup.add_text_input("Password:", "password")
self.refresh()
def __delete_current_host(self):
idx, data = self.popup.current_selection()
log.debug("deleting host: %s", data)
for host in self.config["hosts"]:
if host[0] == data:
self.config["hosts"].remove(host)
break
self.config.save()
def report_message(self, title, message):
self.messages.append((title, message))
def refresh(self):
self.stdscr.erase()
self.draw_statusbars()
self.stdscr.noutrefresh()
if self.popup is None and self.messages:
title, msg = self.messages.popleft()
self.popup = MessagePopup(self, title, msg)
if not self.popup:
self.__update_popup()
self.popup.refresh()
curses.doupdate()
def on_resize(self, *args):
BaseMode.on_resize_norefresh(self, *args)
if self.popup:
self.popup.handle_resize()
self.stdscr.erase()
self.refresh()
def read_input(self):
# Read the character
c = self.stdscr.getch()
if c > 31 and c < 256:
if chr(c) == "q" and self.inlist:
return
if chr(c) == "Q":
from twisted.internet import reactor
if client.connected():
def on_disconnect(result):
reactor.stop()
client.disconnect().addCallback(on_disconnect)
else:
reactor.stop()
return
if chr(c) == "D" and self.inlist:
self.__delete_current_host()
self.__update_popup()
return
if chr(c) == "r" and self.inlist:
self.__update_statuses()
if chr(c) == "a" and self.inlist:
self.__add_popup()
return
if self.popup:
if self.popup.handle_read(c):
self.popup = None
self.refresh()
return