Changeset 3084 for pykota/trunk/bin/pkrefund
- Timestamp:
- 11/29/06 22:21:57 (18 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/pkrefund
r3068 r3084 1 1 #! /usr/bin/env python 2 2 # -*- coding: ISO-8859-15 -*- 3 4 """pkrefund is a tool to refund print jobs and generate PDF receipts.""" 3 5 4 6 # PyKota Print Job Refund Manager … … 26 28 27 29 import sys 28 29 from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_ 30 import os 31 import pwd 32 import time 33 import cStringIO 34 35 try : 36 from reportlab.pdfgen import canvas 37 from reportlab.lib import pagesizes 38 from reportlab.lib.units import cm 39 except ImportError : 40 hasRL = 0 41 else : 42 hasRL = 1 43 44 try : 45 import PIL.Image 46 except ImportError : 47 hasPIL = 0 48 else : 49 hasPIL = 1 50 51 from pykota.tool import Percent, PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_ 30 52 31 53 __doc__ = N_("""pkrefund v%(__version__)s (c) %(__years__)s %(__author__)s … … 44 66 -f | --force Doesn't ask for confirmation before refunding jobs. 45 67 -r | --reason txt Sets textual information to explain the refunding. 68 69 -l | --logo img Use the image as the receipt's logo. The logo will 70 be drawn at the center top of the page. The default 71 logo is /usr/share/pykota/logos/pykota.jpeg 72 73 -p | --pagesize sz Sets sz as the page size. Most well known 74 page sizes are recognized, like 'A4' or 'Letter' 75 to name a few. The default size is A4. 76 77 -n | --number N Sets the number of the first receipt. This number 78 will automatically be incremented for each receipt. 79 80 -o | --output f.pdf Defines the name of the PDF file which will contain 81 the receipts. If not set, then no PDF file will 82 be created. If set to '-', then --force is assumed, 83 and the PDF document is sent to standard output. 84 85 -u | --unit u Defines the name of the unit to use on the receipts. 86 The default unit is 'Credits', optionally translated 87 to your native language if it is supported by PyKota. 88 46 89 47 90 Use the filter expressions to extract only parts of the … … 83 126 Examples : 84 127 85 $ pkrefund jobid=503128 $ pkrefund --output /tmp/receipts.pdf jobid=503 86 129 87 130 This will refund all jobs which Id is 503. BEWARE : installing CUPS 88 afresh will reset the first job id at 1. So you probably want to use 89 a more precise filter as explained below 131 afresh will reset the first job id at 1, so you probably want to use 132 a more precise filter as explained below. A confirmation will 133 be asked for each job to refund, and a PDF file named /tmp/receipts.pdf 134 will be created which will contain printable receipts. 90 135 91 136 $ pkrefund --reason "Hardware problem" jobid=503 start=today-7 … … 115 160 "end", 116 161 ] 162 163 def getPageSize(self, pgsize) : 164 """Returns the correct page size or None if not found.""" 165 try : 166 return getattr(pagesizes, pgsize.upper()) 167 except AttributeError : 168 try : 169 return getattr(pagesizes, pgsize.lower()) 170 except AttributeError : 171 pass 172 173 def printVar(self, label, value, size) : 174 """Outputs a variable onto the PDF canvas. 175 176 Returns the number of points to substract to current Y coordinate. 177 """ 178 xcenter = (self.pagesize[0] / 2.0) - 1*cm 179 self.canvas.saveState() 180 self.canvas.setFont("Helvetica-Bold", size) 181 self.canvas.setFillColorRGB(0, 0, 0) 182 self.canvas.drawRightString(xcenter, self.ypos, "%s :" % self.userCharsetToUTF8(label)) 183 self.canvas.setFont("Courier-Bold", size) 184 self.canvas.setFillColorRGB(0, 0, 1) 185 self.canvas.drawString(xcenter + 0.5*cm, self.ypos, self.userCharsetToUTF8(value)) 186 self.canvas.restoreState() 187 self.ypos -= (size + 4) 188 189 def pagePDF(self, receiptnumber, name, values, unitname, reason) : 190 """Generates a new page in the PDF document.""" 191 if values["nbpages"] : 192 self.canvas.doForm("background") 193 self.ypos = self.yorigine - (cm + 20) 194 self.printVar(_("Refunding receipt"), "#%s" % receiptnumber, 22) 195 self.printVar(_("Username"), name, 22) 196 self.ypos -= 20 197 self.printVar(_("Edited on"), time.strftime("%c", time.localtime()), 14) 198 199 self.ypos -= 20 200 self.printVar(_("Jobs refunded"), str(values["nbjobs"]), 22) 201 self.printVar(_("Pages refunded"), str(values["nbpages"]), 22) 202 self.printVar(_("Amount refunded"), "%.3f %s" % (values["nbcredits"], unitname), 22) 203 self.ypos -= 20 204 self.printVar(_("Reason"), reason, 14) 205 self.canvas.showPage() 206 return 1 207 return 0 208 209 def initPDF(self, logo) : 210 """Initializes the PDF document.""" 211 self.pdfDocument = cStringIO.StringIO() 212 self.canvas = c = canvas.Canvas(self.pdfDocument, \ 213 pagesize=self.pagesize, \ 214 pageCompression=1) 215 216 c.setAuthor(self.originalUserName) 217 c.setTitle("PyKota print job refunding receipts") 218 c.setSubject("Print job refunding receipts generated with PyKota") 219 220 221 self.canvas.beginForm("background") 222 self.canvas.saveState() 223 224 self.ypos = self.pagesize[1] - (2 * cm) 225 226 xcenter = self.pagesize[0] / 2.0 227 if logo : 228 try : 229 imglogo = PIL.Image.open(logo) 230 except IOError : 231 self.printInfo("Unable to open image %s" % logo, "warn") 232 else : 233 (width, height) = imglogo.size 234 multi = float(width) / (8 * cm) 235 width = float(width) / multi 236 height = float(height) / multi 237 self.ypos -= height 238 c.drawImage(logo, xcenter - (width / 2.0), \ 239 self.ypos, \ 240 width, height) 241 242 self.ypos -= (cm + 20) 243 self.canvas.setFont("Helvetica-Bold", 14) 244 self.canvas.setFillColorRGB(0, 0, 0) 245 msg = _("Here's the receipt for the refunding of your print jobs") 246 self.canvas.drawCentredString(xcenter, self.ypos, "%s :" % self.userCharsetToUTF8(msg)) 247 248 self.yorigine = self.ypos 249 self.canvas.restoreState() 250 self.canvas.endForm() 251 252 def endPDF(self, fname) : 253 """Flushes the PDF generator.""" 254 self.canvas.save() 255 if fname != "-" : 256 outfile = open(fname, "w") 257 outfile.write(self.pdfDocument.getvalue()) 258 outfile.close() 259 else : 260 sys.stdout.write(self.pdfDocument.getvalue()) 261 sys.stdout.flush() 262 263 def genReceipts(self, peruser, logo, outfname, firstnumber, reason) : 264 """Generates the receipts file.""" 265 if outfname and len(peruser) : 266 percent = Percent(self) 267 percent.setSize(len(peruser)) 268 if outfname != "-" : 269 percent.display("%s...\n" % _("Generating receipts")) 270 271 self.initPDF(logo) 272 number = firstnumber 273 for (name, values) in peruser.items() : 274 number += self.pagePDF(number, name, values, options["unit"], reason) 275 if outfname != "-" : 276 percent.oneMore() 277 278 if number > firstnumber : 279 self.endPDF(outfname) 280 281 if outfname != "-" : 282 percent.done() 283 117 284 def main(self, arguments, options, restricted=1) : 118 285 """Print Quota Data Dumper.""" 286 if not hasRL : 287 raise PyKotaToolError, "The ReportLab module is missing. Download it from http://www.reportlab.org" 288 if not hasPIL : 289 raise PyKotaToolError, "The Python Imaging Library is missing. Download it from http://www.pythonware.com/downloads" 290 119 291 if restricted and not self.config.isAdmin : 120 292 raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command.")) 293 294 if (not options["reason"]) or not options["reason"].strip() : 295 raise PyKotaCommandLineError, _("Refunding for no reason is forbidden. Please use the --reason command line option.") 296 297 if options["output"] : 298 options["output"] = options["output"].strip() 299 if options["output"] == "-" : 300 options["force"] = True 301 self.printInfo(_("The PDF file containing the receipts will be sent to stdout. --force is assumed."), "warn") 302 303 try : 304 firstnumber = int(options["number"]) 305 if firstnumber <= 0 : 306 raise ValueError 307 except (ValueError, TypeError) : 308 raise PyKotaCommandLineError, _("Incorrect value '%s' for the --number command line option") % options["number"] 309 310 self.pagesize = self.getPageSize(options["pagesize"]) 311 if self.pagesize is None : 312 self.pagesize = self.getPageSize("a4") 313 self.printInfo(_("Invalid 'pagesize' option %s, defaulting to A4.") % options["pagesize"], "warn") 121 314 122 315 extractonly = {} … … 198 391 break 199 392 print 200 print _("Refunded %i jobs, %i pages and %.3f credits") % (nbjobs, nbpages, nbcredits) 393 self.genReceipts(peruser, options["logo"].strip(), options["output"], firstnumber, reason) 394 if options["output"] != "-" : 395 print _("Refunded %i jobs, %i pages and %.3f credits") % (nbjobs, nbpages, nbcredits) 201 396 202 397 if __name__ == "__main__" : 203 398 retcode = 0 204 399 try : 205 short_options = "vhfr" 206 long_options = ["help", "version", "force", "reason="] 400 defaults = { "unit" : N_("Credits"), 401 "pagesize" : "a4", \ 402 "logo" : "/usr/share/pykota/logos/pykota.jpeg", 403 "number" : "1", 404 } 405 short_options = "vhfru:o:p:l:n:" 406 long_options = ["help", "version", "force", "reason=", "unit=", "output=", "pagesize=", "logo=", "number="] 207 407 208 408 # Initializes the command line tool … … 218 418 options["force"] = options["f"] or options["force"] 219 419 options["reason"] = options["r"] or options["reason"] 420 options["unit"] = options["u"] or options["unit"] or defaults["unit"] 421 options["output"] = options["o"] or options["output"] 422 options["pagesize"] = options["p"] or options["pagesize"] or defaults["pagesize"] 423 options["number"] = options["n"] or options["number"] or defaults["number"] 424 options["logo"] = options["l"] or options["logo"] 425 if options["logo"] is None : # Allows --logo="" to disable the logo entirely 426 options["logo"] = defaults["logo"] 220 427 221 428 if options["help"] :