Michael Pasternak has uploaded a new change for review.

Change subject: cli: implement visualization effects
......................................................................

cli: implement visualization effects

Change-Id: I074e6d03f46f42261f96a71024fe28f871bd0c65
Signed-off-by: Michael pasternak <[email protected]>
---
M src/cli/command/command.py
M src/cli/context.py
M src/cli/error.py
M src/cli/messages.py
A src/cli/warning.py
M src/ovirtcli/shell/engineshell.py
A src/ovirtcli/utils/colorhelper.py
7 files changed, 182 insertions(+), 20 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine-cli refs/changes/47/20147/1

diff --git a/src/cli/command/command.py b/src/cli/command/command.py
index f964ad2..b549e45 100644
--- a/src/cli/command/command.py
+++ b/src/cli/command/command.py
@@ -20,6 +20,7 @@
 from ovirtcli.format.help import Help
 from ovirtcli.utils.methodhelper import MethodHelper
 from ovirtcli.utils.multivaluedict import MultiValueDict
+from cli.warning import GenericWarning
 
 
 class Command(object):
@@ -102,8 +103,8 @@
     def execute(self, context):
         """Override this method in a subclass."""
 
-    def warning(self, message):
-        self.context.terminal.stdout.write('warning: ' + message + '\n')
+    def warning(self, message, **kwargs):
+        raise GenericWarning(message, **kwargs)
 
     def write(self, message):
         self.context.terminal.stdout.write(message + '\n')
diff --git a/src/cli/context.py b/src/cli/context.py
index 3085b9b..33c3e5e 100644
--- a/src/cli/context.py
+++ b/src/cli/context.py
@@ -34,6 +34,7 @@
 from cli.platform import Terminal
 from cli import platform
 from cli.executionmode import ExecutionMode
+from ovirtcli.utils.colorhelper import ColorHelper
 
 
 class ExecutionContext(object):
@@ -202,6 +203,15 @@
         ]
 
         err_str = str(err)
