Index: /pykoticon/trunk/bin/pykoticon
===================================================================
--- /pykoticon/trunk/bin/pykoticon (revision 114)
+++ /pykoticon/trunk/bin/pykoticon (revision 119)
@@ -1,4 +1,6 @@
 #! /usr/bin/env python
 # -*- coding: ISO-8859-15 -*-
+
+"""PyKotIcon is a generic, networked, cross-platform dialog box manager."""
 
 # PyKotIcon - Client side helper for PyKota
@@ -19,10 +21,16 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 #
-# $Id$
 #
-#
+
+__version__ = "1.01"
+__author__ = "Jerome Alet"
+__author_email__ = "alet@librelogiciel.com"
+__license__ = "GNU GPL"
+__url__ = "http://www.librelogiciel.com/software/"
+__revision__ = "$Id$"
 
 import sys
 import os
+import time
 import urllib
 import urllib2
@@ -34,8 +42,7 @@
 import SimpleXMLRPCServer
 
-import time
 
 if sys.platform == "win32" :
-    isWindows = 1
+    isWindows = True
     try :
         import win32api
@@ -45,5 +52,5 @@
         iconsdir = os.path.split(sys.argv[0])[0]
 else :        
-    isWindows = 0
+    isWindows = False
     iconsdir = "/usr/share/pykoticon"   # TODO : change this
     import pwd
@@ -51,12 +58,14 @@
 try :    
     import wx
-    hasWxPython = 1
+    hasWxPython = True
 except ImportError :    
-    hasWxPython = 0
+    hasWxPython = False
     raise ImportError, "wxPython is missing. Please install it."
     
-aboutbox = """PyKotIcon v1.00 (c) 2003, 2004, 2005, 2006 Jerome Alet - alet@librelogiciel.com    
-
-PyKotIcon is a client side print quota notifier for PyKota, but it 
+aboutbox = """PyKotIcon v%(__version__)s (c) 2003-2006 %(__author__)s - %(__author_email__)s
+
+PyKotIcon is generic, networked, cross-platform dialog box manager.
+
+It is often used as a client side companion for PyKota, but it
 can be used from other applications if you want.
 
@@ -75,13 +84,4 @@
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."""
 
-def getCurrentUserName() :
-    """Retrieves the current user's name."""
-    if isWindows :
-        return win32api.GetUserName()
-    else :    
-        try :
-            return pwd.getpwuid(os.geteuid())[0]
-        except :
-            return "** Unknown **"
         
 class MyXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer) :
@@ -110,7 +110,7 @@
         """Asks some textual datas defined by a list of labels, a list of variables' names and a list of variables values in a mapping."""
         values = {}
