root / pykota / trunk / bin / pkbanner @ 1918

Revision 1918, 9.4 kB (checked in by jalet, 19 years ago)

PyKota banners now basically work !

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3
4# A banner generator for PyKota
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22#
23# $Id$
24#
25# $Log$
26# Revision 1.4  2004/11/15 19:59:34  jalet
27# PyKota banners now basically work !
28#
29# Revision 1.3  2004/11/12 23:46:44  jalet
30# Heavy work on pkbanner. Not finished yet though, but mostly works.
31#
32# Revision 1.2  2004/11/11 14:25:48  jalet
33# Added some TODO comments
34#
35# Revision 1.1  2004/11/10 22:48:47  jalet
36# Banner generator's skeleton added
37#
38#
39#
40
41import sys
42import os
43import cStringIO
44import popen2
45
46try :
47    from reportlab.pdfgen import canvas
48    from reportlab.lib import pagesizes
49    from reportlab.lib.units import cm
50except ImportError :   
51    hasRL = 0
52else :   
53    hasRL = 1
54   
55try :
56    import PIL.Image 
57except ImportError :   
58    hasPIL = 0
59else :   
60    hasPIL = 1
61   
62from pykota.tool import Tool, PyKotaToolError, crashed, N_
63
64__doc__ = N_("""pkbanner v%s (c) 2003-2004 C@LL - Conseil Internet & Logiciels Libres
65
66Generates banners.
67
68command line usage :
69
70  pkbanner  [options]  [files]
71
72options :
73
74  -v | --version       Prints pkbanner's version number then exits.
75  -h | --help          Prints this message then exits.
76 
77  ... TODO...
78 
79examples :                             
80
81  ... TODO...
82
83This program is free software; you can redistribute it and/or modify
84it under the terms of the GNU General Public License as published by
85the Free Software Foundation; either version 2 of the License, or
86(at your option) any later version.
87
88This program is distributed in the hope that it will be useful,
89but WITHOUT ANY WARRANTY; without even the implied warranty of
90MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
91GNU General Public License for more details.
92
93You should have received a copy of the GNU General Public License
94along with this program; if not, write to the Free Software
95Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
96
97Please e-mail bugs to: %s""")
98       
99class PyKotaBanner(Tool) :       
100    """A class for pkbanner."""
101    primaryfields = [ 
102                ("PRINTERNAME", N_("Printer")),
103                ("USERNAME", N_("User")),
104                ("JOBID", N_("JobId")),
105                ("JOBORIGINATINGHOSTNAME", N_("Client host")),
106                ("TITLE", N_("Title")),
107                ("FILENAME", N_("Filename")),
108                ("COPIES", N_("Copies")),
109                ("JOBSIZEBYTES", N_("Job size in bytes")),
110                ("PRECOMPUTEDJOBSIZE", N_("Estimated job size")),
111                ("PRECOMPUTEDJOBPRICE", N_("Estimated job price")),
112             ]   
113             
114    secondaryfields = [
115                ("LIMITBY", N_("Account limited by")),
116                ("BALANCE", N_("Account balance")),
117                ("PAGECOUNTER", N_("Number of pages on this printer")),
118                ("SOFTLIMIT", N_("Soft limit")),
119                ("HARDLIMIT", N_("Hard limit")),
120                ("DATELIMIT", N_("Date limit")),
121             ]                           
122   
123    tertiaryfields = [
124                ("ACTION", N_("Action taken for current job")),
125             ]                           
126   
127    def getPageSize(self, pgsize) :
128        """Returns the correct page size or None if not found."""
129        try :
130            return getattr(pagesizes, pgsize.upper())
131        except AttributeError :   
132            try :
133                return getattr(pagesizes, pgsize.lower())
134            except AttributeError :
135                pass
136               
137    def genPDF(self, pagesize, logo, url) :           
138        """Generates the banner in PDF format, return the PDF document as a string."""
139        document = cStringIO.StringIO()
140        c = canvas.Canvas(document, pagesize=pagesize, pageCompression=1)
141       
142        c.setAuthor("Jerome Alet")
143        c.setTitle("PyKota generated Banner")
144        c.setSubject("This is a print banner generated with PyKota")
145       
146        xcenter = pagesize[0] / 2.0
147        ycenter = pagesize[1] / 2.0
148                   
149        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)
162       
163        # New top
164        xpos = pagesize[0] / 5.0
165        ypos -= (1 * cm) + 20
166       
167        for fieldsgroup in [ self.primaryfields, self.secondaryfields, self.tertiaryfields] :
168            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
178            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()
187       
188        c.showPage()
189        c.save()
190        return document.getvalue()
191   
192    def main(self, files, options) :
193        """Generates a banner."""
194        if not hasRL :
195            raise PyKotaToolError, "The ReportLab module is missing. Download it from http://www.reportlab.org"
196        if not hasPIL :
197            raise PyKotaToolError, "The Python Imaging Library is missing. Download it from http://www.pythonware.com/downloads"
198           
199        pagesize = self.getPageSize(options["pagesize"])
200        if pagesize is None :
201            pagesize = self.getPageSize("a4")
202            self.printInfo("Unknown page size %s, defaulting to A4." % options["pagesize"], "warn")
203           
204        self.logdebug("Generating the banner in PDF format...")   
205        doc = self.genPDF(pagesize, options["logo"], options["url"].strip())
206       
207        self.logdebug("Converting the banner to PostScript...")   
208        os.environ["PATH"] = "%s:/bin:/usr/bin:/usr/local/bin:/opt/bin:/sbin:/usr/sbin" % os.environ.get("PATH", "")
209        child = popen2.Popen3("gs -q -dNOPAUSE -dBATCH -dPARANOIDSAFER -sDEVICE=pswrite -sOutputFile=- - 2>/tmp/errgs")
210        child.tochild.write(doc)
211        child.tochild.close()
212        sys.stdout.write(child.fromchild.read())
213        sys.stdout.flush()
214        child.fromchild.close()
215        status = child.wait()
216        if os.WIFEXITED(status) :
217            status = os.WEXITSTATUS(status)
218        self.logdebug("PDF to PostScript converter exit code is %s" % str(status))
219        self.logdebug("Banner completed.")
220        return status
221
222def getInfo(name) :
223    """Extracts some information from the environment."""
224    return os.environ.get(name, _("Unknown"))
225
226if __name__ == "__main__" :
227    # TODO : --papertray : to print banners on a different paper (colored for example)
228    retcode = 0
229    try :
230        defaults = { \
231                     "pagesize" : "a4", \
232                     "logo" : "/usr/share/pykota/logos/pykota.jpeg",
233                     "url" : "http://www.librelogiciel.com/software/",
234                   }
235        short_options = "vhl:p:u:"
236        long_options = ["help", "version", "pagesize=", "logo=", "url="]
237       
238        # Initializes the command line tool
239        banner = PyKotaBanner(doc=__doc__)
240       
241        # parse and checks the command line
242        (options, args) = banner.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
243       
244        # sets long options
245        options["help"] = options["h"] or options["help"]
246        options["version"] = options["v"] or options["version"]
247        options["pagesize"] = options["p"] or options["pagesize"] or defaults["pagesize"]
248        options["logo"] = options["l"] or options["logo"] or defaults["logo"]
249        options["url"] = options["u"] or options["url"] or defaults["url"]
250       
251        if options["help"] :
252            banner.display_usage_and_quit()
253        elif options["version"] :
254            banner.display_version_and_quit()
255        else :
256            retcode = banner.main(args, options)
257    except SystemExit :       
258        pass
259    except :
260        try :
261            banner.crashed("pkbanner failed")
262        except :   
263            crashed("pkbanner failed")
264        retcode = -1
265       
266    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.