Index: pykota/trunk/conf/pykota.conf.sample
===================================================================
--- pykota/trunk/conf/pykota.conf.sample (revision 1055)
+++ pykota/trunk/conf/pykota.conf.sample (revision 1077)
@@ -153,4 +153,35 @@
 gracedelay: 7
 
+#
+# Poor man's threshold
+# If account balance reaches below this amount,
+# a warning message is sent by email
+#
+# If unset, default poor man's threshold is 1.0.
+# This option can only appear in the global section
+poorman: 2.0
+
+# Poor man's warning message
+# The warning message that is sent if the "poorman" value is reached
+# Again this must appear in the global section
+poorwarn: Your Print Quota account balance is low. 
+ Soon you'll not be allowed to print anymore.
+
+# Soft limit reached warning message
+# The warning message that is sent if the soft quota limit is reached
+# May appear either globally or on a per-printer basis
+softwarn: Your Print Quota Soft Limit is reached.
+ This means that you may still be allowed to print for some
+ time, but you must contact your administrator to purchase 
+ more print quota.
+ 
+# Hard limit reached error message
+# The error message that is sent if the hard quota limit is reached
+# May appear either globally or on a per-printer basis
+hardwarn: Your Print Quota Hard Limit is reached.
+ This means that you are not allowed to print anymore.
+ Please contact your administrator at root@localhost
+ as soon as possible to solve the problem.
+
 # one section per printer, or no other section at all if all options 
 # are defined globally.
Index: pykota/trunk/pykota/tool.py
===================================================================
--- pykota/trunk/pykota/tool.py (revision 1068)
+++ pykota/trunk/pykota/tool.py (revision 1077)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.45  2003/07/08 19:43:51  jalet
+# Configurable warning messages.
+# Poor man's treshold value added.
+#
 # Revision 1.44  2003/07/07 11:49:24  jalet
 # Lots of small fixes with the help of PyChecker
@@ -337,7 +341,8 @@
         printer = grouppquota.Printer
         if group.LimitBy and (group.LimitBy.lower() == "balance") : 
-            # TODO : there's no warning (no account balance soft limit)
-            if float(group.AccountBalance) <= 0.0 :
+            if group.AccountBalance <= 0.0 :
                 action = "DENY"
+            elif group.AccountBalance <= self.config.getPoorMan() :    
+                action = "WARN"
             else :    
                 action = "ALLOW"
@@ -402,7 +407,9 @@
                 self.logger.log_message(_("Unable to find user %s's account balance, applying default policy (%s) for printer %s") % (user.Name, action, printer.Name))
             else :    
-                # TODO : there's no warning (no account balance soft limit)
-                if float(user.AccountBalance or 0.0) <= 0.0 :
+                val = float(user.AccountBalance or 0.0)
+                if val <= 0.0 :
                     action = "DENY"
+                elif val <= self.config.getPoorMan() :    
+                    action = "WARN"
                 else :    
                     action = "ALLOW"
@@ -470,5 +477,5 @@
             for user in self.storage.getGroupMembers(group) :
                 if mailto in [ "BOTH", "USER" ] :
-                    self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), _("You are not allowed to print anymore because\nyour group Print Quota is exceeded on printer %s.") % printer.Name)
+                    self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), self.config.getHardWarn(printer.Name))
         elif action == "WARN" :    
             adminmessage = _("Print Quota soft limit exceeded for group %s on printer %s") % (group.Name, printer.Name)
@@ -476,7 +483,11 @@
             if mailto in [ "BOTH", "ADMIN" ] :
                 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)
+            if group.LimitBy and (group.LimitBy.lower() == "balance") : 
+                message = self.config.getPoorWarn()
+            else :     
+                message = self.config.getSoftWarn(printer.Name)
             for user in self.storage.getGroupMembers(group) :
                 if mailto in [ "BOTH", "USER" ] :