-        for (k, v) in varvalues.items() :
-            values[k] = self.frame.UTF8ToUserCharset(v.data)
-        wx.CallAfter(self.frame.askDatas, [ self.frame.UTF8ToUserCharset(v.data) for v in labels ], \
+        for (key, value) in varvalues.items() :
+            values[key] = self.frame.UTF8ToUserCharset(value.data)
+        wx.CallAfter(self.frame.askDatas, [ self.frame.UTF8ToUserCharset(label.data) for label in labels ], \
                                           varnames, \
                                           values)
@@ -119,7 +119,7 @@
             time.sleep(0.1)
         retcode = self.frame.dialogAnswer    
-        for (k, v) in retcode.items() :
-            if k != "isValid" :
-                retcode[k] = xmlrpclib.Binary(self.frame.userCharsetToUTF8(v))
+        for (key, value) in retcode.items() :
+            if key != "isValid" :
+                retcode[key] = xmlrpclib.Binary(self.frame.userCharsetToUTF8(value))
         self.frame.dialogAnswer = None # prepare for next call, just in case
         return retcode
@@ -164,4 +164,5 @@
         self.server_close()    
         sys.exit(0)
+    
     
 class GenericInputDialog(wx.Dialog) :
@@ -203,4 +204,5 @@
         self.Layout()
         
+        
 class PyKotIcon(wx.Frame):
     """Main class."""
@@ -208,5 +210,5 @@
         self.dialogAnswer = None
         wx.Frame.__init__(self, parent, id, \
-               _("PyKotIcon info for %s") % getCurrentUserName(), \
+               _("PyKotIcon info for %s") % self.getCurrentUserName(), \
                size = (1, 1), \
                style = wx.FRAME_NO_TASKBAR | wx.NO_FULL_REPAINT_ON_RESIZE)
@@ -239,4 +241,14 @@
         self.Show(True)
         
+    def getCurrentUserName(self) :
+        """Retrieves the current user's name."""
+        if isWindows :
+            return win32api.GetUserName()
+        else :    
+            try :
+                return pwd.getpwuid(os.geteuid())[0]
+            except :
+                return "** Unknown **"
+            
     def OnIconify(self, event) :
         if not self.IsIconized() :
@@ -265,5 +277,5 @@
     def OnAbout(self, event) :    
         """Displays the about box."""
-        dialog = wx.MessageDialog(self, aboutbox, _("About"), wx.OK | wx.ICON_INFORMATION)
+        dialog = wx.MessageDialog(self, aboutbox % globals(), _("About"), wx.OK | wx.ICON_INFORMATION)
         dialog.ShowModal()
         dialog.Destroy()
@@ -319,5 +331,5 @@
         self.charset = charset
         self.port = localport
-        self.server = MyXMLRPCServer(self, printserver, localport, debug=True)
+        self.server = MyXMLRPCServer(self, printserver, localport)
         
     def UTF8ToUserCharset(self, text) :
@@ -325,14 +337,11 @@
         if text is not None :
             try :
-                return unicode(text, "UTF-8").encode(self.charset) 
-            except (UnicodeError, TypeError) :    
+                return text.decode("UTF-8").encode(self.charset, "replace") 
+            except (UnicodeError, AttributeError) :    
                 try :
-                    # Incorrect locale settings ?
-                    return unicode(text, "UTF-8").encode("ISO-8859-15") 
-                except (UnicodeError, TypeError) :    
-                    try :
-                        return text.encode(self.charset) 
-                    except (UnicodeError, TypeError, AttributeError) :
-                        pass
+                    # Maybe already in Unicode
+                    return text.encode(self.charset, "replace") 
+                except (UnicodeError, AttributeError) :
+                    pass # Don't know what to do
         return text
         
@@ -341,15 +350,22 @@
         if text is not None :
             try :
-                return unicode(text, self.charset).encode("UTF-8") 
-            except (UnicodeError, TypeError) :    
+                # We don't necessarily trust the default charset, because
+                # xprint sends us titles in UTF-8 but CUPS gives us an ISO-8859-1 charset !
+                # So we first try to see if the text is already in UTF-8 or not, and
+                # if it is, we delete characters which can't be converted to the user's charset,
+                # then convert back to UTF-8. PostgreSQL 7.3.x used to reject some unicode characters,
+                # this is fixed by the ugly line below :
+                return text.decode("UTF-8").encode(self.charset, "replace").decode(self.charset).encode("UTF-8", "replace")
+            except (UnicodeError, AttributeError) :
                 try :
-                    # Incorrect locale settings ?
-                    return unicode(text, "ISO-8859-15").encode("UTF-8") 
-                except (UnicodeError, TypeError) :    
+                    return text.decode(self.charset).encode("UTF-8", "replace") 
+                except (UnicodeError, AttributeError) :    
                     try :
-                        return text.encode("UTF-8") 
-                    except (UnicodeError, TypeError, AttributeError) :
-                        pass
+                        # Maybe already in Unicode
+                        return text.encode("UTF-8", "replace") 
+                    except (UnicodeError, AttributeError) :
+                        pass # Don't know what to do
         return text
+        
 
 class PyKotIconApp(wx.App):
@@ -363,4 +379,5 @@
         """Continues processing."""
         self.frame.postInit(charset, printserver, localport)
+        
         
 def main(printserver, localport):
@@ -400,4 +417,5 @@
     app.MainLoop()
     
+    
 def crashed() :    
     """Minimal crash method."""
@@ -410,9 +428,10 @@
     sys.stderr.flush()
     
+    
 if __name__ == '__main__':
     if len(sys.argv) >= 2 :
         arg = sys.argv[1]
         if arg in ("-v", "--version") :    
-            print "0.3"
+            print __version__
         elif arg in ("-h", "--help") :    
             sys.stderr.write("usage : pykoticon  pykota_server_hostname_or_ip_address  localTCPPort\n")
