Changeset 2254 for pykota/trunk/pykota/ipp.py
- Timestamp:
- 05/17/05 22:24:40 (20 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
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])