-                    self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), _("You will soon be forbidden to print anymore because\nyour group Print Quota is almost reached on printer %s.") % printer.Name)
+                    self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), message)
         return action        
         
@@ -495,5 +506,5 @@
             self.logger.log_message(adminmessage)
             if mailto in [ "BOTH", "USER" ] :
-                self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), _("You are not allowed to print anymore because\nyour Print Quota is exceeded on printer %s.") % printer.Name)
+                self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), self.config.getHardWarn(printer.Name))
             if mailto in [ "BOTH", "ADMIN" ] :
                 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)
@@ -502,5 +513,9 @@
             self.logger.log_message(adminmessage)
             if mailto in [ "BOTH", "USER" ] :
-                self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Exceeded"), _("You will soon be forbidden to print anymore because\nyour Print Quota is almost reached on printer %s.") % printer.Name)
+                if user.LimitBy and (user.LimitBy.lower() == "balance") : 
+                    message = self.config.getPoorWarn()
+                else :     
+                    message = self.config.getSoftWarn(printer.Name)
+                self.sendMessageToUser(admin, adminmail, user.Name, _("Print Quota Low"), message)
             if mailto in [ "BOTH", "ADMIN" ] :
                 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)
Index: pykota/trunk/pykota/config.py
===================================================================
--- pykota/trunk/pykota/config.py (revision 1068)
+++ pykota/trunk/pykota/config.py (revision 1077)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.32  2003/07/08 19:43:51  jalet
+# Configurable warning messages.
+# Poor man's treshold value added.
+#
 # Revision 1.31  2003/07/07 11:49:24  jalet
 # Lots of small fixes with the help of PyChecker
@@ -327,6 +331,38 @@
         try :
             return int(gd)
-        except ValueError :    
+        except (TypeError, ValueError) :    
             raise PyKotaConfigError, _("Invalid grace delay %s") % gd
+            
+    def getPoorMan(self) :    
+        """Returns the poor man's treshold."""
+        try :
+            pm = self.getGlobalOption("poorman")
+        except PyKotaConfigError :    
+            pm = 1.0
+        try :
+            return float(pm)
+        except (TypeError, ValueError) :    
+            raise PyKotaConfigError, _("Invalid poor man's treshold %s") % pm
+            
+    def getPoorWarn(self) :    
+        """Returns the poor man's warning message."""
+        try :
+            return self.getGlobalOption("poorwarn")
+        except PyKotaConfigError :    
+            return _("Your Print Quota account balance is Low.\nSoon you'll not be allowed to print anymore.\nPlease contact the Print Quota Administrator to solve the problem.")
+            
+    def getHardWarn(self, printer) :    
+        """Returns the hard limit error message."""
+        try :
+            return self.getPrinterOption(printer, "hardwarn")
+        except PyKotaConfigError :    
+            return _("You are not allowed to print anymore because\nyour Print Quota is exceeded on printer %s.") % printer
+            
+    def getSoftWarn(self, printer) :    
+        """Returns the soft limit error message."""
+        try :
+            return self.getPrinterOption(printer, "softwarn")
+        except PyKotaConfigError :    
+            return _("You will soon be forbidden to print anymore because\nyour Print Quota is almost reached on printer %s.") % printer
             
     def getDebug(self) :          
Index: pykota/trunk/pykota/version.py
===================================================================
--- pykota/trunk/pykota/version.py (revision 1068)
+++ pykota/trunk/pykota/version.py (revision 1077)
@@ -21,5 +21,5 @@
 #
 
-__version__ = "1.13_unofficial"
+__version__ = "1.14alpha1_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
Index: pykota/trunk/NEWS
===================================================================
--- pykota/trunk/NEWS (revision 1072)
+++ pykota/trunk/NEWS (revision 1077)
@@ -22,4 +22,13 @@
 PyKota NEWS :
 
