Bug#279000: cplay: does not show non-ASCII UTF-8 characters

2007-08-27 Thread Martin Michlmayr
* Markus Järvinen [EMAIL PROTECTED] [2004-10-31 00:46]:
 cplay replaces non-ASCII characters in most cases with ??. The only place
 that characters are shown correctly seems to be the top row when in
 filelist mode (Filelist: /...). All characters of the path are printed
 correctly there. In other places I get ?? instead of the non-ASCII
 characters. I am using an UTF-8 locale and UTF-8 file names.

I have an initial patch for this now, which seems to work even if it's
not particularly nice.  I don't know if Ulf Betlehem is still actively
developing cplay, but essentially cplay needs to be converted to use
Unicode strings internally and then to convert them to whatever locale
the user is using.

The patch below still contains some hacks and I'm not sure whether it
should be assumed that random data (lik filenames) are in UTF-8
(rather than in the locale of the user).


--- /usr/bin/cplay  2005-09-13 21:56:38.0 +0200
+++ /home/tbm/cplay 2007-08-27 17:24:08.0 +0200
@@ -32,6 +32,7 @@
 import signal
 import string
 import select
+import types
 import re
 
 try: from ncurses import curses
@@ -121,10 +122,6 @@
 class Window:
 chars = string.letters+string.digits+string.punctuation+string.whitespace
 
-t = ['?'] * 256
-for c in chars: t[ord(c)] = c
-translationTable = string.join(t, ); del t
-
 def __init__(self, parent):
 self.parent = parent
 self.children = []
@@ -136,8 +133,17 @@
 
 def insstr(self, s):
 if not s: return
-self.w.addstr(s[:-1])
-self.w.hline(ord(s[-1]), 1)  # insch() work-around
+s1 = s[:-1]
+s2 = s[-1]
+if type(s) == types.UnicodeType:
+s1 = s1.encode(locale.getpreferredencoding(), replace)
+s2 = s2.encode(locale.getpreferredencoding(), replace)
+# HACK: sometimes self.w.addstr() returns a curses error.
+# Maybe related to strings that take up the whole screen
+try:
+self.w.addstr(s1)
+self.w.hline(ord(s[-1]), 1)  # insch() work-around
+except: pass
 
 def __getattr__(self, name):
 return getattr(self.w, name)
@@ -218,7 +224,7 @@
 return curses.newwin(1, self.parent.cols-12, self.parent.rows-1, 0)
 
 def update(self):
-msg = string.translate(self.current_message, Window.translationTable)
+msg = self.current_message
 self.move(0, 0)
 self.clrtoeol()
 self.insstr(cut(msg, self.cols))
@@ -226,7 +232,7 @@
 self.refresh()
 
 def status(self, message, duration = 0):
-self.current_message = str(message)
+self.current_message = message
 if self.tid: app.timeout.remove(self.tid)
 if duration: self.tid = app.timeout.add(duration, self.timeout)
 else: self.tid = None
@@ -239,7 +245,8 @@
 def set_default_status(self, message):
 if self.current_message == self.default_message: self.status(message)
 self.default_message = message
-XTERM and sys.stderr.write(\033]0;%s\a % (message or cplay))
+# FIXME: doesn't accept UTF-8.  What does it need so it will show 
UTF-8 chars?
+XTERM and sys.stderr.write(\033]0;%s\a % (message.encode(latin-1, 
replace) or cplay))
 
 def restore_default_status(self):
 self.status(self.default_message)
@@ -436,7 +443,10 @@
 return %-*s  %s % (width, cut(self.name+data, width), pos)
 
 def putstr(self, entry, *pos):
-s = string.translate(str(entry), Window.translationTable)
+if type(entry) == types.StringType:
+s = entry
+else:
+s = entry.text()
 pos and apply(self.move, pos)
 if self.hoffset: s = %s % s[self.hoffset+1:]
 self.insstr(cut(s, self.cols))
@@ -555,12 +565,12 @@
 def is_tagged(self):
 return self.tagged == 1
 
-def __str__(self):
+def text(self):
 mark = self.is_tagged() and # or  
 return %s %s%s % (mark, self.vp(), self.slash)
 
 def vp(self):
-return self.vps[0][1](self)
+return unicode(self.vps[0][1](self), utf-8)
 
 def vp_filename(self):
 return self.filename or self.pathname
@@ -789,7 +799,7 @@
 
 def get_title(self):
 self.name = _(Filelist: )
-return ListWindow.get_title(self, re.sub(/?$, /, self.cwd))
+return ListWindow.get_title(self, re.sub(/?$, /, unicode(self.cwd, 
utf-8)))
 
 def listdir_maybe(self, now=0):
 if now  self.mtime_when+2: return
@@ -981,7 +991,7 @@
 self.append(PlaylistEntry(pathname))
 # todo - refactor
 filename = os.path.basename(pathname) or pathname
-quiet or app.status(_(Added: %s) % filename, 1)
+quiet or app.status(_(Added: %s) % unicode(filename, utf-8), 1)
 except Exception, e:
 app.status(e, 2)
 
@@ -1163,16 +1173,14 @@
 
 artist = tags.get(ARTIST, [])[0]
 title = tags.get(TITLE, [])[0]
-tag 

Bug#279000: cplay: does not show non-ASCII UTF-8 characters

2007-08-27 Thread Martin Michlmayr
Just some explanations:

* Martin Michlmayr [EMAIL PROTECTED] [2007-08-27 17:33]:
  def insstr(self, s):
  if not s: return
 -self.w.addstr(s[:-1])
 -self.w.hline(ord(s[-1]), 1)  # insch() work-around
 +s1 = s[:-1]
 +s2 = s[-1]
 +if type(s) == types.UnicodeType:
 +s1 = s1.encode(locale.getpreferredencoding(), replace)
 +s2 = s2.encode(locale.getpreferredencoding(), replace)
 +# HACK: sometimes self.w.addstr() returns a curses error.
 +# Maybe related to strings that take up the whole screen
 +try:
 +self.w.addstr(s1)
 +self.w.hline(ord(s[-1]), 1)  # insch() work-around
 +except: pass

Well, I don't get the whole insch() work-around stuff going on here.
But in any case, in an UTF-8 locale I something get an exception from
curses, maybe it's related to songs that have long titles, but I'm not
really sure why this is happening.

  def putstr(self, entry, *pos):
 -s = string.translate(str(entry), Window.translationTable)
 +if type(entry) == types.StringType:
 +s = entry
 +else:
 +s = entry.text()

This is pretty ugly, but essentially you cannot call str() anymore
because that will give you an exception since Python tries to convert
the string to ASCII and that often fails.  Often this function is
called with a ListEntry so I converted its str function to text.  But
sometimes the function gets passed a normal string (e.g. when you
press 'h' to open the help).  Anyway, this is not nice but I didn't
investigate more closely.

-- 
Martin Michlmayr
http://www.cyrius.com/


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]