diff --git a/deluge/ui/console/colors.py b/deluge/ui/console/colors.py index ab2f24e5f..2035c695c 100644 --- a/deluge/ui/console/colors.py +++ b/deluge/ui/console/colors.py @@ -52,12 +52,12 @@ schemes = { # Colors for various torrent states state_color = { - "Seeding": "{{blue,black,bold}}", - "Downloading": "{{green,black,bold}}", - "Paused": "{{white,black}}", - "Checking": "{{green,black}}", - "Queued": "{{yellow,black}}", - "Error": "{{red,black,bold}}" + "Seeding": "{!blue,black,bold!}", + "Downloading": "{!green,black,bold!}", + "Paused": "{!white,black!}", + "Checking": "{!green,black!}", + "Queued": "{!yellow,black!}", + "Error": "{!red,black,bold!}" } def init_colors(): @@ -89,12 +89,12 @@ def get_line_length(line): Returns the string length without the color formatting. """ - if line.count("{{") != line.count ("}}"): - raise BadColorString("Number of {{ does not equal number of }}") + if line.count("{!") != line.count("!}"): + raise BadColorString("Number of {! is not equal to number of !}") # Remove all the color tags - while line.find("{{") != -1: - line = line[:line.find("{{")] + line[line.find("}}") + 2:] + while line.find("{!") != -1: + line = line[:line.find("{!")] + line[line.find("!}") + 2:] # Replace tabs with the appropriate amount of spaces line = replace_tabs(line) @@ -107,27 +107,26 @@ def parse_color_string(s): :param s:, string to parse """ - if s.count("{{") != s.count ("}}"): - raise BadColorString("Number of {{ does not equal number of }}") - + if s.count("{!") != s.count("!}"): + raise BadColorString("Number of {! is not equal to number of !}") ret = [] # Keep track of where the strings col_index = 0 - while s.find("{{") != -1: - begin = s.find("{{") + while s.find("{!") != -1: + begin = s.find("{!") if begin > 0: ret.append((curses.color_pair(color_pairs[(schemes["input"][0], schemes["input"][1])]), s[:begin])) - end = s.find("}}") + end = s.find("!}") if end == -1: - raise BadColorString("Missing closing '}}'") + raise BadColorString("Missing closing '!}'") # Get a list of attributes in the bracketed section attrs = s[begin+2:end].split(",") if len(attrs) == 1 and not attrs: - raise BadColorString("No description in {{ }}") + raise BadColorString("No description in {! !}") def apply_attrs(cp, a): # This function applies any additional attributes as necessary @@ -151,13 +150,17 @@ def parse_color_string(s): # Default to 'black' if no bg is chosen bg = "black" - color_pair = curses.color_pair(color_pairs[(fg, bg)]) + try: + color_pair = curses.color_pair(color_pairs[(fg, bg)]) + except KeyError: + raise BadColorString("Bad color value in tag: %s,%s" % (fg, bg)) + # Check for additional attributes and OR them to the color_pair color_pair = apply_attrs(color_pair, attrs) - # We need to find the text now, so lets try to find another {{ and if + # We need to find the text now, so lets try to find another {! and if # there isn't one, then it's the rest of the string - next_begin = s.find("{{", end) + next_begin = s.find("{!", end) if next_begin == -1: ret.append((color_pair, replace_tabs(s[end+2:]))) diff --git a/deluge/ui/console/commands/add.py b/deluge/ui/console/commands/add.py index f1496f049..bc63fe030 100644 --- a/deluge/ui/console/commands/add.py +++ b/deluge/ui/console/commands/add.py @@ -48,13 +48,13 @@ class Command(BaseCommand): t_options["download_location"] = options["path"] for arg in args: - self.console.write("{{info}}Attempting to add torrent: %s" % arg) + self.console.write("{!info!}Attempting to add torrent: %s" % arg) filename = os.path.split(arg)[-1] filedump = base64.encodestring(open(arg).read()) def on_success(result): - self.console.write("{{success}}Torrent added!") + self.console.write("{!success!}Torrent added!") def on_fail(result): - self.console.write("{{error}}Torrent was not added! %s" % result) + self.console.write("{!error!}Torrent was not added! %s" % result) client.core.add_torrent_file(filename, filedump, t_options).addCallback(on_success).addErrback(on_fail) diff --git a/deluge/ui/console/commands/config.py b/deluge/ui/console/commands/config.py index 41b52f4a5..d5654f3d1 100644 --- a/deluge/ui/console/commands/config.py +++ b/deluge/ui/console/commands/config.py @@ -23,9 +23,12 @@ # Boston, MA 02110-1301, USA. # -from deluge.ui.console.main import BaseCommand, match_torrents +from deluge.ui.console.main import BaseCommand import deluge.ui.console.colors as colors from deluge.ui.client import client +import deluge.component as component +from deluge.log import LOG as log + from optparse import make_option import re @@ -78,34 +81,46 @@ class Command(BaseCommand): " config --set key value" def handle(self, *args, **options): + self.console = component.get("ConsoleUI") if options['set']: self._set_config(*args, **options) else: self._get_config(*args, **options) def _get_config(self, *args, **options): - def _on_get_config(config): - keys = config.keys() - keys.sort() - for key in keys: - if args and key not in args: - continue - color = 'white' - value = config[key] - if isinstance(value, bool): - color = 'yellow' - elif isinstance(value, int) or isinstance(value, float): - color = 'green' - elif isinstance(value, str): - color = 'cyan' - elif isinstance(value, list): - color = 'magenta' + config = component.get("CoreConfig") - print templates.config_display(key, style[color](str(value))) - client.get_config(_on_get_config) + keys = config.keys() + keys.sort() + s = "" + for key in keys: + if args and key not in args: + continue + color = 'white' + value = config[key] + if isinstance(value, bool): + color = 'yellow' + elif isinstance(value, int) or isinstance(value, float): + color = 'green' + elif isinstance(value, str): + color = 'cyan' + elif isinstance(value, list): + color = 'magenta' + elif isinstance(value, dict): + import pprint + value = pprint.pformat(value, 2, 80) + new_value = [] + for line in value.splitlines(): + new_value.append("{!%s,black,bold!}%s" % (color, line)) + value = "\n".join(new_value) + + s += " %s: {!%s,black,bold!}%s\n" % (key, color, value) + + self.console.write(s) def _set_config(self, *args, **options): - def _got_config_value(config_val): + pass +""" def _got_config_value(config_val): global c_val c_val = config_val key = args[0] @@ -135,4 +150,4 @@ class Command(BaseCommand): return [ k for k in keys if k.startswith(text) ] def split(self, text): - return str.split(text) + return str.split(text)""" diff --git a/deluge/ui/console/commands/connect.py b/deluge/ui/console/commands/connect.py index f5bc684c4..0ebbcea3b 100644 --- a/deluge/ui/console/commands/connect.py +++ b/deluge/ui/console/commands/connect.py @@ -34,10 +34,10 @@ class Command(BaseCommand): port = int(port) d = client.connect(host, port, username, password) def on_connect(result): - self.console.write("{{success}}Connected to %s:%s!" % (host, port)) + self.console.write("{!success!}Connected to %s:%s!" % (host, port)) def on_connect_fail(result): - self.console.write("{{error}}Failed to connect to %s:%s!" % (host, port)) + self.console.write("{!error!}Failed to connect to %s:%s!" % (host, port)) d.addCallback(on_connect) d.addErrback(on_connect_fail) diff --git a/deluge/ui/console/commands/halt.py b/deluge/ui/console/commands/halt.py index ed4242685..250d752ca 100644 --- a/deluge/ui/console/commands/halt.py +++ b/deluge/ui/console/commands/halt.py @@ -33,9 +33,9 @@ class Command(BaseCommand): self.console = component.get("ConsoleUI") def on_shutdown(result): - self.write("{{success}}Daemon was shutdown") + self.write("{!success!}Daemon was shutdown") def on_shutdown_fail(reason): - self.write("{{error}}Unable to shutdown daemon: %s" % reason) + self.write("{!error!}Unable to shutdown daemon: %s" % reason) client.daemon.shutdown().addCallback(on_shutdown).addErrback(on_shutdown_fail) diff --git a/deluge/ui/console/commands/help.py b/deluge/ui/console/commands/help.py index bc1c43383..134e08451 100644 --- a/deluge/ui/console/commands/help.py +++ b/deluge/ui/console/commands/help.py @@ -41,7 +41,7 @@ class Command(BaseCommand): try: cmd = self._commands[args[0]] except KeyError: - self.console.write("{{error}}Unknown command %r" % args[0]) + self.console.write("{!error!}Unknown command %r" % args[0]) return try: parser = cmd.create_parser() @@ -51,6 +51,6 @@ class Command(BaseCommand): else: max_length = max( len(k) for k in self._commands) for cmd in sorted(self._commands): - self.console.write("{{info}}" + cmd + "{{input}} - " + self._commands[cmd].__doc__ or '') + self.console.write("{!info!}" + cmd + "{!input!} - " + self._commands[cmd].__doc__ or '') self.console.write(" ") self.console.write('For help on a specific command, use " --help"') diff --git a/deluge/ui/console/commands/info.py b/deluge/ui/console/commands/info.py index e541f0525..38f9cdee7 100644 --- a/deluge/ui/console/commands/info.py +++ b/deluge/ui/console/commands/info.py @@ -106,7 +106,7 @@ class Command(BaseCommand): self.show_info(key, value, options["verbose"]) def on_torrents_status_fail(reason): - self.console.write("{{error}}Error getting torrent info: %s" % reason) + self.console.write("{!error!}Error getting torrent info: %s" % reason) d = client.core.get_torrents_status({"id": torrent_ids}, status_keys) d.addCallback(on_torrents_status) @@ -123,61 +123,61 @@ class Command(BaseCommand): the torrent """ self.console.write(" ") - self.console.write("{{info}}Name: {{input}}%s" % (status["name"])) - self.console.write("{{info}}ID: {{input}}%s" % (torrent_id)) - s = "{{info}}State: %s%s" % (colors.state_color[status["state"]], status["state"]) + self.console.write("{!info!}Name: {!input!}%s" % (status["name"])) + self.console.write("{!info!}ID: {!input!}%s" % (torrent_id)) + s = "{!info!}State: %s%s" % (colors.state_color[status["state"]], status["state"]) # Only show speed if active if status["state"] in ("Seeding", "Downloading"): if status["state"] != "Seeding": - s += " {{info}}Down Speed: {{input}}%s" % common.fspeed(status["download_payload_rate"]) - s += " {{info}}Up Speed: {{input}}%s" % common.fspeed(status["upload_payload_rate"]) + s += " {!info!}Down Speed: {!input!}%s" % common.fspeed(status["download_payload_rate"]) + s += " {!info!}Up Speed: {!input!}%s" % common.fspeed(status["upload_payload_rate"]) if common.ftime(status["eta"]): - s += " {{info}}ETA: {{input}}%s" % common.ftime(status["eta"]) + s += " {!info!}ETA: {!input!}%s" % common.ftime(status["eta"]) self.console.write(s) if status["state"] in ("Seeding", "Downloading", "Queued"): - s = "{{info}}Seeds: {{input}}%s (%s)" % (status["num_seeds"], status["total_seeds"]) - s += " {{info}}Peers: {{input}}%s (%s)" % (status["num_peers"], status["total_peers"]) - s += " {{info}}Availibility: {{input}}%.2f" % status["distributed_copies"] + s = "{!info!}Seeds: {!input!}%s (%s)" % (status["num_seeds"], status["total_seeds"]) + s += " {!info!}Peers: {!input!}%s (%s)" % (status["num_peers"], status["total_peers"]) + s += " {!info!}Availibility: {!input!}%.2f" % status["distributed_copies"] self.console.write(s) - s = "{{info}}Size: {{input}}%s/%s" % (common.fsize(status["total_done"]), common.fsize(status["total_size"])) - s += " {{info}}Ratio: {{input}}%.3f" % status["ratio"] + s = "{!info!}Size: {!input!}%s/%s" % (common.fsize(status["total_done"]), common.fsize(status["total_size"])) + s += " {!info!}Ratio: {!input!}%.3f" % status["ratio"] self.console.write(s) if not status["is_finished"]: pbar = format_progressbar(status["progress"], self.console.screen.cols - (13 + len("%.2f%%" % status["progress"]))) - s = "{{info}}Progress: {{input}}%.2f%% %s" % (status["progress"], pbar) + s = "{!info!}Progress: {!input!}%.2f%% %s" % (status["progress"], pbar) self.console.write(s) if verbose: - self.console.write(" {{info}}::Files") + self.console.write(" {!info!}::Files") for i, f in enumerate(status["files"]): - s = " {{input}}%s (%s)" % (f["path"], common.fsize(f["size"])) - s += " {{info}}Progress: {{input}}%.2f%%" % (status["file_progress"][i] * 100) - s += " {{info}}Priority:" + s = " {!input!}%s (%s)" % (f["path"], common.fsize(f["size"])) + s += " {!info!}Progress: {!input!}%.2f%%" % (status["file_progress"][i] * 100) + s += " {!info!}Priority:" fp = common.FILE_PRIORITY[status["file_priorities"][i]].replace("Priority", "") if fp == "Do Not Download": - s += "{{error}}" + s += "{!error!}" else: - s += "{{success}}" + s += "{!success!}" s += " %s" % (fp) self.console.write(s) - self.console.write(" {{info}}::Peers") + self.console.write(" {!info!}::Peers") if len(status["peers"]) == 0: self.console.write(" None") else: s = "" for peer in status["peers"]: if peer["seed"]: - s += "%sSeed\t{{input}}" % colors.state_color["Seeding"] + s += "%sSeed\t{!input!}" % colors.state_color["Seeding"] else: - s += "%sPeer\t{{input}}" % colors.state_color["Downloading"] + s += "%sPeer\t{!input!}" % colors.state_color["Downloading"] s += peer["country"] + "\t" s += peer["ip"] diff --git a/deluge/ui/console/eventlog.py b/deluge/ui/console/eventlog.py index 8f6dac0e2..d9aa16920 100644 --- a/deluge/ui/console/eventlog.py +++ b/deluge/ui/console/eventlog.py @@ -49,11 +49,11 @@ class EventLog(component.Component): def on_torrent_added_event(self, torrent_id): def on_torrent_status(status): - self.console.write("{{event}}* TorrentAdded: {{info}}%s (%s)" % (status["name"], torrent_id)) + self.console.write("{!event!}* TorrentAdded: {!info!}%s (%s)" % (status["name"], torrent_id)) client.core.get_torrent_status(torrent_id, ["name"]).addCallback(on_torrent_status) def on_torrent_removed_event(self, torrent_id): - self.console.write("{{event}}* TorrentRemovedEvent: {{info}}%s (%s)" % + self.console.write("{!event!}* TorrentRemovedEvent: {!info!}%s (%s)" % (self.console.get_torrent_name(torrent_id), torrent_id)) def on_torrent_state_changed_event(self, torrent_id, state): @@ -62,27 +62,27 @@ class EventLog(component.Component): if state in colors.state_color: state = colors.state_color[state] + state - self.console.write("{{event}}* TorrentStateChanged: %s {{info}}%s (%s)" % + self.console.write("{!event!}* TorrentStateChanged: %s {!info!}%s (%s)" % (state, self.console.get_torrent_name(torrent_id), torrent_id)) def on_torrent_paused_event(self, torrent_id): - self.console.write("{{event}}* TorrentPaused: {{info}}%s (%s)" % + self.console.write("{!event!}* TorrentPaused: {!info!}%s (%s)" % (self.console.get_torrent_name(torrent_id), torrent_id)) def on_torrent_finished_event(self, torrent_id): - self.console.write("{{event}}* TorrentFinished: {{info}}%s (%s)" % + self.console.write("{!event!}* TorrentFinished: {!info!}%s (%s)" % (self.console.get_torrent_name(torrent_id), torrent_id)) def on_new_version_available_event(self, version): - self.console.write("{{event}}* NewVersionAvailable: {{info}}%s" % + self.console.write("{!event!}* NewVersionAvailable: {!info!}%s" % (version)) def on_session_paused_event(self): - self.console.write("{{event}}* SessionPaused") + self.console.write("{!event!}* SessionPaused") def on_session_resumed_event(self): - self.console.write("{{event}}* SessionResumed") + self.console.write("{!event!}* SessionResumed") def on_config_value_changed_event(self, key, value): - self.console.write("{{event}}* ConfigValueChanged: %s: %s" % + self.console.write("{!event!}* ConfigValueChanged: %s: %s" % (key, value)) diff --git a/deluge/ui/console/main.py b/deluge/ui/console/main.py index 8ec0edc64..0cc7b2a8a 100644 --- a/deluge/ui/console/main.py +++ b/deluge/ui/console/main.py @@ -40,10 +40,6 @@ import deluge.ui.console.screen as screen import deluge.ui.console.colors as colors from deluge.log import LOG as log -# XXX: Remove when the commands are all fixed up -def match_torrents(a=[]): - pass - class OptionParser(optparse.OptionParser): """subclass from optparse.OptionParser so exit() won't exit.""" def exit(self, status=0, msg=None): @@ -149,8 +145,8 @@ class ConsoleUI(component.Component): self.statusbars = StatusBars() self.eventlog = EventLog() - self.screen.topbar = "{{status}}Deluge " + deluge.common.get_version() + " Console" - self.screen.bottombar = "{{status}}" + self.screen.topbar = "{!status!}Deluge " + deluge.common.get_version() + " Console" + self.screen.bottombar = "{!status!}" self.screen.refresh() # The Screen object is designed to run as a twisted reader so that it @@ -203,7 +199,7 @@ class ConsoleUI(component.Component): try: parser = self._commands[cmd].create_parser() except KeyError: - self.write("{{error}}Unknown command: %s" % cmd) + self.write("{!error!}Unknown command: %s" % cmd) return args = self._commands[cmd].split(line) @@ -221,7 +217,7 @@ class ConsoleUI(component.Component): try: self._commands[cmd].handle(*args, **options.__dict__) except Exception, e: - self.write("{{error}}" + str(e)) + self.write("{!error!}" + str(e)) log.exception(e) import traceback self.write("%s" % traceback.format_exc()) diff --git a/deluge/ui/console/screen.py b/deluge/ui/console/screen.py index ab05d4aa7..67faa4e7f 100644 --- a/deluge/ui/console/screen.py +++ b/deluge/ui/console/screen.py @@ -97,25 +97,23 @@ class Screen(CursesStdIO): Add a line to the screen. This will be showed between the two bars. The text can be formatted with color using the following format: - "{{fg, bg, attributes, ...}}" + "{!fg, bg, attributes, ...!}" See: http://docs.python.org/library/curses.html#constants for attributes. Alternatively, it can use some built-in scheme for coloring. See colors.py for built-in schemes. - "{{scheme}}" + "{!scheme!}" Examples: - "{{blue, black, bold}}My Text is {{white, black}}cool" - "{{info}}I am some info text!" - "{{error}}Uh oh!" + "{!blue, black, bold!}My Text is {!white, black!}cool" + "{!info!}I am some info text!" + "{!error!}Uh oh!" :param text: str, the text to show """ - log.debug("adding line: %s", text) - def get_line_chunks(line): """ @@ -123,11 +121,11 @@ class Screen(CursesStdIO): """ chunks = [] - num_chunks = line.count("{{") + num_chunks = line.count("{!") for i in range(num_chunks): # Find the beginning and end of the color tag - beg = line.find("{{") - end = line.find("}}") + 2 + beg = line.find("{!") + end = line.find("!}") + 2 color = line[beg:end] line = line[end:] @@ -137,8 +135,8 @@ class Screen(CursesStdIO): else: # Not the last chunk so get the text up to the next tag # and remove the text from line - text = line[:line.find("{{")] - line = line[line.find("{{"):] + text = line[:line.find("{!")] + line = line[line.find("{!"):] chunks.append((color, text)) @@ -196,8 +194,8 @@ class Screen(CursesStdIO): col = 0 try: parsed = colors.parse_color_string(string) - except colors.BadColorString: - log.error("Cannot add bad color string: %s", string) + except colors.BadColorString, e: + log.error("Cannot add bad color string %s: %s", string, e) return for index, (color, s) in enumerate(parsed): diff --git a/deluge/ui/console/statusbars.py b/deluge/ui/console/statusbars.py index 77e172e2a..094dff074 100644 --- a/deluge/ui/console/statusbars.py +++ b/deluge/ui/console/statusbars.py @@ -74,7 +74,7 @@ class StatusBars(component.Component): def update_statusbars(self): # Update the topbar string - self.screen.topbar = "{{status}}Deluge %s Console - " % deluge.common.get_version() + self.screen.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version() if client.connected(): info = client.connection_info() self.screen.topbar += "%s@%s:%s" % (info[2], info[0], info[1]) @@ -82,7 +82,7 @@ class StatusBars(component.Component): self.screen.topbar += "Not Connected" # Update the bottombar string - self.screen.bottombar = "{{status}}C: %s" % self.connections + self.screen.bottombar = "{!status!}C: %s" % self.connections if self.config["max_connections_global"] > -1: self.screen.bottombar += " (%s)" % self.config["max_connections_global"]