+    - 1.14alpha1 :
+    
+        - Poor man's treshold included : users with a low account
+          balance (below 1.0 by default, configurable) are sent
+          a warning message.
+          
+        - All warning messages to users are now configurable.  
+          NB : Warning messages to the administrator are not.
+        
     - 1.13 :
     
Index: pykota/trunk/po/en/pykota.po
===================================================================
--- pykota/trunk/po/en/pykota.po (revision 1058)
+++ pykota/trunk/po/en/pykota.po (revision 1077)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.31  2003/07/08 19:43:50  jalet
+# Configurable warning messages.
+# Poor man's treshold value added.
+#
 # Revision 1.30  2003/07/03 11:38:44  jalet
 # Translations for pykotme added
@@ -325,77 +329,80 @@
 msgstr ""
 
+msgid "Print Quota soft limit exceeded for group %s on printer %s"
+msgstr ""
+
+msgid "Totals may be inaccurate if some users are members of several groups."
+msgstr ""
+
+msgid "Price per job: %.3f"
+msgstr ""
+
+msgid "Price per page: %.3f"
+msgstr ""
+
+msgid "Group %s not found in the PyKota Storage."
+msgstr ""
+
+msgid "Unsupported accounter backend %s"
+msgstr ""
+
+msgid "Option accounter in section %s only supports values in %s"
+msgstr ""
+
+msgid "Option requester for printer %s was not set"
+msgstr ""
+
+msgid "Using the 'stupid' accounting method is unreliable."
+msgstr ""
+
+msgid "Invalid external accounter %s for printer %s"
+msgstr ""
+
+msgid "Unable to compute job size with external accounter %s"
+msgstr ""
+
+msgid "Search for %s(%s) from %s(scope=%s) returned no answer."
+msgstr ""
+
+msgid "Problem adding LDAP entry (%s, %s)"
+msgstr ""
+
+msgid "Problem modifying LDAP entry (%s, %s)"
+msgstr ""
+
+msgid "Problem deleting LDAP entry (%s)"
+msgstr ""
+
+msgid "Impossible to add printer %s"
+msgstr ""
+
+msgid "Prototype object %s not found in Quota Storage."
+msgstr ""
+
+msgid "Impossible to send mail to %s, error %s : %s"
+msgstr ""
+
+msgid "Unsupported reporter backend %s"
+msgstr ""
+
+msgid "Unable to compute size of %s in number of pages.\n"
+msgstr ""
+
+msgid "Job size : %i pages"    
+msgstr ""
+
+msgid "Cost on printer %s : %.2f"
+msgstr ""
+
+msgid "Invalid poor man's treshold %s"
+msgstr ""
+
 msgid ""
-"You are not allowed to print anymore because\n"
-"your group Print Quota is exceeded on printer %s."
-msgstr ""
-
-msgid "Print Quota soft limit exceeded for group %s on printer %s"
-msgstr ""
-
-msgid ""
-"You will soon be forbidden to print anymore because\n"
-"your group Print Quota is almost reached on printer %s."
-msgstr ""
-
-msgid "Totals may be inaccurate if some users are members of several groups."
-msgstr ""
-
-msgid "Price per job: %.3f"
-msgstr ""
-
-msgid "Price per page: %.3f"
-msgstr ""
-
-msgid "Group %s not found in the PyKota Storage."
-msgstr ""
-
-msgid "Unsupported accounter backend %s"
-msgstr ""
-
-msgid "Option accounter in section %s only supports values in %s"
-msgstr ""
-
-msgid "Option requester for printer %s was not set"
-msgstr ""
-
-msgid "Using the 'stupid' accounting method is unreliable."
-msgstr ""
-
-msgid "Invalid external accounter %s for printer %s"
-msgstr ""
-
-msgid "Unable to compute job size with external accounter %s"
-msgstr ""
-
-msgid "Search for %s(%s) from %s(scope=%s) returned no answer."
-msgstr ""
-
-msgid "Problem adding LDAP entry (%s, %s)"
-msgstr ""
-
-msgid "Problem modifying LDAP entry (%s, %s)"
-msgstr ""
-
-msgid "Problem deleting LDAP entry (%s)"
-msgstr ""
-
-msgid "Impossible to add printer %s"
-msgstr ""
-
-msgid "Prototype object %s not found in Quota Storage."
-msgstr ""
-
-msgid "Impossible to send mail to %s, error %s : %s"
-msgstr ""
-
-msgid "Unsupported reporter backend %s"
-msgstr ""
-
-msgid "Unable to compute size of %s in number of pages.\n"
-msgstr ""
-
-msgid "Job size : %i pages"    
-msgstr ""
-
-msgid "Cost on printer %s : %.2f"
-msgstr ""
+"Your Print Quota account balance is Low.\n"
+"Soon you'll not be allowed to print anymore.\n"
+"Please contact the Print Quota Administrator to solve the problem."
+msgstr ""
+
+msgid "Print Quota Low"
+msgstr ""
+
Index: pykota/trunk/po/fr/pykota.po
===================================================================
--- pykota/trunk/po/fr/pykota.po (revision 1058)
+++ pykota/trunk/po/fr/pykota.po (revision 1077)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.30  2003/07/08 19:43:51  jalet
+# Configurable warning messages.
+# Poor man's treshold value added.
+#
 # Revision 1.29  2003/07/03 11:38:44  jalet
 # Translations for pykotme added
