Index: /pykota/trunk/pykota/dumper.py
===================================================================
--- /pykota/trunk/pykota/dumper.py (revision 3275)
+++ /pykota/trunk/pykota/dumper.py (revision 3288)
@@ -35,10 +35,11 @@
     sys.stderr.write("The jaxml Python module is not installed. XML output is disabled.\n")
     sys.stderr.write("Download jaxml from http://www.librelogiciel.com/software/ or from your Debian archive of choice\n")
-    hasJAXML = 0
+    hasJAXML = False
 else :    
-    hasJAXML = 1
+    hasJAXML = True
 
 from pykota import version
-from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, N_
+from pykota.tool import PyKotaTool, N_
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
 
 class DumPyKota(PyKotaTool) :        
Index: /pykota/trunk/pykota/storages/mysqlstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/mysqlstorage.py (revision 3275)
+++ /pykota/trunk/pykota/storages/mysqlstorage.py (revision 3288)
@@ -25,5 +25,6 @@
 import time
 
-from pykota.storage import PyKotaStorageError, BaseStorage
+from pykota.errors import PyKotaStorageError
+from pykota.storage import BaseStorage
 from pykota.storages.sql import SQLStorage
 
Index: /pykota/trunk/pykota/storages/pgstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/pgstorage.py (revision 3275)
+++ /pykota/trunk/pykota/storages/pgstorage.py (revision 3288)
@@ -26,5 +26,6 @@
 from types import StringType
 
-from pykota.storage import PyKotaStorageError, BaseStorage
+from pykota.errors import PyKotaStorageError
+from pykota.storage import BaseStorage
 from pykota.storages.sql import SQLStorage
 
Index: /pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/ldapstorage.py (revision 3275)
+++ /pykota/trunk/pykota/storages/ldapstorage.py (revision 3288)
@@ -37,5 +37,6 @@
 from mx import DateTime
 
-from pykota.storage import PyKotaStorageError, BaseStorage, \
+from pykota.errors import PyKotaStorageError
+from pykota.storage import BaseStorage, \
                            StorageUser, StorageGroup, StoragePrinter, \
                            StorageJob, StorageLastJob, StorageUserPQuota, \
Index: /pykota/trunk/pykota/storages/sqlitestorage.py
===================================================================
--- /pykota/trunk/pykota/storages/sqlitestorage.py (revision 3275)
+++ /pykota/trunk/pykota/storages/sqlitestorage.py (revision 3288)
@@ -25,5 +25,6 @@
 import time
 
-from pykota.storage import PyKotaStorageError, BaseStorage
+from pykota.errors import PyKotaStorageError
+from pykota.storage import BaseStorage
 from pykota.storages.sql import SQLStorage
 
Index: /pykota/trunk/pykota/reporter.py
===================================================================
--- /pykota/trunk/pykota/reporter.py (revision 3275)
+++ /pykota/trunk/pykota/reporter.py (revision 3288)
@@ -27,12 +27,5 @@
 from mx import DateTime
 
-class PyKotaReporterError(Exception):
-    """An exception for Reporter related stuff."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message
-    __str__ = __repr__
+from pykota.errors import PyKotaReporterError
     
 class BaseReporter :    
Index: /pykota/trunk/pykota/storage.py
===================================================================
--- /pykota/trunk/pykota/storage.py (revision 3276)
+++ /pykota/trunk/pykota/storage.py (revision 3288)
@@ -27,14 +27,6 @@
 from mx import DateTime
 
-class PyKotaStorageError(Exception):
-    """An exception for database related stuff."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message
-    __str__ = __repr__
-        
-        
+from pykota.errors import PyKotaStorageError
+
 class StorageObject :
     """Object present in the database."""
Index: /pykota/trunk/pykota/config.py
===================================================================
--- /pykota/trunk/pykota/config.py (revision 3284)
+++ /pykota/trunk/pykota/config.py (revision 3288)
@@ -27,13 +27,6 @@
 import ConfigParser
 
-class PyKotaConfigError(Exception):
-    """An exception for PyKota config related stuff."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message
-    __str__ = __repr__
-    
+from pykota.errors import PyKotaConfigError    
+
 class PyKotaConfig :
     """A class to deal with PyKota's configuration."""
Index: /pykota/trunk/pykota/cups.py
===================================================================
--- /pykota/trunk/pykota/cups.py (revision 3275)
+++ /pykota/trunk/pykota/cups.py (revision 3288)
@@ -22,5 +22,5 @@
 """This module implements some CUPS specific classes."""
 
-from pykota.tool import PyKotaToolError
+from pykota.errors import PyKotaToolError
 try :
     from pkipplib import pkipplib
