diff --git a/CHANGELOG b/CHANGELOG index 9066b92..73a5e0f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ 1.1 - Incorrect relational operations now raise an exception instead of returning None - Forces relations to have correct names for attributes +- Colored output in readline mode 1.0 - Adds history in the GUI diff --git a/CREDITS b/CREDITS index 36d9124..30fb6c3 100644 --- a/CREDITS +++ b/CREDITS @@ -1,3 +1,5 @@ Ori Avtalion for suggesting some improvements Chris Lamb for being interested Emilio Di Prima for the windows port +Konstantin Lepa (for the termcolor module) + diff --git a/relational_readline/linegui.py b/relational_readline/linegui.py index 41a63aa..005bb35 100644 --- a/relational_readline/linegui.py +++ b/relational_readline/linegui.py @@ -24,9 +24,10 @@ import logging import os.path import os import sys -import curses from relational import relation, parser, rtypes +from termcolor import colored + class SimpleCompleter(object): '''Handles completion''' @@ -96,7 +97,7 @@ completer=SimpleCompleter(['LIST','LOAD ','UNLOAD ','HELP ','QUIT','SAVE ','_PRO def load_relation(filename,defname=None): if not os.path.isfile(filename): - print >> sys.stderr, "%s is not a file" % filename + print >> sys.stderr, colored("%s is not a file" % filename,'red') return None f=filename.split('/') @@ -106,16 +107,16 @@ def load_relation(filename,defname=None): defname=defname[:-4] if not rtypes.is_valid_relation_name(defname): - print >> sys.stderr, "%s is not a valid relation name" % defname + print >> sys.stderr, colored("%s is not a valid relation name" % defname,'red') return try: relations[defname]=relation.relation(filename) completer.add_completion(defname) - print "Loaded relation %s"% defname + print colored("Loaded relation %s"% defname,'green',attrs=['bold']) return defname except Exception, e: - print e + print >>sys.stderr,colored(e,'red') return None def help(command): @@ -151,7 +152,10 @@ def help(command): def exec_line(command): command=command.strip() - if command=='QUIT': + + if command.startswith(';'): + return + elif command=='QUIT': sys.exit(0) elif command.startswith('HELP'): help(command) @@ -159,10 +163,10 @@ def exec_line(command): for i in relations: if not i.startswith('_'): print i - elif command.startswith('LOAD'): #Loads a relation + elif command.startswith('LOAD '): #Loads a relation pars=command.split(' ') if len(pars)==1: - print "Missing parameter" + print colored("Missing parameter",'red') return filename=pars[1] @@ -172,34 +176,34 @@ def exec_line(command): defname=None load_relation(filename,defname) - elif command.startswith('UNLOAD'): + elif command.startswith('UNLOAD '): pars=command.split(' ') if len(pars)<2: - print "Missing parameter" + print colored("Missing parameter",'red') return if pars[1] in relations: del relations[pars[1]] completer.remove_completion(pars[1]) else: - print "No such relation %s" % pars[1] + print colored("No such relation %s" % pars[1],'red') pass - elif command.startswith('SAVE'): + elif command.startswith('SAVE '): pars=command.split(' ') if len(pars)!=3: - print "Missing parameter" + print colored("Missing parameter",'red') return filename=pars[1] defname=pars[2] if defname not in relations: - print "No such relation %s" % defname + print colored("No such relation %s" % defname,'red') return try: relations[defname].save(filename) except Exception,e: - print e + print colored(e,'red') else: exec_query(command) @@ -249,7 +253,7 @@ def exec_query(command): try: pyquery=parser.parse(query) result=eval(pyquery,relations) - print "-> query: %s" % pyquery + print colored("-> query: %s" % pyquery,'green') if printrel: print @@ -259,22 +263,11 @@ def exec_query(command): completer.add_completion(relname) except Exception, e: - print e + print colored(e,'red') def main(files=[]): - - import locale - locale.setlocale(locale.LC_ALL, '') - code = locale.getpreferredencoding() - - print curses.can_change_color() - - curses.color_pair(curses.A_BOLD) - - - - print "> ; Type HELP to get the HELP" - print "> ; Completion is activated using the tab (if supported by the terminal)" + print colored('> ','blue') + "; Type HELP to get the HELP" + print colored('> ','blue') + "; Completion is activated using the tab (if supported by the terminal)" for i in files: load_relation(i) @@ -288,8 +281,8 @@ def main(files=[]): while True: try: - line = raw_input('> ') - if isinstance(line,str) and len(line)>0 and not line.startswith(';'): + line = raw_input(colored('> ','blue')) + if isinstance(line,str) and len(line)>0: exec_line(line) except EOFError: print @@ -297,5 +290,5 @@ def main(files=[]): if __name__ == "__main__": - - main() \ No newline at end of file + main() + \ No newline at end of file diff --git a/relational_readline/termcolor.py b/relational_readline/termcolor.py new file mode 100644 index 0000000..8f451eb --- /dev/null +++ b/relational_readline/termcolor.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2008-2009 Konstantin Lepa . +# +# This file is part of termcolor. +# +# termcolor is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# termcolor is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License +# along with termcolor. If not, see . + +"""ANSII Color formatting for output in terminal.""" + +import os + + +__ALL__ = [ 'colored' ] + + +ATTRIBUTES = dict( + zip([ + 'bold', + 'dark', + '', + 'underline', + 'blink', + '', + 'reverse', + 'concealed' + ], + range(1, 9) + ) + ) +del ATTRIBUTES[''] + + +HIGHLIGHTS = dict( + zip([ + 'on_grey', + 'on_red', + 'on_green', + 'on_yellow', + 'on_blue', + 'on_magenta', + 'on_cyan', + 'on_white' + ], + range(40, 48) + ) + ) + + +COLORS = dict( + zip([ + 'grey', + 'red', + 'green', + 'yellow', + 'blue', + 'magenta', + 'cyan', + 'white', + ], + range(30, 38) + ) + ) + + +RESET = '\033[0m' + + +def colored(text, color=None, on_color=None, attrs=['bold']): + """Colorize text. + + Available text colors: + red, green, yellow, blue, magenta, cyan, white. + + Available text highlights: + on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white. + + Available attributes: + bold, dark, underline, blink, reverse, concealed. + + Example: + colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink']) + colored('Hello, World!', 'green') + """ + if os.getenv('ANSI_COLORS_DISABLED') is None: + fmt_str = '\033[%dm%s' + if color is not None: + text = fmt_str % (COLORS[color], text) + + if on_color is not None: + text = fmt_str % (HIGHLIGHTS[on_color], text) + + if attrs is not None: + for attr in attrs: + text = fmt_str % (ATTRIBUTES[attr], text) + + text += RESET + return text + + +if __name__ == '__main__': + print 'Current terminal type: ', os.getenv('TERM') + print 'Test basic colors:' + print colored('Grey color', 'grey') + print colored('Red color', 'red') + print colored('Green color', 'green') + print colored('Yellow color', 'yellow') + print colored('Blue color', 'blue') + print colored('Magenta color', 'magenta') + print colored('Cyan color', 'cyan') + print colored('White color', 'white') + print '-' * 78 + + print 'Test highlights:' + print colored('On grey color', on_color='on_grey') + print colored('On red color', on_color='on_red') + print colored('On green color', on_color='on_green') + print colored('On yellow color', on_color='on_yellow') + print colored('On blue color', on_color='on_blue') + print colored('On magenta color', on_color='on_magenta') + print colored('On cyan color', on_color='on_cyan') + print colored('On white color', color='grey', on_color='on_white') + print '-' * 78 + + print 'Test attributes:' + print colored('Bold grey color', 'grey', attrs=['bold']) + print colored('Dark red color', 'red', attrs=['dark']) + print colored('Underline green color', 'green', attrs=['underline']) + print colored('Blink yellow color', 'yellow', attrs=['blink']) + print colored('Reversed blue color', 'blue', attrs=['reverse']) + print colored('Concealed Magenta color', 'magenta', attrs=['concealed']) + print colored('Bold underline reverse cyan color', 'cyan', + attrs=['bold', 'underline', 'reverse']) + print colored('Dark blink concealed white color', 'white', + attrs=['dark', 'blink', 'concealed']) + print '-' * 78 + + print 'Test mixing:' + print colored('Underline red on grey color', 'red', 'on_grey', + ['underline']) + print colored('Reversed green on red color', 'green', 'on_red', ['reverse']) + diff --git a/test/driver.py b/test/driver.py index 0e997a3..461bc29 100644 --- a/test/driver.py +++ b/test/driver.py @@ -20,7 +20,7 @@ # author Salvo "LtWorf" Tomaselli from relational import relation, parser, optimizer - +from relational_readline.termcolor import colored import os print relation @@ -139,7 +139,7 @@ def run_exec_test(testname): fields_ok = fields_ok and glob[i]==exp_result[i] if fields_ok: - print "\033[32;1mTest passed\033[0m" + print colored('Test passed','green') return True except: pass