@@ -334,20 +338,6 @@
 msgstr "D�ssement de Quota d'impression pour le groupe %s sur l'imprimante %s"
 
-msgid ""
-"You are not allowed to print anymore because\n"
-"your group Print Quota is exceeded on printer %s."
-msgstr ""
-"Vous n'�s plus autoris� imprimer car\n"
-"le Quota d'Impression de votre groupe est d�ss�ur l'imprimante %s."
-
 msgid "Print Quota soft limit exceeded for group %s on printer %s"
 msgstr "Limite souple de Quota d'Impression d�ss�pour le groupe %s sur l'imprimante %s"
-
-msgid ""
-"You will soon be forbidden to print anymore because\n"
-"your group Print Quota is almost reached on printer %s."
-msgstr ""
-"Vous n'aurez bient�lus le droit d'imprimer car\n"
-"le Quota d'Impression de votre groupe sur l'imprimante %s est presque atteint."
 
 msgid "Totals may be inaccurate if some users are members of several groups."
@@ -411,2 +401,18 @@
 msgid "Cost on printer %s : %.2f"
 msgstr "Co�r l'imprimante %s : %.2f"
+
+msgid "Invalid poor man's treshold %s"
+msgstr "Valeur 'pauvre homme' %s invalide"
+
+msgid ""
+"Your Print Quota account balance is Low.\n"
+"Soon you'll not be allowed to print anymore.\n"
+"Please contact the Print Quota Administrator to solve the problem."
+msgstr ""
+"Le montant de votre compte d'impression est Bas.\n"
+"Bient�ous ne serez plus autoris�) �mprimer.\n"
+"Merci de contacter l'Administrateur de Quota d'Impression pour r�udre ce probl�."
+
+msgid "Print Quota Low"
+msgstr "Quota d'Impression Bas"
+
Index: pykota/trunk/po/pykota.pot
===================================================================
--- pykota/trunk/po/pykota.pot (revision 1058)
+++ pykota/trunk/po/pykota.pot (revision 1077)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.31  2003/07/08 19:43:50  jalet
+# Configurable warning messages.
+# Poor man's treshold value added.
+#
 # Revision 1.30  2003/07/03 11:38:43  jalet
 # Translations for pykotme added
@@ -325,77 +329,80 @@
 msgstr ""
 