Index: /pykota/trunk/pykota/errors.py
===================================================================
--- /pykota/trunk/pykota/errors.py (revision 3288)
+++ /pykota/trunk/pykota/errors.py (revision 3288)
@@ -0,0 +1,67 @@
+# -*- coding: UTF-8 -*-
+#
+# PyKota : Print Quotas for CUPS
+#
+# (c) 2003, 2004, 2005, 2006, 2007, 2008 Jerome Alet <alet@librelogiciel.com>
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id$
+#
+
+"""This module defines ALL PyKota specific exceptions."""
+
+class PyKotaError(Exception) :
+    """Mother class of all PyKota exceptions."""
+    def __init__(self, value) :
+        """Saves the value passed as a parameter."""
+        self.value = value
+        
+    def __str__(self) :    
+        """Returns an unicode string representation."""
+        try :
+            return unicode(self.value, errors="replace")
+        except TypeError :    
+            return unicode(self.value) # None and strings which are already unicode
+        
+class PyKotaToolError(PyKotaError) :
+    """PyKota Exception for all executables."""
+    pass
+    
+class PyKotaToolError(PyKotaError) :
+    """PyKota Exception for all executables."""
+    pass
+    
+class PyKotaCommandLineError(PyKotaToolError) :
+    """PyKota Exception for errors on executables' command line."""
+    pass
+    
+class PyKotaStorageError(PyKotaError) :
+    """PyKota Exception for database backend related errors."""
+    pass
+    
+class PyKotaConfigError(PyKotaError) :
+    """PyKota Exception for errors in PyKota's configuration."""
+    pass
+    
+class PyKotaAccounterError(PyKotaError) :
+    """PyKota Exception for errors in PyKota accounters."""
+    pass
+    
+class PyKotaReporterError(PyKotaError) :
+    """PyKota Exception for errors in PyKota report generators."""
+    pass
+    
+class PyKotaLoggingError(PyKotaError) :
+    """PyKota Exception for errors in PyKota logging."""
+    pass
Index: /pykota/trunk/pykota/tool.py
===================================================================
--- /pykota/trunk/pykota/tool.py (revision 3287)
+++ /pykota/trunk/pykota/tool.py (revision 3288)
@@ -39,4 +39,5 @@
 from mx import DateTime
 
+from pykota.errors import PyKotaCommandLineError
 from pykota import config, storage, logger
 from pykota.version import __version__, __author__, __years__, __gplblurb__
@@ -46,17 +47,4 @@
     return message
 
-class PyKotaToolError(Exception):
-    """An exception for PyKota related stuff."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message.encode(sys.stdout.encoding or "UTF-8", "replace")
-    __str__ = __repr__
-    
-class PyKotaCommandLineError(PyKotaToolError) :    
-    """An exception for Pykota command line tools."""
-    pass
-    
 def crashed(message="Bug in PyKota") :    
     """Minimal crash method."""
Index: /pykota/trunk/pykota/logger.py
===================================================================
--- /pykota/trunk/pykota/logger.py (revision 3275)
+++ /pykota/trunk/pykota/logger.py (revision 3288)
@@ -26,12 +26,5 @@
 import imp
 
-class PyKotaLoggingError(Exception):
-    """An exception for logging related stuff."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message
-    __str__ = __repr__
+from pykota.errors import PyKotaLoggingError
 
 def openLogger(backend) :
Index: /pykota/trunk/pykota/accounters/software.py
===================================================================
--- /pykota/trunk/pykota/accounters/software.py (revision 3285)
+++ /pykota/trunk/pykota/accounters/software.py (revision 3288)
@@ -21,7 +21,11 @@
 #
 
+"""This module handles software page counting for PyKota."""
+
 import os
 import popen2
-from pykota.accounter import AccounterBase, PyKotaAccounterError
+
+from pykota.errors import PyKotaAccounterError
+from pykota.accounter import AccounterBase
 
 class Accounter(AccounterBase) :
Index: /pykota/trunk/pykota/accounters/hardware.py
===================================================================
--- /pykota/trunk/pykota/accounters/hardware.py (revision 3275)
+++ /pykota/trunk/pykota/accounters/hardware.py (revision 3288)
@@ -25,5 +25,6 @@
 import popen2
 
-from pykota.accounter import AccounterBase, PyKotaAccounterError
+from pykota.errors import PyKotaAccounterError
+from pykota.accounter import AccounterBase
 from pykota.accounters import snmp, pjl
 
