1
0
mirror of https://github.com/openSUSE/osc.git synced 2024-12-25 01:16:14 +01:00

- don't fail if terminal encoding doesn't support unicode (fixes #660445)

- added util.safewriter.SafeWriter class
This commit is contained in:
Marcus Huewe 2011-02-11 02:43:10 +01:00
parent 8fc0a4e94b
commit 5cb8468f3b
4 changed files with 40 additions and 21 deletions

View File

@ -9,6 +9,7 @@ import cmdln
import conf import conf
import oscerr import oscerr
import sys import sys
from util import safewriter
from optparse import SUPPRESS_HELP from optparse import SUPPRESS_HELP
MAN_HEADER = r""".TH %(ucname)s "1" "%(date)s" "%(name)s %(version)s" "User Commands" MAN_HEADER = r""".TH %(ucname)s "1" "%(date)s" "%(name)s %(version)s" "User Commands"
@ -63,6 +64,8 @@ class Osc(cmdln.Cmdln):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
cmdln.Cmdln.__init__(self, *args, **kwargs) cmdln.Cmdln.__init__(self, *args, **kwargs)
cmdln.Cmdln.do_help.aliases.append('h') cmdln.Cmdln.do_help.aliases.append('h')
sys.stderr = safewriter.SafeWriter(sys.stderr)
sys.stdout = safewriter.SafeWriter(sys.stdout)
def get_version(self): def get_version(self):
return get_osc_version() return get_osc_version()
@ -349,10 +352,7 @@ class Osc(cmdln.Cmdln):
elif not opts.binaries: elif not opts.binaries:
if not args: if not args:
for prj in meta_get_project_list(apiurl, opts.deleted): for prj in meta_get_project_list(apiurl, opts.deleted):
try: print prj
print prj
except UnicodeEncodeError:
print prj.encode('unicode_escape')
elif len(args) == 1: elif len(args) == 1:
if opts.verbose: if opts.verbose:
@ -361,10 +361,7 @@ class Osc(cmdln.Cmdln):
if opts.expand: if opts.expand:
raise oscerr.WrongOptions('Sorry, the --expand option is not implemented for projects.') raise oscerr.WrongOptions('Sorry, the --expand option is not implemented for projects.')
for pkg in meta_get_packagelist(apiurl, project, opts.deleted): for pkg in meta_get_packagelist(apiurl, project, opts.deleted):
try: print pkg
print pkg
except UnicodeEncodeError:
print pkg.encode('unicode_escape')
elif len(args) == 2 or len(args) == 3: elif len(args) == 2 or len(args) == 3:
link_seen = False link_seen = False

View File

@ -2500,7 +2500,7 @@ class Request:
def list_view(self): def list_view(self):
"""return "list view" format""" """return "list view" format"""
import textwrap, locale import textwrap
lines = ['%6s State:%-10s By:%-12s When:%-19s' % (self.reqid, self.state.name, self.state.who, self.state.when)] lines = ['%6s State:%-10s By:%-12s When:%-19s' % (self.reqid, self.state.name, self.state.who, self.state.when)]
tmpl = ' %(type)-16s %(source)-50s %(target)s' tmpl = ' %(type)-16s %(source)-50s %(target)s'
for action in self.actions: for action in self.actions:
@ -2512,14 +2512,12 @@ class Request:
if history: if history:
lines.append(' From: %s' % ' -> '.join(history)) lines.append(' From: %s' % ' -> '.join(history))
if self.description: if self.description:
descr = self.description.encode(locale.getpreferredencoding(), 'replace') lines.append(textwrap.fill(self.description, width=80, initial_indent=' Descr: ',
lines.append(textwrap.fill(descr, width=80, initial_indent=' Descr: ',
subsequent_indent=' ')) subsequent_indent=' '))
return '\n'.join(lines) return '\n'.join(lines)
def __str__(self): def __str__(self):
"""return "detailed" format""" """return "detailed" format"""
import locale
lines = ['Request: #%s\n' % self.reqid] lines = ['Request: #%s\n' % self.reqid]
for action in self.actions: for action in self.actions:
tmpl = ' %(type)-13s %(source)s %(target)s' tmpl = ' %(type)-13s %(source)s %(target)s'
@ -2529,7 +2527,7 @@ class Request:
lines.append(tmpl % Request.format_action(action, show_srcupdate=True)) lines.append(tmpl % Request.format_action(action, show_srcupdate=True))
lines.append('\n\nMessage:') lines.append('\n\nMessage:')
if self.description: if self.description:
lines.append(self.description.encode(locale.getpreferredencoding(), 'replace')) lines.append(self.description)
else: else:
lines.append('<no message>') lines.append('<no message>')
if self.state: if self.state:
@ -5892,13 +5890,8 @@ def request_interactive_review(apiurl, request, initial_cmd=''):
tmpfile = None tmpfile = None
def print_request(request): def print_request(request):
try: print request
# FIXME: print can fail with unicode chars in the string.
# Here we fix the symptoms, not the cause.
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u2002' in position 309: ordinal not in range(128)
print request
except:
print request.__str__().encode('ascii', 'xmlcharrefreplace')
print_request(request) print_request(request)
try: try:
prompt = '(a)ccept/(d)ecline/(r)evoke/c(l)one/(s)kip/(c)ancel > ' prompt = '(a)ccept/(d)ecline/(r)evoke/c(l)one/(s)kip/(c)ancel > '

View File

@ -1 +1 @@
__all__ = ['ar', 'cpio', 'debquery', 'packagequery', 'rpmquery'] __all__ = ['ar', 'cpio', 'debquery', 'packagequery', 'rpmquery', 'safewriter']

29
osc/util/safewriter.py Normal file
View File

@ -0,0 +1,29 @@
# be careful when debugging this code:
# don't add print statements when setting sys.stdout = SafeWriter(sys.stdout)...
class SafeWriter:
"""
Safely write an (unicode) str. In case of an "UnicodeEncodeError" the
the str is encoded with the "encoding" encoding.
All getattr, setattr calls are passed through to the "writer" instance.
"""
def __init__(self, writer, encoding='unicode_escape'):
self.__dict__['writer'] = writer
self.__dict__['encoding'] = encoding
def __get_writer(self):
return self.__dict__['writer']
def __get_encoding(self):
return self.__dict__['encoding']
def write(self, s):
try:
self.__get_writer().write(s)
except UnicodeEncodeError, e:
self.__get_writer().write(s.encode(self.__get_encoding()))
def __getattr__(self, name):
return getattr(self.__get_writer(), name)
def __setattr__(self, name, value):
setattr(self.__get_writer(), name, value)