+        err_str = (
+           "\n" if not (
+                    err_str.startswith("\n")
+                    or
+                    err_str.startswith("\r\n")
+                )
+                else ""
+        ) + err_str
+
         for err_pattern in err_patterns:
             if err_str.find(err_pattern) <> -1:
                 err_str = err_str.replace(
@@ -221,25 +231,73 @@
         elif isinstance(e, CommandError) or isinstance(e, RequestError) \
             or isinstance(e, AmbiguousQueryError):
             self.status = getattr(e, 'status', self.COMMAND_ERROR)
-            sys.stderr.write('\nerror: %s\n\n' % self.__error_to_string(e))
+            self.__pint_error(e)
             if hasattr(e, 'help'):
                 sys.stderr.write('%s\n' % e.help)
         elif isinstance(e, SyntaxError):
             self.status = getattr(e, 'status', self.SYNTAX_ERROR)
-            sys.stderr.write('\nerror: %s\n\n' % self.__error_to_string(e))
+            self.__pint_error(e)
             if hasattr(e, 'help'):
                 sys.stderr.write('%s\n' % e.help)
         elif isinstance(e, ConnectionError):
             self.status = getattr(e, 'status', self.COMMUNICATION_ERROR)
-            sys.stderr.write('\nerror: %s\n\n' % self.__error_to_string(e))
+            self.__pint_error(e)
             if hasattr(e, 'help'):
                 sys.stderr.write('%s\n' % e.help)
+        elif isinstance(e, Warning):
+            self.__pint_warning(e)
         else:
             self.status = self.UNKNOWN_ERROR
             if self.settings['cli:debug']:
                 sys.stderr.write(traceback.format_exc())
             else:
-                sys.stderr.write('\nunknown error: %s\n\n' % 
self.__error_to_string(e))
+                self.__pint_error(e, header='UNKNOWN ERROR')
+
+    def __pint_error(self, e, header='ERROR'):
+        """
+        prints error to stderr
+        
+        @param e: exception
+        @param header: the error header
+        """
+        sys.stderr.write(
+             ColorHelper.color(
+                 '\n++++++++++++++++++ %s ++++++++++++++++++\n%s\n\n'
+                  %
+                  (
+                   header,
+                   self.__error_to_string(e)
+                  ),
+                  ColorHelper.RED if self.mode != ExecutionMode.SCRIPT
+                                     and self.interactive
+                                  else None
+              )
+        )
+
+    def __pint_warning(self, e):
+        """
+        prints warning to stdout
+        
+        @param e: exception
+        """
+        sys.stdout.write(
+             ColorHelper.color(
+                 '\n+++++++++++++++++ WARNING +++++++++++++++++\n%s\n\n'
+                  %
+                  self.__error_to_string(e),
+                  ColorHelper.YELLOW if self.mode != ExecutionMode.SCRIPT
+                                        and self.interactive
+                                     else None
+              )
+        )
+
+    def _pint_text(self, text):
+        """
+        prints text to stdout
+        
+        @param text: text
+        """
+        sys.stdout.write("\n" + text + "\n")
 
     def _read_command(self):
         """Parse input until we can parse at least one full command, and
@@ -265,7 +323,7 @@
                 return
             command += line
             try:
-                parsed = self.parser.parse(command)
+                parsed = self.parser.parse(command)  # @UnusedVariable
             except EOFError:
                 prompt = self.settings['cli:ps2']
                 continue
diff --git a/src/cli/error.py b/src/cli/error.py
index 0529c68..27f4740 100644
--- a/src/cli/error.py
+++ b/src/cli/error.py
@@ -38,5 +38,5 @@
 class CommandError(Error):
     """Illegal command."""
 
-class SyntaxError(Error):
+class SyntaxError(Error):  # @ReservedAssignment
     """Illegal syntax."""
diff --git a/src/cli/messages.py b/src/cli/messages.py
index 55ec281..8da51de 100644
--- a/src/cli/messages.py
+++ b/src/cli/messages.py
@@ -41,7 +41,7 @@
         CANNOT_CONNECT_TO_BACKEND = 'could NOT reach %s manager\n.'
         CANNOT_CONSTRUCT_COLLECTION_MEMBER_VIEW = 'cannot construct 
collection/member view, checked variants are:\n%s.\n'
         INVALID_DISPLAY_PROTOCOL = 'display protocol "%s" is not supported.'
-        INVALID_COMMAND = 'command "%s" not valid or not available while not 
connected.'
+        INVALID_COMMAND = 'command "%s" is not valid or not available while 
not connected.'
         INVALID_ENV_MODE_FOR_CONSOLE = 'not running in a GUI, cannot start a 
%s viewer.'
         INVALID_OPTION = 'option %s cannot be empty.'
         INVALID_COLLECTION_BASED_OPTION_SYNTAX = 'invalid syntax at "--%s", 
see help on collection based arguments for more details.'
diff --git a/src/cli/warning.py b/src/cli/warning.py
new file mode 100644
index 0000000..bb0652b
--- /dev/null
+++ b/src/cli/warning.py
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2010 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#           http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+from cli import compat
+
+
+class Warning(Exception):  # @ReservedAssignment
+    """Base class for python-cli warnings."""
+
+    def __init__(self, message=None, **kwargs):
+        if message is None: message = self.__doc__
+        message = message + '\n' if not message.endswith('\n') \
+                                 else message
+        compat.super(Warning, self).__init__(message)
+
+        for key in kwargs:
+            setattr(self, key, kwargs[key])
+
+class GenericWarning(Warning):
+    """Generic warning."""
+
diff --git a/src/ovirtcli/shell/engineshell.py 
b/src/ovirtcli/shell/engineshell.py
index ac6323e..e575961 100644
--- a/src/ovirtcli/shell/engineshell.py
+++ b/src/ovirtcli/shell/engineshell.py
@@ -47,6 +47,8 @@
 from cli.messages import Messages
 
 from urlparse import urlparse
+from ovirtcli.utils.colorhelper import ColorHelper
+from cli.executionmode import ExecutionMode
 
 
 class EngineShell(cmd.Cmd, ConnectCmdShell, ActionCmdShell, \
@@ -156,21 +158,55 @@
         elif mode == PromptMode.Disconnected or mode == PromptMode.Default:
             if not self.__org_prompt and self.prompt != "(Cmd) ":
                 self.__org_prompt = self.prompt
-            self.prompt = 
self.context.settings.get('ovirt-shell:ps1.disconnected')
+            self.prompt = self.__get_disconnected_prompt()
         elif mode == PromptMode.Connected:
             self.prompt = self.__get_connected_prompt()
+
+    def __get_disconnected_prompt(self):
+        dprompt = self.context.settings.get('ovirt-shell:ps1.disconnected')
+        if self.context.mode != ExecutionMode.SCRIPT \
+           and self.context.interactive:
+            dprompt = dprompt.replace(
+                          "disconnected",
+                          ColorHelper.color(
+                                "disconnected",
+                                color_=ColorHelper.RED
+                          )
+            )
+        return dprompt
 
     def __get_connected_prompt(self):
         if self.context.settings.get('ovirt-shell:extended_prompt'):
             url = self.context.settings.get('ovirt-shell:url')
             url_obj = urlparse(url)
             if url_obj and hasattr(url_obj, 'hostname'):
-                return self.context.settings.get(
-                       'ovirt-shell:ps3.connected'
-                       ) % {
-                          'host':url_obj.hostname
-                       }
-        return self.context.settings.get('ovirt-shell:ps2.connected')
+                cprompt = self.context.settings.get(
+                               'ovirt-shell:ps3.connected'
+                          ) % {
+                               'host':url_obj.hostname
+                }
+                if self.context.mode != ExecutionMode.SCRIPT \
+                   and self.context.interactive:
+                    cprompt = cprompt.replace(
+                              "connected@" + url_obj.hostname,
+                              ColorHelper.color(
+                                    'connected@' + url_obj.hostname,
+                                    color_=ColorHelper.GREEN
+                              )
+                )
+                return cprompt
+
+        cprompt = self.context.settings.get('ovirt-shell:ps2.connected')
+        if self.context.mode != ExecutionMode.SCRIPT \
+           and self.context.interactive:
+            cprompt = cprompt.replace(
+                              "connected",
+                              ColorHelper.color(
+                                 "connected",
+                                 color_=ColorHelper.GREEN
+                               )
+        )
+        return cprompt
 
 
     def __persistCmdOptions(self, opts):
@@ -296,12 +332,10 @@
             return None
 
     def _error(self, msg):
-        sys.stderr.write("\nerror: " + msg + "\n")
-        sys.stdout.write("\n")
+        self.context._handle_exception(SyntaxError(msg))
 
     def _print(self, msg):
-        sys.stdout.write("\n" + msg + "\n")
-        sys.stdout.write("\n")
+        self.context._pint_text(msg)
 
     def do_EOF(self, line):
         """\
diff --git a/src/ovirtcli/utils/colorhelper.py 
b/src/ovirtcli/utils/colorhelper.py
new file mode 100644
index 0000000..0aab2d5
--- /dev/null
+++ b/src/ovirtcli/utils/colorhelper.py
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2010 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#           http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+class ColorHelper():
+    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
+
+    __NONE = None
+    __ENDC = '\033[0m'
+
+    @staticmethod
+    def color(text, color_):
+        """
+        Colors text
+        
+        @param text: text to color
+        @param color_: color to use (ColorHelper.RED|ColorHelper.BLUE...)
+        """
+        if color_:
+            return "\x1b[1;%dm" % (30 + color_) + text + "\x1b[0m"
+        return text


-- 
To view, visit http://gerrit.ovirt.org/20147
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I074e6d03f46f42261f96a71024fe28f871bd0c65
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine-cli
Gerrit-Branch: master
Gerrit-Owner: Michael Pasternak <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to