Index: /pykota/trunk/conf/pykota.conf.sample
===================================================================
--- /pykota/trunk/conf/pykota.conf.sample (revision 1915)
+++ /pykota/trunk/conf/pykota.conf.sample (revision 1923)
@@ -638,6 +638,8 @@
 # this command in a pipe through GhostScript if your printer doesn't 
 # accept PostScript as an input format.
-#
-# startingbanner: /usr/share/pykota/banner-page.sh
+# NB : pkbanner's default page size is A4
+#
+# startingbanner: /usr/bin/pkbanner --pagesize=A4 --logo="/home/joe/mylogo.jpeg" --url="http://tech.example.com"
+# startingbanner: /usr/bin/pkbanner
 
 # EndingBanner : if defined will print a banner before the rest of the job 
@@ -655,6 +657,8 @@
 # this command in a pipe through GhostScript if your printer doesn't 
 # accept PostScript as an input format.
-#
-# endingbanner: /usr/share/pykota/banner-page.sh
+# NB : pkbanner's default page size is A4
+#
+# endingbanner: /usr/bin/pkbanner --pagesize=A4 --logo="/home/joe/mylogo.jpeg" --url="http://tech.example.com"
+# endingbanner: /usr/bin/pkbanner
 
 # How should enforcement be done for this printer ?
Index: /pykota/trunk/CREDITS
===================================================================
--- /pykota/trunk/CREDITS (revision 1888)
+++ /pykota/trunk/CREDITS (revision 1923)
@@ -143,4 +143,5 @@
   - Beda Szukics - Kantonsschule Obwalden - German translation
   - Klaus Ade Johnstad - SkoleLinux - Norwegian Bokm�translation
+  - Matt Hyclak - Wrote the banner handling stuff.
 
 ==============================================================
Index: /pykota/trunk/bin/pkbanner
===================================================================
--- /pykota/trunk/bin/pkbanner (revision 1918)
+++ /pykota/trunk/bin/pkbanner (revision 1923)
@@ -24,4 +24,8 @@
 #
 # $Log$
+# Revision 1.5  2004/11/15 22:01:34  jalet
+# Improved banner handling.
+# Fix for raw printing and banners.
+#
 # Revision 1.4  2004/11/15 19:59:34  jalet
 # PyKota banners now basically work !
@@ -41,4 +45,5 @@
 import sys
 import os
+import time
 import cStringIO
 import popen2
@@ -75,9 +80,27 @@
   -h | --help          Prints this message then exits.
   
-  ... TODO...
+  -d | --darkness d    Sets the darkness to d%%. This can be used to
+                       save toner. The default value is 100.
+                       NOT IMPLEMENTED YET.
+  
+  -p | --pagesize sz   Sets sz as the page size. Most well known
+                       page sizes are recognized, like 'A4' or 'Letter'
+                       to name a few.
+  
+  -l | --logo img      Use the image as the banner's logo. The logo will
+                       be drawn at the top center of the page. The default
+                       logo is /usr/share/pykota/logos/pykota.jpeg
+                       
+  -u | --url u         Uses u as an url to be written at the bottom of 
+                       the banner page. The default url is :
+                       http://www.librelogiciel.com/software/
   
 examples :                              
 
-  ... TODO...
+  Using pkbanner directly from the command line is not recommended,
+  excepted for testing purposes. You should use pkbanner in the
+  'startingbanner' or 'endingbanner' directives in pykota.conf
+  
+  For this reason, there's no example.
 
 This program is free software; you can redistribute it and/or modify