Index: /pykota/trunk/pykota/accounters/ink.py
===================================================================
--- /pykota/trunk/pykota/accounters/ink.py (revision 3275)
+++ /pykota/trunk/pykota/accounters/ink.py (revision 3288)
@@ -21,7 +21,10 @@
 #
 
+"""This module handles ink accounting in PyKota."""
+
 import os
-from pykota.accounter import AccounterBase, PyKotaAccounterError
 
+from pykota.errors import PyKotaAccounterError
+from pykota.accounter import AccounterBase
 
 class Accounter(AccounterBase) :
@@ -50,5 +53,5 @@
         colorspace = colorspace.lower()
         if colorspace not in ("cmyk", "bw", "cmy", "rgb", "gc") :
-            raise PyKotaAccounterError, "Invalid parameters for ink accounter : [%s]" % self.arguments
+            raise PyKotaAccounterError, _("Invalid parameters for ink accounter : [%s]") % self.arguments
             
         try :    
Index: /pykota/trunk/pykota/accounter.py
===================================================================
--- /pykota/trunk/pykota/accounter.py (revision 3275)
+++ /pykota/trunk/pykota/accounter.py (revision 3288)
@@ -27,13 +27,6 @@
 import imp
 
-class PyKotaAccounterError(Exception):
-    """An exception for Accounter related stuff."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message
-    __str__ = __repr__
-    
+from pykota.errors import PyKotaAccounterError
+
 class AccounterBase :    
     """A class to account print usage by querying printers."""
Index: /pykota/trunk/bin/edpykota
===================================================================
--- /pykota/trunk/bin/edpykota (revision 3275)
+++ /pykota/trunk/bin/edpykota (revision 3288)
@@ -24,5 +24,6 @@
 import sys
 
-from pykota.tool import Percent, PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import Percent, PyKotaTool, crashed, N_
 from pykota.storage import StorageUserPQuota, StorageGroupPQuota
 
Index: /pykota/trunk/bin/pkinvoice
===================================================================
--- /pykota/trunk/bin/pkinvoice (revision 3276)
+++ /pykota/trunk/bin/pkinvoice (revision 3288)
@@ -33,16 +33,17 @@
     from reportlab.lib.units import cm
 except ImportError :    
-    hasRL = 0
+    hasRL = False
 else :    
-    hasRL = 1
+    hasRL = True
     
 try :
     import PIL.Image 
 except ImportError :    
-    hasPIL = 0
+    hasPIL = False
 else :    
-    hasPIL = 1
-
-from pykota.tool import Percent, PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+    hasPIL = True
+
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import Percent, PyKotaTool, crashed, N_
 
 __doc__ = N_("""pkinvoice v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/pykotme
===================================================================
--- /pykota/trunk/bin/pykotme (revision 3275)
+++ /pykota/trunk/bin/pykotme (revision 3288)
@@ -26,5 +26,6 @@
 import pwd
 
-from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import PyKotaTool, crashed, N_
 from pykota.accounter import openAccounter
     
Index: /pykota/trunk/bin/pkbcodes
===================================================================
--- /pykota/trunk/bin/pkbcodes (revision 3275)
+++ /pykota/trunk/bin/pkbcodes (revision 3288)
@@ -26,5 +26,6 @@
 import pwd
 
-from pykota.tool import Percent, PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import Percent, PyKotaTool, crashed, N_
 from pykota.storage import StorageBillingCode
 
Index: /pykota/trunk/bin/pkturnkey
===================================================================
--- /pykota/trunk/bin/pkturnkey (revision 3275)
+++ /pykota/trunk/bin/pkturnkey (revision 3288)
@@ -29,5 +29,6 @@
 import signal
 
