Changeset 2254
- Timestamp:
- 05/17/05 22:24:40 (20 years ago)
- Location:
- pykota/trunk
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/cupspykota
r2239 r2254 40 40 from pykota.storage import PyKotaStorageError 41 41 from pykota.accounter import PyKotaAccounterError 42 from pykota.ipp import IPPMessage, PyKotaIPPError42 from pykota.ipp import IPPMessage, IPPError 43 43 44 44 class PyKotaPopen4(popen2.Popen4) : … … 215 215 ippdatafile.close() 216 216 self.dropPriv() 217 clienthost = ippmessage.get("job-originating-host-name") 218 billingcode = ippmessage.get("job-billing") 217 218 try : 219 (chtype, clienthost) = ippmessage.operation_attributes.get("job-originating-host-name", \ 220 ippmessage.job_attributes.get("job-originating-host-name", (None, None))) 221 (jbtype, billingcode) = ippmessage.job_attributes.get("job-billing", (None, None)) 222 except AttributeError : 223 clienthost = None 224 billingcode = None 219 225 if clienthost is None : 220 226 (billingcode, clienthost) = self.getJobInfosFromPageLog(cupsdconf, printer.Name, user.Name, self.jobid) 221 227 self.logdebug("Client Hostname : %s" % (clienthost or "Unknown")) 222 228 self.logdebug("Billing Code : %s" % (billingcode or "None")) 229 223 230 os.environ["PYKOTAJOBORIGINATINGHOSTNAME"] = str(clienthost or "") 224 231 os.environ["PYKOTAJOBBILLING"] = str(billingcode or "") -
pykota/trunk/NEWS
r2241 r2254 22 22 PyKota NEWS : 23 23 24 - 1.23alpha2 : 25 26 - Major rewrite of the IPP message parsing code to definitely 27 fix the job-originating-hostname IPP attribute problem. 28 24 29 - 1.23alpha1 : 25 30 -
pykota/trunk/pykota/ipp.py
r2190 r2254 2 2 # -*- coding: ISO-8859-15 -*- 3 3 # 4 # PyKota - Print Quotas for CUPS and LPRng 5 # 6 # (c) 2003-2004 Jerome Alet <alet@librelogiciel.com> 4 # PyKota 5 # 6 # PyKota : Print Quotas for CUPS and LPRng 7 # 8 # (c) 2003, 2004, 2005 Jerome Alet <alet@librelogiciel.com> 7 9 # This program is free software; you can redistribute it and/or modify 8 10 # it under the terms of the GNU General Public License as published by … … 32 34 UNSUPPORTED_ATTRIBUTES_TAG = 0x05 33 35 34 class PyKotaIPPError(Exception):35 """An exception for PyKotaIPP related stuff."""36 class IPPError(Exception): 37 """An exception for IPP related stuff.""" 36 38 def __init__(self, message = ""): 37 39 self.message = message … … 42 44 43 45 class IPPMessage : 44 """A class for IPP message files.""" 45 def __init__(self, data) : 46 """Initializes an IPP Message object.""" 46 """A class for IPP message files. 47 48 Usage : 49 50 fp = open("/var/spool/cups/c00001", "rb") 51 message = IPPMessage(fp.read()) 52 fp.close() 53 print "IPP version : %s" % message.version 54 print "IPP operation Id : %s" % message.operation_id 55 print "IPP request Id : %s" % message.request_id 56 for attrtype in ("operation", "job", "printer", "unsupported") : 57 attrdict = getattr(message, "%s_attributes" % attrtype) 58 if attrdict : 59 print "%s attributes :" % attrtype.title() 60 for key in attrdict.keys() : 61 print " %s : %s" % (key, attrdict[key]) 62 """ 63 def __init__(self, data, debug=0) : 64 """Initializes and parses IPP Message object. 65 66 Parameters : 67 68 data : the IPP Message's content. 69 debug : a boolean value to output debug info on stderr. 70 """ 71 self.debug = debug 47 72 self.data = data 48 self._attributes = {} 49 self.curname = None 73 self.operation_attributes = {} 74 self.job_attributes = {} 75 self.printer_attributes = {} 76 self.unsupported_attributes = {} 50 77 self.tags = [ None ] * 256 # by default all tags reserved 51 78 52 79 # Delimiter tags 53 self.tags[ 0x01] = "operation-attributes-tag"54 self.tags[ 0x02] = "job-attributes-tag"55 self.tags[ 0x03] = "end-of-attributes-tag"56 self.tags[ 0x04] = "printer-attributes-tag"57 self.tags[ 0x05] = "unsupported-attributes-tag"80 self.tags[OPERATION_ATTRIBUTES_TAG] = "operation-attributes-tag" 81 self.tags[JOB_ATTRIBUTES_TAG] = "job-attributes-tag" 82 self.tags[END_OF_ATTRIBUTES_TAG] = "end-of-attributes-tag" 83 self.tags[PRINTER_ATTRIBUTES_TAG] = "printer-attributes-tag" 84 self.tags[UNSUPPORTED_ATTRIBUTES_TAG] = "unsupported-attributes-tag" 58 85 59 86 # out of band values … … 93 120 self.parse() 94 121 95 def __getattr__(self, attrname) : 96 """Allows self.attributes to return the attributes names.""" 97 if attrname == "attributes" : 98 keys = self._attributes.keys() 99 keys.sort() 100 return keys 101 raise AttributeError, attrname 122 def printInfo(self, msg) : 123 """Prints a debug message.""" 124 if self.debug : 125 sys.stderr.write("%s\n" % msg) 126 sys.stderr.flush() 102 127 103 def __getitem__(self, ippattrname) :104 """Fakes a dictionnary d['key'] notation."""105 value = self._attributes.get(ippattrname)106 if value is not None :107 if len(value) == 1 :108 value = value[0]109 return value110 get = __getitem__111 112 def keys(self) :113 """Fakes a dictionnary .keys() method."""114 return self._attributes.keys()115 116 128 def parseTag(self) : 117 129 """Extracts information from an IPP tag.""" 118 130 pos = self.position 119 valuetag = self.tags[ord(self.data[pos])] 120 # print valuetag.get("name") 131 tagtype = self.tags[ord(self.data[pos])] 121 132 pos += 1 122 133 posend = pos2 = pos + 2 123 134 namelength = unpack(">H", self.data[pos:pos2])[0] 124 135 if not namelength : 125 name = self. curname136 name = self._curname 126 137 else : 127 138 posend += namelength 128 self. curname = name = self.data[pos2:posend]139 self._curname = name = self.data[pos2:posend] 129 140 pos2 = posend + 2 130 141 valuelength = unpack(">H", self.data[posend:pos2])[0] 131 142 posend = pos2 + valuelength 132 143 value = self.data[pos2:posend] 133 oldval = self._attributes.setdefault(name, []) 134 oldval.append(value) 144 if tagtype in ("integer", "enum") : 145 value = unpack(">I", value)[0] 146 oldval = self._curdict.setdefault(name, []) 147 oldval.append((tagtype, value)) 148 self.printInfo("%s(%s) %s" % (name, tagtype, value)) 135 149 return posend - self.position 136 150 137 151 def operation_attributes_tag(self) : 138 152 """Indicates that the parser enters into an operation-attributes-tag group.""" 153 self.printInfo("Start of operation_attributes_tag") 154 self._curdict = self.operation_attributes 139 155 return self.parseTag() 140 156 141 157 def job_attributes_tag(self) : 142 """Indicates that the parser enters into an operation-attributes-tag group.""" 158 """Indicates that the parser enters into a job-attributes-tag group.""" 159 self.printInfo("Start of job_attributes_tag") 160 self._curdict = self.job_attributes 143 161 return self.parseTag() 144 162 145 163 def printer_attributes_tag(self) : 146 """Indicates that the parser enters into an operation-attributes-tag group.""" 164 """Indicates that the parser enters into a printer-attributes-tag group.""" 165 self.printInfo("Start of printer_attributes_tag") 166 self._curdict = self.printer_attributes 167 return self.parseTag() 168 169 def unsupported_attributes_tag(self) : 170 """Indicates that the parser enters into an unsupported-attributes-tag group.""" 171 self.printInfo("Start of unsupported_attributes_tag") 172 self._curdict = self.unsupported_attributes 147 173 return self.parseTag() 148 174 … … 151 177 152 178 NB : Only a subset of RFC2910 is implemented. 153 We are only interested in textual informations for now anyway.154 179 """ 180 self._curname = None 181 self._curdict = None 155 182 self.version = "%s.%s" % (ord(self.data[0]), ord(self.data[1])) 156 183 self.operation_id = "0x%04x" % unpack(">H", self.data[2:4])[0] … … 171 198 tag = ord(self.data[self.position]) 172 199 except IndexError : 173 raise PyKotaIPPError, "Unexpected end of IPP message." 200 raise IPPError, "Unexpected end of IPP message." 201 202 # Now transform all one-element lists into single values 203 for attrtype in ("operation", "job", "printer") : 204 attrdict = getattr(self, "%s_attributes" % attrtype) 205 for (key, value) in attrdict.items() : 206 if len(value) == 1 : 207 attrdict[key] = value[0] 174 208 175 209 if __name__ == "__main__" : 176 if len(sys.argv) < 2:177 print "usage : python ipp.py /var/spool/cups/c00005 (for example)\n"210 if (len(sys.argv) < 2) or (sys.argv[1] == "--debug") : 211 print "usage : python ipp.py /var/spool/cups/c00005 [--debug] (for example)\n" 178 212 else : 179 infile = open(sys.argv[1] )180 message = IPPMessage(infile.read() )213 infile = open(sys.argv[1], "rb") 214 message = IPPMessage(infile.read(), debug=(sys.argv[-1]=="--debug")) 181 215 infile.close() 182 for key in message.keys() : 183 print "%s : %s" % (key, message[key]) 216 print "IPP version : %s" % message.version 217 print "IPP operation Id : %s" % message.operation_id 218 print "IPP request Id : %s" % message.request_id 219 for attrtype in ("operation", "job", "printer", "unsupported") : 220 attrdict = getattr(message, "%s_attributes" % attrtype) 221 if attrdict : 222 print "%s attributes :" % attrtype.title() 223 for key in attrdict.keys() : 224 print " %s : %s" % (key, attrdict[key]) -
pykota/trunk/pykota/version.py
r2239 r2254 22 22 # 23 23 24 __version__ = "1.23alpha 1_unofficial"24 __version__ = "1.23alpha2_unofficial" 25 25 26 26 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""