@@ -101,5 +124,4 @@
     primaryfields = [ 
                 ("PRINTERNAME", N_("Printer")),
-                ("USERNAME", N_("User")),
                 ("JOBID", N_("JobId")),
                 ("JOBORIGINATINGHOSTNAME", N_("Client host")),
@@ -135,6 +157,29 @@
                 pass
                 
-    def genPDF(self, pagesize, logo, url) :            
+    def getVar(self, varname) :            
+        """Extracts a variable from the environment and returns its value or 'Unknown' in the current locale."""
+        return os.environ.get(varname) or _("Unknown")
+        
+    def printVar(self, canvas, x, y, label, value, size, darkness) :
+        """Outputs a variable onto the PDF canvas.
+        
+           Returns the number of points to substract to current Y coordinate.
+        """   
+        canvas.saveState()
+        canvas.setFont("Helvetica-Bold", size)
+        (r, g, b) =  (0, 0, 0)  # Black : TODO : darkness
+        canvas.setFillColorRGB(r, g, b)
+        message = "%s :" % _(label).title()
+        canvas.drawRightString(x, y, message)
+        canvas.setFont("Courier-Bold", size)
+        (r, g, b) = (1, 0, 0)   # Red : TODO : darkness
+        canvas.setFillColorRGB(r, g, b)
+        canvas.drawString(x + 0.5*cm, y, value)
+        canvas.restoreState()
+        return (size + 4)
+    
+    def genPDF(self, pagesize, logo, url, darkness) :
         """Generates the banner in PDF format, return the PDF document as a string."""
+        
         document = cStringIO.StringIO()
         c = canvas.Canvas(document, pagesize=pagesize, pageCompression=1)
@@ -148,16 +193,18 @@
                     
         ypos = pagesize[1] - (2 * cm)            
-        try :    
-            imglogo = PIL.Image.open(logo)
-        except :    
-            self.printInfo("Unable to open image %s" % logo, "warn")
-        else :
-            (width, height) = imglogo.size
-            multi = float(width) / (8 * cm) 
-            width = float(width) / multi
-            height = float(height) / multi
-            xpos = xcenter - (width / 2.0)
-            ypos -= height
-            c.drawImage(logo, xpos, ypos, width, height)
+        
+        if logo :
+            try :    
+                imglogo = PIL.Image.open(logo)
+            except :    
+                self.printInfo("Unable to open image %s" % logo, "warn")
+            else :
+                (width, height) = imglogo.size
+                multi = float(width) / (8 * cm) 
+                width = float(width) / multi
+                height = float(height) / multi
+                xpos = xcenter - (width / 2.0)
+                ypos -= height
+                c.drawImage(logo, xpos, ypos, width, height)
         
         # New top
@@ -165,29 +212,65 @@
         ypos -= (1 * cm) + 20
         
-        for fieldsgroup in [ self.primaryfields, self.secondaryfields, self.tertiaryfields] :
+        printername = self.getVar("PYKOTAPRINTERNAME")
+        username = self.getVar("PYKOTAUSERNAME")
+        accountbanner = self.config.getAccountBanner(printername)
+        
+        # Outputs the username
+        ypos -= self.printVar(c, xcenter, ypos, _("Username"), username, 20, darkness) 
+        
+        # Printer and Job Id
+        job = "%s - %s" % (printername, self.getVar("PYKOTAJOBID"))
+        ypos -= self.printVar(c, xcenter, ypos, _("Job"), job, 14, darkness) 
+        
+        # Current date (TODO : at the time the banner was printed ! Change this to job's submission date)
+        datetime = time.strftime("%c", time.localtime())
+        ypos -= self.printVar(c, xcenter, ypos, _("Date"), datetime, 14, darkness) 
+        
+        # Result of the print job
+        action = self.getVar("PYKOTAACTION")
+        if action == "ALLOW" :
+            action = _("Allowed")
+        elif action == "DENY" :    
+            action = _("Denied")
+        elif action == "WARN" :    
+            action = _("Allowed with Warning")
+        ypos -= self.printVar(c, xcenter, ypos, _("Result"), action, 14, darkness) 
+        
+        # skip some space
+        ypos -= 20
+        
+        # Outputs title and filename
+        title = self.getVar("PYKOTATITLE")
+        ypos -= self.printVar(c, xcenter, ypos, _("Title"), title, 10, darkness) 
+        
+        filename = self.getVar("PYKOTAFILENAME")
+        ypos -= self.printVar(c, xcenter, ypos, _("Filename"), filename, 10, darkness) 
+        
+        # skip some space
+        ypos -= 20
+        
+        # Now outputs the user's account balance or page counter
+        ypos -= self.printVar(c, xcenter, ypos, _("Pages printed on %s") % printername, self.getVar("PYKOTAPAGECOUNTER"), 14, darkness) 
+        limitby = self.getVar("PYKOTALIMITBY")
+        if limitby == "balance" :  
+            ypos -= self.printVar(c, xcenter, ypos, _("Account balance"), self.getVar("PYKOTABALANCE"), 14, darkness) 
+        else :
+            ypos -= self.printVar(c, xcenter, ypos, _("Soft Limit"), self.getVar("PYKOTASOFTLIMIT"), 14, darkness) 
+            ypos -= self.printVar(c, xcenter, ypos, _("Hard Limit"), self.getVar("PYKOTAHARDLIMIT"), 14, darkness) 
+            ypos -= self.printVar(c, xcenter, ypos, _("Date Limit"), self.getVar("PYKOTADATELIMIT"), 14, darkness) 
+            
+        # URL
+        if url :
             c.saveState()
-            for (varname, label) in fieldsgroup :
-                c.setFont("Helvetica-Bold", 14)
-                c.setFillColorRGB(0, 0, 0)
-                message = "%s :" % _(label).title()
-                c.drawRightString(xcenter, ypos, message)
-                c.setFont("Courier-Bold", 14)
-                c.setFillColorRGB(1, 0, 0)
-                c.drawString(xcenter + 0.5*cm, ypos, os.environ.get("PYKOTA%s" % varname, _("Unknown")))
-                ypos -= 18  # next line
+            c.setFont("Courier-Bold", 16)
+            (r, g, b) = (0, 0, 1)   # Blue : TODO : darkness
+            c.setFillColorRGB(r, g, b)
+            c.drawCentredString(xcenter, 2 * cm, url)
             c.restoreState()
-            ypos -= 18      # skip an additionnal line
-        
-        # URL
-        c.saveState()
-        c.setFont("Courier-Bold", 16)
-        c.setFillColorRGB(0, 0, 1)
-        c.drawCentredString(xcenter, 2 * cm, url)
-        c.restoreState()
         
         c.showPage()
         c.save()
         return document.getvalue()
-    
+        
     def main(self, files, options) :
         """Generates a banner."""
@@ -197,4 +280,13 @@
             raise PyKotaToolError, "The Python Imaging Library is missing. Download it from http://www.pythonware.com/downloads"
             
+        try :
+            darkness = int(options["darkness"])
+            if (darkness <= 0) or (darkness > 100) :
+                raise ValueError, "Allowed range is (1..100)"
+            darkness /= 100.0    
+        except (TypeError, ValueError), msg :
+            self.printInfo("Invalid darkness value %s : %s" % (options["darkness"], msg), "warn")
+            darkness = 1.0
+            
         pagesize = self.getPageSize(options["pagesize"])
         if pagesize is None :
@@ -203,5 +295,5 @@
             
         self.logdebug("Generating the banner in PDF format...")    
-        doc = self.genPDF(pagesize, options["logo"], options["url"].strip())
+        doc = self.genPDF(pagesize, options["logo"].strip(), options["url"].strip(), darkness)
         
         self.logdebug("Converting the banner to PostScript...")    
@@ -229,10 +321,11 @@
     try :
         defaults = { \
+                     "darkness" : "100", \
                      "pagesize" : "a4", \
                      "logo" : "/usr/share/pykota/logos/pykota.jpeg",
                      "url" : "http://www.librelogiciel.com/software/",
                    }
-        short_options = "vhl:p:u:"
-        long_options = ["help", "version", "pagesize=", "logo=", "url="]
+        short_options = "vhd:l:p:u:"
+        long_options = ["help", "version", "darkness=", "pagesize=", "logo=", "url="]
         
         # Initializes the command line tool
@@ -245,4 +338,5 @@
         options["help"] = options["h"] or options["help"]
         options["version"] = options["v"] or options["version"]
+        options["darkness"] = options["d"] or options["darkness"] or defaults["darkness"]
         options["pagesize"] = options["p"] or options["pagesize"] or defaults["pagesize"]
         options["logo"] = options["l"] or options["logo"] or defaults["logo"]
Index: /pykota/trunk/bin/cupspykota
===================================================================
--- /pykota/trunk/bin/cupspykota (revision 1918)
+++ /pykota/trunk/bin/cupspykota (revision 1923)
@@ -24,4 +24,8 @@
 #
 # $Log$
+# Revision 1.79  2004/11/15 22:01:34  jalet
+# Improved banner handling.
+# Fix for raw printing and banners.
+#
 # Revision 1.78  2004/11/15 19:59:34  jalet
 # PyKota banners now basically work !
@@ -526,11 +530,4 @@
             self.printMoreInfo(user, printer, _("Job accounting ends."))
                 
-            # handle ending banner pages after accounting ends
-            if accountbanner in ["STARTING", "NONE"] :
-                banner = self.endingBanner(printer.Name)
-                if banner :
-                    self.logdebug("Printing ending banner after accounting ends.")
-                    self.handleData(banner)
- 
             # retrieve the job size    
             if action == "DENY" :
@@ -555,4 +552,11 @@
             # then re-export user information with new value
             self.exportUserInfo(userpquota)
+            
+            # handle ending banner pages after accounting ends
+            if accountbanner in ["STARTING", "NONE"] :
+                banner = self.endingBanner(printer.Name)
+                if banner :
+                    self.logdebug("Printing ending banner after accounting ends.")
+                    self.handleData(banner)
             
             # Launches the post hook
@@ -595,6 +599,11 @@
         
         # And launch it
-        self.logdebug("Starting real backend %s with args %s" % (realbackend, " ".join(['"%s"' % a for a in ([os.environ["DEVICE_URI"]] + sys.argv[1:])])))
-        subprocess = PyKotaPopen4([realbackend] + sys.argv[1:], bufsize=0, arg0=os.environ["DEVICE_URI"])
+        if filehandle is None :
+            arguments = sys.argv
+        else :    
+            # Here we absolutely WANT to remove any filename from the command line !
+            arguments = [ "Fake this because we are printing a banner" ] + sys.argv[1:6]
+        self.logdebug("Starting real backend %s with args %s" % (realbackend, " ".join(['"%s"' % a for a in ([os.environ["DEVICE_URI"]] + arguments)])))
+        subprocess = PyKotaPopen4([realbackend] + arguments, bufsize=0, arg0=os.environ["DEVICE_URI"])
         
         # Save file descriptors, we will need them later.
Index: /pykota/trunk/NEWS
===================================================================
--- /pykota/trunk/NEWS (revision 1913)
+++ /pykota/trunk/NEWS (revision 1923)
@@ -22,4 +22,11 @@
 PyKota NEWS :
 
+    - 1.21alpha3 :
+    
+        - PyKota can now generate its own banners, and either account
+          for them or not, depending on newly introduced directives
+          in pykota.conf
+          Thanks to Matt Hyclak for the patch.
+          
     - 1.21alpha2 :
     
Index: /pykota/trunk/pykota/tool.py
===================================================================
--- /pykota/trunk/pykota/tool.py (revision 1918)
+++ /pykota/trunk/pykota/tool.py (revision 1923)
@@ -22,4 +22,8 @@
 #
 # $Log$
+# Revision 1.141  2004/11/15 22:01:34  jalet
+# Improved banner handling.
+# Fix for raw printing and banners.
+#
 # Revision 1.140  2004/11/15 19:59:34  jalet
 # PyKota banners now basically work !
@@ -626,5 +630,8 @@
     def display_version_and_quit(self) :
         """Displays version number, then exists successfully."""
-        self.clean()
+        try :
+            self.clean()
+        except AttributeError :    
+            pass
         print version.__version__
         sys.exit(0)
@@ -632,5 +639,8 @@
     def display_usage_and_quit(self) :
         """Displays command line usage, then exists successfully."""
-        self.clean()
+        try :
+            self.clean()
+        except AttributeError :    
+            pass
         print _(self.documentation) % (version.__version__, version.__author__)
         sys.exit(0)
Index: /pykota/trunk/pykota/version.py
===================================================================
--- /pykota/trunk/pykota/version.py (revision 1905)
+++ /pykota/trunk/pykota/version.py (revision 1923)
@@ -22,5 +22,5 @@
 #
 
-__version__ = "1.21alpha2_unofficial"
+__version__ = "1.21alpha3_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
