Changeset 3413 for pykota/trunk/bin/pkrefund
- Timestamp:
- 09/27/08 22:02:37 (16 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/pkrefund
r3411 r3413 9 9 # the Free Software Foundation, either version 3 of the License, or 10 10 # (at your option) any later version. 11 # 11 # 12 12 # This program is distributed in the hope that it will be useful, 13 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 # GNU General Public License for more details. 16 # 16 # 17 17 # You should have received a copy of the GNU General Public License 18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. … … 34 34 from reportlab.lib import pagesizes 35 35 from reportlab.lib.units import cm 36 except ImportError : 36 except ImportError : 37 37 hasRL = False 38 else : 38 else : 39 39 hasRL = True 40 40 41 41 try : 42 import PIL.Image 43 except ImportError : 42 import PIL.Image 43 except ImportError : 44 44 hasPIL = False 45 else : 45 else : 46 46 hasPIL = True 47 47 … … 54 54 from pykota.errors import PyKotaToolError, PyKotaCommandLineError 55 55 from pykota.tool import Percent, PyKotaTool 56 57 class PKRefund(PyKotaTool) : 56 57 class PKRefund(PyKotaTool) : 58 58 """A class for refund manager.""" 59 59 validfilterkeys = [ "username", … … 65 65 "end", 66 66 ] 67 67 68 68 def printVar(self, label, value, size) : 69 69 """Outputs a variable onto the PDF canvas. 70 70 71 71 Returns the number of points to substract to current Y coordinate. 72 """ 72 """ 73 73 xcenter = (self.pagesize[0] / 2.0) - 1*cm 74 74 self.canvas.saveState() … … 81 81 self.canvas.restoreState() 82 82 self.ypos -= (size + 4) 83 83 84 84 def pagePDF(self, receiptnumber, name, values, unit, reason) : 85 85 """Generates a new page in the PDF document.""" … … 92 92 datetime = time.strftime("%c", time.localtime()).decode(self.charset, "replace") 93 93 self.printVar(_("Edited on"), datetime, 14) 94 94 95 95 self.ypos -= 20 96 96 self.printVar(_("Jobs refunded"), str(values["nbjobs"]), 18) … … 101 101 self.canvas.showPage() 102 102 return 1 103 return 0 104 103 return 0 104 105 105 def initPDF(self, logo) : 106 106 """Initializes the PDF document.""" 107 self.pdfDocument = cStringIO.StringIO() 107 self.pdfDocument = cStringIO.StringIO() 108 108 self.canvas = c = canvas.Canvas(self.pdfDocument, \ 109 109 pagesize=self.pagesize, \ 110 110 pageCompression=1) 111 111 112 112 c.setAuthor(self.effectiveUserName) 113 113 c.setTitle(_("PyKota print job refunding receipts")) 114 114 c.setSubject(_("Print job refunding receipts generated with PyKota")) 115 115 116 116 self.canvas.beginForm("background") 117 117 self.canvas.saveState() 118 119 self.ypos = self.pagesize[1] - (2 * cm) 120 118 119 self.ypos = self.pagesize[1] - (2 * cm) 120 121 121 xcenter = self.pagesize[0] / 2.0 122 122 if logo : 123 try : 123 try : 124 124 imglogo = PIL.Image.open(logo) 125 except IOError : 125 except IOError : 126 126 self.printInfo("Unable to open image %s" % logo, "warn") 127 127 else : 128 128 (width, height) = imglogo.size 129 multi = float(width) / (8 * cm) 129 multi = float(width) / (8 * cm) 130 130 width = float(width) / multi 131 131 height = float(height) / multi … … 134 134 self.ypos, \ 135 135 width, height) 136 136 137 137 self.ypos -= (cm + 20) 138 138 self.canvas.setFont("Helvetica-Bold", 14) … … 140 140 msg = _("Here's the receipt for the refunding of your print jobs") 141 141 self.canvas.drawCentredString(xcenter, self.ypos, "%s :" % msg) 142 142 143 143 self.yorigine = self.ypos 144 144 self.canvas.restoreState() 145 145 self.canvas.endForm() 146 147 def endPDF(self, fname) : 146 147 def endPDF(self, fname) : 148 148 """Flushes the PDF generator.""" 149 149 self.canvas.save() 150 if fname != "-" : 150 if fname != "-" : 151 151 outfile = open(fname, "w") 152 152 outfile.write(self.pdfDocument.getvalue()) 153 153 outfile.close() 154 else : 154 else : 155 155 sys.stdout.write(self.pdfDocument.getvalue()) 156 156 sys.stdout.flush() 157 157 158 158 def genReceipts(self, peruser, logo, outfname, firstnumber, reason, unit) : 159 159 """Generates the receipts file.""" … … 162 162 if outfname != "-" : 163 163 percent.display("%s...\n" % _("Generating receipts")) 164 164 165 165 self.initPDF(logo) 166 166 number = firstnumber … … 169 169 if outfname != "-" : 170 170 percent.oneMore() 171 171 172 172 if number > firstnumber : 173 173 self.endPDF(outfname) 174 174 175 175 if outfname != "-" : 176 176 percent.done() 177 177 178 178 def main(self, arguments, options) : 179 179 """Refunds jobs.""" … … 182 182 if not hasPIL : 183 183 raise PyKotaToolError, "The Python Imaging Library is missing. Download it from http://www.pythonware.com/downloads" 184 185 self.adminOnly() 186 184 185 self.adminOnly() 186 187 187 self.pagesize = getPageSize(options.pagesize) 188 188 189 189 if (not options.reason) or (not options.reason.strip()) : 190 190 raise PyKotaCommandLineError, _("Refunding for no reason is forbidden. Please use the --reason command line option.") 191 191 192 192 extractonly = {} 193 193 for filterexp in arguments : … … 197 197 filterkey = filterkey.lower() 198 198 if filterkey not in self.validfilterkeys : 199 raise ValueError 200 except ValueError : 199 raise ValueError 200 except ValueError : 201 201 raise PyKotaCommandLineError, _("Invalid filter value [%s], see help.") % filterexp 202 else : 202 else : 203 203 extractonly.update({ filterkey : filtervalue }) 204 204 205 205 percent = Percent(self) 206 206 outfname = options.output.strip().encode(sys.getfilesystemencoding()) 207 207 if outfname != "-" : 208 208 percent.display("%s..." % _("Extracting datas")) 209 else : 209 else : 210 210 options.force = True 211 211 self.printInfo(_("The PDF file containing the receipts will be sent to stdout. --force is assumed."), "warn") 212 213 username = extractonly.get("username") 212 213 username = extractonly.get("username") 214 214 if username : 215 215 user = self.storage.getUser(username) 216 216 else : 217 217 user = None 218 219 printername = extractonly.get("printername") 218 219 printername = extractonly.get("printername") 220 220 if printername : 221 221 printer = self.storage.getPrinter(printername) 222 else : 222 else : 223 223 printer = None 224 224 225 225 start = extractonly.get("start") 226 226 end = extractonly.get("end") 227 227 (start, end) = self.storage.cleanDates(start, end) 228 229 jobs = self.storage.retrieveHistory(user=user, 230 printer=printer, 228 229 jobs = self.storage.retrieveHistory(user=user, 230 printer=printer, 231 231 hostname=extractonly.get("hostname"), 232 232 billingcode=extractonly.get("billingcode"), … … 235 235 end=end, 236 236 limit=0) 237 238 peruser = {} 239 nbjobs = 0 240 nbpages = 0 237 238 peruser = {} 239 nbjobs = 0 240 nbpages = 0 241 241 nbcredits = 0.0 242 242 percent.setSize(len(jobs)) 243 243 if outfname != "-" : 244 244 percent.display("\n") 245 for job in jobs : 245 for job in jobs : 246 246 if job.JobSize and (job.JobAction not in ("DENY", "CANCEL", "REFUND")) : 247 247 if options.force : … … 256 256 if outfname != "-" : 257 257 percent.oneMore() 258 else : 258 else : 259 259 print _("Date : %s") % str(job.JobDate)[:19] 260 260 print _("Printer : %s") % job.PrinterName … … 266 266 print _("Pages : %i") % job.JobSize 267 267 print _("Credits : %.3f") % job.JobPrice 268 269 while True : 268 269 while True : 270 270 answer = raw_input("\t%s ? " % _("Refund (Y/N)")).strip().upper() 271 271 if answer == _("Y") : … … 278 278 counters["nbjobs"] += 1 279 279 nbjobs += 1 280 break281 elif answer == _("N") :282 280 break 283 print 281 elif answer == _("N") : 282 break 283 print 284 284 if outfname != "-" : 285 285 percent.done() 286 self.genReceipts(peruser, 287 options.logo.strip().encode(sys.getfilesystemencoding()), 288 outfname, 289 options.number, 290 options.reason, 286 self.genReceipts(peruser, 287 options.logo.strip().encode(sys.getfilesystemencoding()), 288 outfname, 289 options.number, 290 options.reason, 291 291 options.unit or _("Credits")) 292 if outfname != "-" : 292 if outfname != "-" : 293 293 nbusers = len(peruser) 294 294 print _("Refunded %(nbusers)i users for %(nbjobs)i jobs, %(nbpages)i pages and %(nbcredits).3f credits") \ 295 295 % locals() 296 297 if __name__ == "__main__" : 296 297 if __name__ == "__main__" : 298 298 parser = PyKotaOptionParser(description=_("Refunding tool for PyKota."), 299 299 usage="pkrefund [options] [filterexpr]") … … 313 313 default=u"A4", 314 314 help=_("Set the size of the page. Most well known page sizes are recognized, like 'A4' or 'Letter' to name a few. The default page size is %default.")) 315 parser.add_option("-n", "--number", 315 parser.add_option("-n", "--number", 316 316 dest="number", 317 317 type="int", … … 329 329 type="string", 330 330 help=_("The reason why there was a refund.")) 331 331 332 332 # TODO : due to Python's optparse.py bug #1498146 fixed in rev 46861 333 333 # TODO : we can't use 'default=_("Credits")' for this option 334 parser.add_option("-u", "--unit", 334 parser.add_option("-u", "--unit", 335 335 dest="unit", 336 336 type="string", 337 337 help=_("The name of the unit to use on the receipts. The default value is 'Credits' or its locale translation.")) 338 338 339 339 parser.add_filterexpression("username", _("User's name")) 340 340 parser.add_filterexpression("printername", _("Printer's name")) … … 344 344 parser.add_filterexpression("start", _("Job's date of printing")) 345 345 parser.add_filterexpression("end", _("Job's date of printing")) 346 346 347 347 parser.add_example('--output /tmp/receipts.pdf jobid=503', 348 348 _("This would refund all jobs which Id is 503. A confirmation would be asked for each job to refund, and a PDF file named /tmp/receipts.pdf would be created containing printable receipts. BEWARE of job ids rolling over if you reset CUPS' history.")) 349 349 350 350 parser.add_example('--reason "Hardware problem" jobid=503 start=today-7', 351 351 _("This would refund all jobs which id is 503 but which would have been printed during the past week. The reason would be marked as being an hardware problem.")) 352 352 353 353 parser.add_example('--force username=jerome printername=HP2100', 354 354 _("This would refund all jobs printed by user jerome on printer HP2100. No confirmation would be asked.")) 355 355 356 356 parser.add_example('--force printername=HP2100 start=200602 end=yesterday', 357 357 _("This would refund all jobs printed on printer HP2100 between February 1st 2006 and yesterday. No confirmation would be asked.")) 358 358 359 359 (options, arguments) = parser.parse_args() 360 run(parser, PKRefund) 360 run(parser, PKRefund)