-from pykota.tool import Tool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import Tool, crashed, N_
 
 __doc__ = N_("""pkturnkey v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/pkusers
===================================================================
--- /pykota/trunk/bin/pkusers (revision 3275)
+++ /pykota/trunk/bin/pkusers (revision 3288)
@@ -26,5 +26,6 @@
 import grp
 
-from pykota.tool import Percent, PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import Percent, PyKotaTool, crashed, N_
 from pykota.storage import StorageUser, StorageGroup
 
Index: /pykota/trunk/bin/repykota
===================================================================
--- /pykota/trunk/bin/repykota (revision 3275)
+++ /pykota/trunk/bin/repykota (revision 3288)
@@ -28,5 +28,6 @@
 from mx import DateTime
 
-from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import PyKotaTool, crashed, N_
 from pykota import reporter
 
Index: /pykota/trunk/bin/warnpykota
===================================================================
--- /pykota/trunk/bin/warnpykota (revision 3275)
+++ /pykota/trunk/bin/warnpykota (revision 3288)
@@ -26,5 +26,6 @@
 import pwd
 
-from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import PyKotaTool, crashed, N_
 
 __doc__ = N_("""warnpykota v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/pkbanner
===================================================================
--- /pykota/trunk/bin/pkbanner (revision 3275)
+++ /pykota/trunk/bin/pkbanner (revision 3288)
@@ -33,16 +33,17 @@
     from reportlab.lib.units import cm
 except ImportError :    
-    hasRL = 0
+    hasRL = False
 else :    
-    hasRL = 1
+    hasRL = True
     
 try :
     import PIL.Image 
 except ImportError :    
-    hasPIL = 0
+    hasPIL = False
 else :    
-    hasPIL = 1
+    hasPIL = True
     
-from pykota.tool import Tool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import Tool, crashed, N_
 
 __doc__ = N_("""pkbanner v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/autopykota
===================================================================
--- /pykota/trunk/bin/autopykota (revision 3275)
+++ /pykota/trunk/bin/autopykota (revision 3288)
@@ -26,5 +26,6 @@
 import os
 
-from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import PyKotaTool, crashed, N_
 
 __doc__ = N_("""autopykota v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/pkprinters
===================================================================
--- /pykota/trunk/bin/pkprinters (revision 3276)
+++ /pykota/trunk/bin/pkprinters (revision 3288)
@@ -26,5 +26,6 @@
 import pwd
 
-from pykota.tool import Percent, PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import Percent, PyKotaTool, crashed, N_
 from pykota.storage import StoragePrinter
 
Index: /pykota/trunk/bin/cupspykota
===================================================================
--- /pykota/trunk/bin/cupspykota (revision 3276)
+++ /pykota/trunk/bin/cupspykota (revision 3288)
@@ -44,5 +44,6 @@
 from mx import DateTime
 
-from pykota.tool import PyKotaTool, PyKotaToolError, crashed
+from pykota.errors import PyKotaToolError
+from pykota.tool import PyKotaTool, crashed
 from pykota.accounter import openAccounter
 from pykota import cups
Index: /pykota/trunk/bin/pknotify
===================================================================
--- /pykota/trunk/bin/pknotify (revision 3276)
+++ /pykota/trunk/bin/pknotify (revision 3288)
@@ -31,9 +31,10 @@
     import PAM
 except ImportError :    
-    hasPAM = 0
+    hasPAM = False
 else :    
-    hasPAM = 1
-
-from pykota.tool import Tool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+    hasPAM = True
+
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import Tool, crashed, N_
 
 __doc__ = N_("""pknotify v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/pykosd
===================================================================
--- /pykota/trunk/bin/pykosd (revision 3275)
+++ /pykota/trunk/bin/pykosd (revision 3288)
@@ -33,5 +33,6 @@
     sys.exit(-1)
 
-from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import PyKotaTool, crashed, N_
 
 __doc__ = N_("""pykosd v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/pkmail
===================================================================
--- /pykota/trunk/bin/pkmail (revision 3275)
+++ /pykota/trunk/bin/pkmail (revision 3288)
@@ -31,5 +31,6 @@
 import email.Utils
 
-from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import PyKotaTool, crashed, N_
     
 __doc__ = N_("""pkmail v%(__version__)s (c) %(__years__)s %(__author__)s
Index: /pykota/trunk/bin/dumpykota
===================================================================
--- /pykota/trunk/bin/dumpykota (revision 3275)
+++ /pykota/trunk/bin/dumpykota (revision 3288)
@@ -24,5 +24,6 @@
 import sys
 
-from pykota.tool import PyKotaCommandLineError, crashed, N_
+from pykota.errors import PyKotaCommandLineError
+from pykota.tool import crashed, N_
 from pykota.dumper import DumPyKota
 
Index: /pykota/trunk/bin/pkrefund
===================================================================
--- /pykota/trunk/bin/pkrefund (revision 3276)
+++ /pykota/trunk/bin/pkrefund (revision 3288)
@@ -33,16 +33,17 @@
     from reportlab.lib.units import cm
 except ImportError :    
-    hasRL = 0
+    hasRL = False
 else :    
-    hasRL = 1
+    hasRL = True
     
 try :
     import PIL.Image 
 except ImportError :    
-    hasPIL = 0
+    hasPIL = False
 else :    
-    hasPIL = 1
-
-from pykota.tool import Percent, PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
+    hasPIL = True
+
+from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.tool import Percent, PyKotaTool, crashed, N_
 
 __doc__ = N_("""pkrefund v%(__version__)s (c) %(__years__)s %(__author__)s
