Revision 026e10fc

b/kamaki/cli/__init__.py
500 500
    def wrap():
501 501
        try:
502 502
            exe = basename(argv[0])
503
            if argv[1:]:
504
                from utils import pref_enc
505
                internal_argv = [arg.decode(pref_enc) for arg in argv]
503 506
            parser = ArgumentParseManager(exe)
504 507

  
505 508
            if parser.arguments['version'].value:
......
511 514
                logger.set_log_filename(log_file)
512 515
            global filelog
513 516
            filelog = logger.add_file_logger(__name__.split('.')[0])
514
            filelog.info('* Initial Call *\n%s\n- - -' % ' '.join(argv))
517

  
518
            filelog.info('%s\n- - -' % ' '.join(internal_argv))
515 519

  
516 520
            from kamaki.cli.utils import suggest_missing
517 521
            global _colors
b/kamaki/cli/commands/__init__.py
33 33

  
34 34
from kamaki.cli.logger import get_logger
35 35
from kamaki.cli.utils import (
36
    print_list, print_dict, print_json, print_items, ask_user,
37
    filter_dicts_by_dict, DontRaiseUnicodeError, pref_enc)
36
    print_list, print_dict, print_json, print_items, ask_user, pref_enc,
37
    filter_dicts_by_dict)
38 38
from kamaki.cli.argument import FlagArgument, ValueArgument
39 39
from kamaki.cli.errors import CLIInvalidArgument
40 40
from sys import stdin, stdout, stderr
......
114 114
        self.auth_base = auth_base or getattr(self, 'auth_base', None)
115 115
        self.cloud = cloud or getattr(self, 'cloud', None)
116 116

  
117
    @DontRaiseUnicodeError
118 117
    def write(self, s):
119
        self._out.write(s)
118
        self._out.write(s.encode(pref_enc, errors='replace'))
120 119
        self._out.flush()
121 120

  
122
    @DontRaiseUnicodeError
123 121
    def writeln(self, s=''):
124 122
        self.write('%s\n' % s)
125 123

  
126
    @DontRaiseUnicodeError
127 124
    def error(self, s=''):
128
        self._err.write('%s\n' % s)
125
        self._err.write(('%s\n' % s).encode(pref_enc, errors='replace'))
129 126
        self._err.flush()
130 127

  
131 128
    def print_list(self, *args, **kwargs):
b/kamaki/cli/utils/__init__.py
60 60
    suggest['ansicolors']['active'] = True
61 61

  
62 62

  
63
def _encode_nicely(somestr, encoding, replacement='?'):
64
    """Encode somestr as 'encoding', but don't raise errors (replace with ?)
65
        This method is slow. Us it only for grace.
66
        :param encoding: (str) encode every character in this encoding
67
        :param replacement: (char) replace each char raising encode-decode errs
68
    """
69
    newstr, err_counter = '', 0
70
    for c in somestr:
71
        try:
72
            newc = c.decode('utf-8').encode(encoding)
73
            newstr = '%s%s' % (newstr, newc)
74
        except UnicodeError as e:
75
            newstr = '%s%s' % (newstr, replacement)
76
            err_counter += 1
77
    if err_counter:
78
        log.warning('WARNING: \t%s character%s failed to be encoded as %s' % (
79
            err_counter, 's' if err_counter > 1 else '', encoding))
80
        log.debug('Unicode Error %s' % e)
81
    return newstr
82

  
83

  
84
def DontRaiseUnicodeError(foo):
85
    if pref_enc.lower() == 'utf-8':
86
        return foo
87

  
88
    def wrap(self, *args, **kwargs):
89
        try:
90
            s = kwargs.pop('s')
91
        except KeyError:
92
            try:
93
                s = args[0]
94
            except IndexError:
95
                return foo(self, *args, **kwargs)
96
            args = args[1:]
97
        try:
98
            s = (u'%s' % s).decode('utf-8').encode(pref_enc)
99
        except UnicodeError as ue:
100
            log.debug('Encoding(%s): %s' % (pref_enc, ue))
101
            s = _encode_nicely(u'%s' % s, pref_enc, replacement='?')
102
        return foo(self, s, *args, **kwargs)
103
    return wrap
104

  
105

  
106
def encode_for_console(s, encoding=pref_enc, replacement='?'):
107
    if encoding.lower() == 'utf-8':
108
        return s
109
    try:
110
        return s.decode('utf-8').encode(encoding)
111
    except UnicodeError as ue:
112
        log.debug('Encoding(%s): %s' % (encoding, ue))
113
        return _encode_nicely(s, encoding, replacement)
114

  
115

  
116 63
def suggest_missing(miss=None, exclude=[]):
117 64
    global suggest
118 65
    sgs = dict(suggest)
......
126 73
    for k, v in (miss, sgs[miss]) if miss else sgs.items():
127 74
        if v['active'] and stderr.isatty():
128 75
            stderr.write('Suggestion: you may like to install %s\n' % k)
129
            stderr.write('\t%s\n' % encode_for_console(v['description']))
76
            stderr.write(
77
                ('%s\n' % v['description']).encode(pref_enc, errors='replace'))
130 78
            stderr.write('\tIt is easy, here are the instructions:\n')
131 79
            stderr.write('\t%s/installation.html%s\n' % (
132 80
                kamaki_docs, v['url']))
......
170 118
    return new_d
171 119

  
172 120

  
173
def print_json(data, out=stdout, encoding=pref_enc):
121
def print_json(data, out=stdout):
174 122
    """Print a list or dict as json in console
175 123

  
176 124
    :param data: json-dumpable data

Also available in: Unified diff