+msgid "Print Quota soft limit exceeded for group %s on printer %s"
+msgstr ""
+
+msgid "Totals may be inaccurate if some users are members of several groups."
+msgstr ""
+
+msgid "Price per job: %.3f"
+msgstr ""
+
+msgid "Price per page: %.3f"
+msgstr ""
+
+msgid "Group %s not found in the PyKota Storage."
+msgstr ""
+
+msgid "Unsupported accounter backend %s"
+msgstr ""
+
+msgid "Option accounter in section %s only supports values in %s"
+msgstr ""
+
+msgid "Option requester for printer %s was not set"
+msgstr ""
+
+msgid "Using the 'stupid' accounting method is unreliable."
+msgstr ""
+
+msgid "Invalid external accounter %s for printer %s"
+msgstr ""
+
+msgid "Unable to compute job size with external accounter %s"
+msgstr ""
+
+msgid "Search for %s(%s) from %s(scope=%s) returned no answer."
+msgstr ""
+
+msgid "Problem adding LDAP entry (%s, %s)"
+msgstr ""
+
+msgid "Problem modifying LDAP entry (%s, %s)"
+msgstr ""
+
+msgid "Problem deleting LDAP entry (%s)"
+msgstr ""
+
+msgid "Impossible to add printer %s"
+msgstr ""
+
+msgid "Prototype object %s not found in Quota Storage."
+msgstr ""
+
+msgid "Impossible to send mail to %s, error %s : %s"
+msgstr ""
+
+msgid "Unsupported reporter backend %s"
+msgstr ""
+
+msgid "Unable to compute size of %s in number of pages.\n"
+msgstr ""
+
+msgid "Job size : %i pages"    
+msgstr ""
+
+msgid "Cost on printer %s : %.2f"
+msgstr ""
+
+msgid "Invalid poor man's treshold %s"
+msgstr ""
+
 msgid ""
-"You are not allowed to print anymore because\n"
-"your group Print Quota is exceeded on printer %s."
-msgstr ""
-
-msgid "Print Quota soft limit exceeded for group %s on printer %s"
-msgstr ""
-
-msgid ""
-"You will soon be forbidden to print anymore because\n"
-"your group Print Quota is almost reached on printer %s."
-msgstr ""
-
-msgid "Totals may be inaccurate if some users are members of several groups."
-msgstr ""
-
-msgid "Price per job: %.3f"
-msgstr ""
-
-msgid "Price per page: %.3f"
-msgstr ""
-
-msgid "Group %s not found in the PyKota Storage."
-msgstr ""
-
-msgid "Unsupported accounter backend %s"
-msgstr ""
-
-msgid "Option accounter in section %s only supports values in %s"
-msgstr ""
-
-msgid "Option requester for printer %s was not set"
-msgstr ""
-
-msgid "Using the 'stupid' accounting method is unreliable."
-msgstr ""
-
-msgid "Invalid external accounter %s for printer %s"
-msgstr ""
-
-msgid "Unable to compute job size with external accounter %s"
-msgstr ""
-
-msgid "Search for %s(%s) from %s(scope=%s) returned no answer."
-msgstr ""
-
-msgid "Problem adding LDAP entry (%s, %s)"
-msgstr ""
-
-msgid "Problem modifying LDAP entry (%s, %s)"
-msgstr ""
-
-msgid "Problem deleting LDAP entry (%s)"
-msgstr ""
-
-msgid "Impossible to add printer %s"
-msgstr ""
-
-msgid "Prototype object %s not found in Quota Storage."
-msgstr ""
-
-msgid "Impossible to send mail to %s, error %s : %s"
-msgstr ""
-
-msgid "Unsupported reporter backend %s"
-msgstr ""
-
-msgid "Unable to compute size of %s in number of pages.\n"
-msgstr ""
-
-msgid "Job size : %i pages"    
-msgstr ""
-
-msgid "Cost on printer %s : %.2f"
-msgstr ""
+"Your Print Quota account balance is Low.\n"
+"Soon you'll not be allowed to print anymore.\n"
+"Please contact the Print Quota Administrator to solve the problem."
+msgstr ""
+
+msgid "Print Quota Low"
+msgstr ""
+
