Changeset 1923

Show
Ignore:
Timestamp:
11/15/04 23:01:34 (19 years ago)
Author:
jalet
Message:

Improved banner handling.
Fix for raw printing and banners.

Location:
pykota/trunk
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/cupspykota

    r1918 r1923  
    2424# 
    2525# $Log$ 
     26# Revision 1.79  2004/11/15 22:01:34  jalet 
     27# Improved banner handling. 
     28# Fix for raw printing and banners. 
     29# 
    2630# Revision 1.78  2004/11/15 19:59:34  jalet 
    2731# PyKota banners now basically work ! 
     
    526530            self.printMoreInfo(user, printer, _("Job accounting ends.")) 
    527531                 
    528             # handle ending banner pages after accounting ends 
    529             if accountbanner in ["STARTING", "NONE"] : 
    530                 banner = self.endingBanner(printer.Name) 
    531                 if banner : 
    532                     self.logdebug("Printing ending banner after accounting ends.") 
    533                     self.handleData(banner) 
    534   
    535532            # retrieve the job size     
    536533            if action == "DENY" : 
     
    555552            # then re-export user information with new value 
    556553            self.exportUserInfo(userpquota) 
     554             
     555            # handle ending banner pages after accounting ends 
     556            if accountbanner in ["STARTING", "NONE"] : 
     557                banner = self.endingBanner(printer.Name) 
     558                if banner : 
     559                    self.logdebug("Printing ending banner after accounting ends.") 
     560                    self.handleData(banner) 
    557561             
    558562            # Launches the post hook 
     
    595599         
    596600        # And launch it 
    597         self.logdebug("Starting real backend %s with args %s" % (realbackend, " ".join(['"%s"' % a for a in ([os.environ["DEVICE_URI"]] + sys.argv[1:])]))) 
    598         subprocess = PyKotaPopen4([realbackend] + sys.argv[1:], bufsize=0, arg0=os.environ["DEVICE_URI"]) 
     601        if filehandle is None : 
     602            arguments = sys.argv 
     603        else :     
     604            # Here we absolutely WANT to remove any filename from the command line ! 
     605            arguments = [ "Fake this because we are printing a banner" ] + sys.argv[1:6] 
     606        self.logdebug("Starting real backend %s with args %s" % (realbackend, " ".join(['"%s"' % a for a in ([os.environ["DEVICE_URI"]] + arguments)]))) 
     607        subprocess = PyKotaPopen4([realbackend] + arguments, bufsize=0, arg0=os.environ["DEVICE_URI"]) 
    599608         
    600609        # Save file descriptors, we will need them later. 
  • pykota/trunk/bin/pkbanner

    r1918 r1923  
    2424# 
    2525# $Log$ 
     26# Revision 1.5  2004/11/15 22:01:34  jalet 
     27# Improved banner handling. 
     28# Fix for raw printing and banners. 
     29# 
    2630# Revision 1.4  2004/11/15 19:59:34  jalet 
    2731# PyKota banners now basically work ! 
     
    4145import sys 
    4246import os 
     47import time 
    4348import cStringIO 
    4449import popen2 
     
    7580  -h | --help          Prints this message then exits. 
    7681   
    77   ... TODO... 
     82  -d | --darkness d    Sets the darkness to d%%. This can be used to 
     83                       save toner. The default value is 100. 
     84                       NOT IMPLEMENTED YET. 
     85   
     86  -p | --pagesize sz   Sets sz as the page size. Most well known 
     87                       page sizes are recognized, like 'A4' or 'Letter' 
     88                       to name a few. 
     89   
     90  -l | --logo img      Use the image as the banner's logo. The logo will 
     91                       be drawn at the top center of the page. The default 
     92                       logo is /usr/share/pykota/logos/pykota.jpeg 
     93                        
     94  -u | --url u         Uses u as an url to be written at the bottom of  
     95                       the banner page. The default url is : 
     96                       http://www.librelogiciel.com/software/ 
    7897   
    7998examples :                               
    8099 
    81   ... TODO... 
     100  Using pkbanner directly from the command line is not recommended, 
     101  excepted for testing purposes. You should use pkbanner in the 
     102  'startingbanner' or 'endingbanner' directives in pykota.conf 
     103   
     104  For this reason, there's no example. 
    82105 
    83106This program is free software; you can redistribute it and/or modify 
     
    101124    primaryfields = [  
    102125                ("PRINTERNAME", N_("Printer")), 
    103                 ("USERNAME", N_("User")), 
    104126                ("JOBID", N_("JobId")), 
    105127                ("JOBORIGINATINGHOSTNAME", N_("Client host")), 
     
    135157                pass 
    136158                 
    137     def genPDF(self, pagesize, logo, url) :             
     159    def getVar(self, varname) :             
     160        """Extracts a variable from the environment and returns its value or 'Unknown' in the current locale.""" 
     161        return os.environ.get(varname) or _("Unknown") 
     162         
     163    def printVar(self, canvas, x, y, label, value, size, darkness) : 
     164        """Outputs a variable onto the PDF canvas. 
     165         
     166           Returns the number of points to substract to current Y coordinate. 
     167        """    
     168        canvas.saveState() 
     169        canvas.setFont("Helvetica-Bold", size) 
     170        (r, g, b) =  (0, 0, 0)  # Black : TODO : darkness 
     171        canvas.setFillColorRGB(r, g, b) 
     172        message = "%s :" % _(label).title() 
     173        canvas.drawRightString(x, y, message) 
     174        canvas.setFont("Courier-Bold", size) 
     175        (r, g, b) = (1, 0, 0)   # Red : TODO : darkness 
     176        canvas.setFillColorRGB(r, g, b) 
     177        canvas.drawString(x + 0.5*cm, y, value) 
     178        canvas.restoreState() 
     179        return (size + 4) 
     180     
     181    def genPDF(self, pagesize, logo, url, darkness) : 
    138182        """Generates the banner in PDF format, return the PDF document as a string.""" 
     183         
    139184        document = cStringIO.StringIO() 
    140185        c = canvas.Canvas(document, pagesize=pagesize, pageCompression=1) 
     
    148193                     
    149194        ypos = pagesize[1] - (2 * cm)             
    150         try :     
    151             imglogo = PIL.Image.open(logo) 
    152         except :     
    153             self.printInfo("Unable to open image %s" % logo, "warn") 
    154         else : 
    155             (width, height) = imglogo.size 
    156             multi = float(width) / (8 * cm)  
    157             width = float(width) / multi 
    158             height = float(height) / multi 
    159             xpos = xcenter - (width / 2.0) 
    160             ypos -= height 
    161             c.drawImage(logo, xpos, ypos, width, height) 
     195         
     196        if logo : 
     197            try :     
     198                imglogo = PIL.Image.open(logo) 
     199            except :     
     200                self.printInfo("Unable to open image %s" % logo, "warn") 
     201            else : 
     202                (width, height) = imglogo.size 
     203                multi = float(width) / (8 * cm)  
     204                width = float(width) / multi 
     205                height = float(height) / multi 
     206                xpos = xcenter - (width / 2.0) 
     207                ypos -= height 
     208                c.drawImage(logo, xpos, ypos, width, height) 
    162209         
    163210        # New top 
     
    165212        ypos -= (1 * cm) + 20 
    166213         
    167         for fieldsgroup in [ self.primaryfields, self.secondaryfields, self.tertiaryfields] : 
     214        printername = self.getVar("PYKOTAPRINTERNAME") 
     215        username = self.getVar("PYKOTAUSERNAME") 
     216        accountbanner = self.config.getAccountBanner(printername) 
     217         
     218        # Outputs the username 
     219        ypos -= self.printVar(c, xcenter, ypos, _("Username"), username, 20, darkness)  
     220         
     221        # Printer and Job Id 
     222        job = "%s - %s" % (printername, self.getVar("PYKOTAJOBID")) 
     223        ypos -= self.printVar(c, xcenter, ypos, _("Job"), job, 14, darkness)  
     224         
     225        # Current date (TODO : at the time the banner was printed ! Change this to job's submission date) 
     226        datetime = time.strftime("%c", time.localtime()) 
     227        ypos -= self.printVar(c, xcenter, ypos, _("Date"), datetime, 14, darkness)  
     228         
     229        # Result of the print job 
     230        action = self.getVar("PYKOTAACTION") 
     231        if action == "ALLOW" : 
     232            action = _("Allowed") 
     233        elif action == "DENY" :     
     234            action = _("Denied") 
     235        elif action == "WARN" :     
     236            action = _("Allowed with Warning") 
     237        ypos -= self.printVar(c, xcenter, ypos, _("Result"), action, 14, darkness)  
     238         
     239        # skip some space 
     240        ypos -= 20 
     241         
     242        # Outputs title and filename 
     243        title = self.getVar("PYKOTATITLE") 
     244        ypos -= self.printVar(c, xcenter, ypos, _("Title"), title, 10, darkness)  
     245         
     246        filename = self.getVar("PYKOTAFILENAME") 
     247        ypos -= self.printVar(c, xcenter, ypos, _("Filename"), filename, 10, darkness)  
     248         
     249        # skip some space 
     250        ypos -= 20 
     251         
     252        # Now outputs the user's account balance or page counter 
     253        ypos -= self.printVar(c, xcenter, ypos, _("Pages printed on %s") % printername, self.getVar("PYKOTAPAGECOUNTER"), 14, darkness)  
     254        limitby = self.getVar("PYKOTALIMITBY") 
     255        if limitby == "balance" :   
     256            ypos -= self.printVar(c, xcenter, ypos, _("Account balance"), self.getVar("PYKOTABALANCE"), 14, darkness)  
     257        else : 
     258            ypos -= self.printVar(c, xcenter, ypos, _("Soft Limit"), self.getVar("PYKOTASOFTLIMIT"), 14, darkness)  
     259            ypos -= self.printVar(c, xcenter, ypos, _("Hard Limit"), self.getVar("PYKOTAHARDLIMIT"), 14, darkness)  
     260            ypos -= self.printVar(c, xcenter, ypos, _("Date Limit"), self.getVar("PYKOTADATELIMIT"), 14, darkness)  
     261             
     262        # URL 
     263        if url : 
    168264            c.saveState() 
    169             for (varname, label) in fieldsgroup : 
    170                 c.setFont("Helvetica-Bold", 14) 
    171                 c.setFillColorRGB(0, 0, 0) 
    172                 message = "%s :" % _(label).title() 
    173                 c.drawRightString(xcenter, ypos, message) 
    174                 c.setFont("Courier-Bold", 14) 
    175                 c.setFillColorRGB(1, 0, 0) 
    176                 c.drawString(xcenter + 0.5*cm, ypos, os.environ.get("PYKOTA%s" % varname, _("Unknown"))) 
    177                 ypos -= 18  # next line 
     265            c.setFont("Courier-Bold", 16) 
     266            (r, g, b) = (0, 0, 1)   # Blue : TODO : darkness 
     267            c.setFillColorRGB(r, g, b) 
     268            c.drawCentredString(xcenter, 2 * cm, url) 
    178269            c.restoreState() 
    179             ypos -= 18      # skip an additionnal line 
    180          
    181         # URL 
    182         c.saveState() 
    183         c.setFont("Courier-Bold", 16) 
    184         c.setFillColorRGB(0, 0, 1) 
    185         c.drawCentredString(xcenter, 2 * cm, url) 
    186         c.restoreState() 
    187270         
    188271        c.showPage() 
    189272        c.save() 
    190273        return document.getvalue() 
    191      
     274         
    192275    def main(self, files, options) : 
    193276        """Generates a banner.""" 
     
    197280            raise PyKotaToolError, "The Python Imaging Library is missing. Download it from http://www.pythonware.com/downloads" 
    198281             
     282        try : 
     283            darkness = int(options["darkness"]) 
     284            if (darkness <= 0) or (darkness > 100) : 
     285                raise ValueError, "Allowed range is (1..100)" 
     286            darkness /= 100.0     
     287        except (TypeError, ValueError), msg : 
     288            self.printInfo("Invalid darkness value %s : %s" % (options["darkness"], msg), "warn") 
     289            darkness = 1.0 
     290             
    199291        pagesize = self.getPageSize(options["pagesize"]) 
    200292        if pagesize is None : 
     
    203295             
    204296        self.logdebug("Generating the banner in PDF format...")     
    205         doc = self.genPDF(pagesize, options["logo"], options["url"].strip()) 
     297        doc = self.genPDF(pagesize, options["logo"].strip(), options["url"].strip(), darkness) 
    206298         
    207299        self.logdebug("Converting the banner to PostScript...")     
     
    229321    try : 
    230322        defaults = { \ 
     323                     "darkness" : "100", \ 
    231324                     "pagesize" : "a4", \ 
    232325                     "logo" : "/usr/share/pykota/logos/pykota.jpeg", 
    233326                     "url" : "http://www.librelogiciel.com/software/", 
    234327                   } 
    235         short_options = "vhl:p:u:" 
    236         long_options = ["help", "version", "pagesize=", "logo=", "url="] 
     328        short_options = "vhd:l:p:u:" 
     329        long_options = ["help", "version", "darkness=", "pagesize=", "logo=", "url="] 
    237330         
    238331        # Initializes the command line tool 
     
    245338        options["help"] = options["h"] or options["help"] 
    246339        options["version"] = options["v"] or options["version"] 
     340        options["darkness"] = options["d"] or options["darkness"] or defaults["darkness"] 
    247341        options["pagesize"] = options["p"] or options["pagesize"] or defaults["pagesize"] 
    248342        options["logo"] = options["l"] or options["logo"] or defaults["logo"] 
  • pykota/trunk/conf/pykota.conf.sample

    r1915 r1923  
    638638# this command in a pipe through GhostScript if your printer doesn't  
    639639# accept PostScript as an input format. 
    640 # 
    641 # startingbanner: /usr/share/pykota/banner-page.sh 
     640# NB : pkbanner's default page size is A4 
     641# 
     642# startingbanner: /usr/bin/pkbanner --pagesize=A4 --logo="/home/joe/mylogo.jpeg" --url="http://tech.example.com" 
     643# startingbanner: /usr/bin/pkbanner 
    642644 
    643645# EndingBanner : if defined will print a banner before the rest of the job  
     
    655657# this command in a pipe through GhostScript if your printer doesn't  
    656658# accept PostScript as an input format. 
    657 # 
    658 # endingbanner: /usr/share/pykota/banner-page.sh 
     659# NB : pkbanner's default page size is A4 
     660# 
     661# endingbanner: /usr/bin/pkbanner --pagesize=A4 --logo="/home/joe/mylogo.jpeg" --url="http://tech.example.com" 
     662# endingbanner: /usr/bin/pkbanner 
    659663 
    660664# How should enforcement be done for this printer ? 
  • pykota/trunk/CREDITS

    r1888 r1923  
    143143  - Beda Szukics - Kantonsschule Obwalden - German translation 
    144144  - Klaus Ade Johnstad - SkoleLinux - Norwegian Bokm�translation 
     145  - Matt Hyclak - Wrote the banner handling stuff. 
    145146 
    146147============================================================== 
  • pykota/trunk/NEWS

    r1913 r1923  
    2222PyKota NEWS : 
    2323 
     24    - 1.21alpha3 : 
     25     
     26        - PyKota can now generate its own banners, and either account 
     27          for them or not, depending on newly introduced directives 
     28          in pykota.conf 
     29          Thanks to Matt Hyclak for the patch. 
     30           
    2431    - 1.21alpha2 : 
    2532     
  • pykota/trunk/pykota/tool.py

    r1918 r1923  
    2222# 
    2323# $Log$ 
     24# Revision 1.141  2004/11/15 22:01:34  jalet 
     25# Improved banner handling. 
     26# Fix for raw printing and banners. 
     27# 
    2428# Revision 1.140  2004/11/15 19:59:34  jalet 
    2529# PyKota banners now basically work ! 
     
    626630    def display_version_and_quit(self) : 
    627631        """Displays version number, then exists successfully.""" 
    628         self.clean() 
     632        try : 
     633            self.clean() 
     634        except AttributeError :     
     635            pass 
    629636        print version.__version__ 
    630637        sys.exit(0) 
     
    632639    def display_usage_and_quit(self) : 
    633640        """Displays command line usage, then exists successfully.""" 
    634         self.clean() 
     641        try : 
     642            self.clean() 
     643        except AttributeError :     
     644            pass 
    635645        print _(self.documentation) % (version.__version__, version.__author__) 
    636646        sys.exit(0) 
  • pykota/trunk/pykota/version.py

    r1905 r1923  
    2222# 
    2323 
    24 __version__ = "1.21alpha2_unofficial" 
     24__version__ = "1.21alpha3_unofficial" 
    2525 
    2626__doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""