# -*- coding: utf-8 -*- # # PyKota : Print Quotas for CUPS # # (c) 2003-2013 Jerome Alet # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # $Id: cups.py 3561 2013-01-04 22:34:24Z jerome $ # """This module implements some CUPS specific classes.""" from pykota.errors import PyKotaToolError try : from pkipplib import pkipplib except ImportError : raise RuntimeError, "The python-pkipplib module is now mandatory. You can download pkipplib from http://www.pykota.com/" class JobTicket : """A class to hold CUPS print job informations.""" def __init__(self, jobid=None, printername=None, copies=1, filename=None, \ options=None) : """Initializes a print job's information.""" self.JobId = jobid self.PrinterName = printername self.Copies = copies self.FileName = filename self.Options = options self.Charset = None self.OriginatingUserName = None self.OriginalUserName = None self.Title = None self.BillingCode = None self.OriginatingHostName = None self.TimeAtCreation = None self.TimeAtProcessing = None self.MimeType = None self.UUID = None if self.JobId is not None : self.retrieveAttributesFromCUPS() def getAttributeTypeAndValue(self, ippanswer, attribute, category="job") : """Retrieves a particular attribute's type and value from an IPP answer. Returns a tuple of the form (type, value). """ try : return getattr(ippanswer, category)[attribute][0] except KeyError : return (None, None) def retrieveAttributesFromCUPS(self) : """Retrieve attribute's values from CUPS.""" server = pkipplib.CUPS() # TODO : username and password and/or encryption answer = server.getJobAttributes(self.JobId) if answer is None : raise PyKotaToolError, "Network error while querying the CUPS server : %s" \ % server.lastErrorMessage (dummy, self.Charset) = self.getAttributeTypeAndValue(answer, "attributes-charset", "operation") (dummy, self.OriginatingUserName) = self.getAttributeTypeAndValue(answer, "job-originating-user-name") (dummy, self.Title) = self.getAttributeTypeAndValue(answer, "job-name") (dummy, self.BillingCode) = self.getAttributeTypeAndValue(answer, "job-billing") (dummy, self.OriginatingHostName) = self.getAttributeTypeAndValue(answer, "job-originating-host-name") (dummy, self.UUID) = self.getAttributeTypeAndValue(answer, "job-uuid") (dummy, self.TimeAtCreation) = self.getAttributeTypeAndValue(answer, "time-at-creation") (dummy, self.TimeAtProcessing) = self.getAttributeTypeAndValue(answer, "time-at-processing") (dummy, self.MimeType) = self.getAttributeTypeAndValue(answer, "document-format") # handle Kerberized usernames as described here : # http://www.mit.edu/~kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-user/What-is-a-Kerberos-Principal_003f.html # # Only does this if there's a "@" in the username, otherwise we could break non-kerberized # usernames containing a "/", like Samba/Windows usernames in some cases. try : if self.OriginatingUserName.find("@") != -1 : self.OriginatingUserName = self.OriginatingUserName.split("@", 1)[0].split("/")[0] except AttributeError : # None self.OriginatingUserName = "" # The options weren't retrieved from the job ticket but from the # command line instead, so they already are in unicode form. # That's why we convert them back to the ticket's charset. try : self.Options = self.Options.encode(self.Charset, "replace") except AttributeError : pass for attrib in ("OriginatingUserName", "OriginatingHostName", "Title", "BillingCode", "PrinterName", "Options", "Charset", "UUID", "MimeType") : try : setattr(self, attrib, getattr(self, attrib).decode(self.Charset, "replace")) # Charset itself should only be stored in ascii anyway except AttributeError : pass self.OriginalUserName = self.OriginatingUserName[:] if __name__ == "__main__" : import sys if len(sys.argv) != 2 : sys.stderr.write("usage : python cups.py jobid\n") else : job = JobTicket(int(sys.argv[1]), "FakePrinter") for attribute in ("PrinterName", "Charset", "JobId", "Copies", "FileName", "OriginatingUserName", "Title", "BillingCode", "OriginatingHostName", "TimeAtCreation", "TimeAtProcessing", "UUID", "MimeType") : sys.stdout.write("%s : %s\n" % (attribute, repr(getattr(job, attribute))))