Show
Ignore:
Timestamp:
05/19/06 16:12:46 (18 years ago)
Author:
jerome
Message:

Finished a basic useable implementation for the creation of IPP request,
their sending to a CUPS server, and the retrieval of answers.
Implemented a basic CUPS class.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pkipplib/trunk/ipplib/ipplib.py

    r3 r7  
    22# -*- coding: ISO-8859-15 -*- 
    33# 
    4 # ipplib : IPP support for Python 
     4# ipplib : IPP and CUPS support for Python 
    55# 
    6 # (c) 2003, 2004, 2005 Jerome Alet <alet@librelogiciel.com> 
     6# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com> 
    77# This program is free software; you can redistribute it and/or modify 
    88# it under the terms of the GNU General Public License as published by 
     
    245245    __str__ = __repr__ 
    246246 
     247class FakeAttribute : 
     248    """Fakes an IPPRequest attribute to simplify usage syntax.""" 
     249    def __init__(self, request, name) : 
     250        """Initializes the fake attribute.""" 
     251        self.request = request 
     252        self.name = name 
     253         
     254    def __setitem__(self, key, value) : 
     255        """Appends the value to the real attribute.""" 
     256        attributeslist = getattr(self.request, "_%s_attributes" % self.name) 
     257        for i in range(len(attributeslist)) : 
     258            attribute = attributeslist[i] 
     259            for j in range(len(attribute)) : 
     260                (attrname, attrvalue) = attribute[j] 
     261                if attrname == key : 
     262                    attribute[j][1].append(value) 
     263                    return 
     264            attribute.append((key, [value]))         
     265             
     266    def __getitem__(self, key) : 
     267        """Returns an attribute's value.""" 
     268        attributeslist = getattr(self.request, "_%s_attributes" % self.name) 
     269        for i in range(len(attributeslist)) : 
     270            attribute = attributeslist[i] 
     271            for j in range(len(attribute)) : 
     272                (attrname, attrvalue) = attribute[j] 
     273                if attrname == key : 
     274                    return attrvalue 
     275        raise KeyError, key             
     276     
    247277class IPPRequest : 
    248278    """A class for IPP requests.""" 
     
    251281    def __init__(self, data="", version=IPP_VERSION,  
    252282                                operation_id=None, \ 
    253                                 request_id=None, debug=0) : 
     283                                request_id=None, \ 
     284                                url = "http://localhost:631", \ 
     285                                username = None, \ 
     286                                password = None, \ 
     287                                debug=False) : 
    254288        """Initializes an IPP Message object. 
    255289         
     
    259293             debug : a boolean value to output debug info on stderr. 
    260294        """ 
     295        self.url = url 
     296        self.username = username 
     297        self.password = password 
    261298        self.debug = debug 
    262299        self._data = data 
    263         self.parsed = 0 
     300        self.parsed = False 
    264301         
    265302        # Initializes message 
     
    270307         
    271308        for attrtype in self.attributes_types : 
    272             setattr(self, "%s_attributes" % attrtype, [[]]) 
     309            setattr(self, "_%s_attributes" % attrtype, [[]]) 
    273310         
    274311        # Initialize tags     
     
    328365                self.tagvalues[value] = i 
    329366                                      
     367    def __getattr__(self, name) :                                  
     368        """Fakes attribute access.""" 
     369        if name in self.attributes_types : 
     370            return FakeAttribute(self, name) 
     371        else : 
     372            raise AttributeError, name 
     373             
    330374    def __str__(self) :         
    331375        """Returns the parsed IPP message in a readable form.""" 
     
    337381        mybuffer.append("IPP request Id : 0x%08x" % self.request_id) 
    338382        for attrtype in self.attributes_types : 
    339             for attribute in getattr(self, "%s_attributes" % attrtype) : 
     383            for attribute in getattr(self, "_%s_attributes" % attrtype) : 
    340384                if attribute : 
    341385                    mybuffer.append("%s attributes :" % attrtype.title()) 
     
    388432        """     
    389433        mybuffer = [] 
    390         if None not in (self.version, self.operation_id, self.request_id) : 
     434        if None not in (self.version, self.operation_id) : 
     435            if self.request_id is None : 
     436                self.nextRequestId() 
    391437            mybuffer.append(chr(self.version[0]) + chr(self.version[1])) 
    392438            mybuffer.append(pack(">H", self.operation_id)) 
    393439            mybuffer.append(pack(">I", self.request_id)) 
    394440            for attrtype in self.attributes_types : 
    395                 for attribute in getattr(self, "%s_attributes" % attrtype) : 
     441                for attribute in getattr(self, "_%s_attributes" % attrtype) : 
    396442                    if attribute : 
    397443                        mybuffer.append(chr(self.tagvalues["%s-attributes-tag" % attrtype])) 
     
    453499             
    454500        self.data = self._data[self.position+1:]             
    455         self.parsed = 1             
     501        self.parsed = True 
    456502         
    457503    def parseTag(self) :     
     
    488534    def operation_attributes_tag(self) :  
    489535        """Indicates that the parser enters into an operation-attributes-tag group.""" 
    490         self._curattributes = self.operation_attributes 
     536        self._curattributes = self._operation_attributes 
    491537        return self.parseTag() 
    492538         
    493539    def job_attributes_tag(self) :  
    494540        """Indicates that the parser enters into a job-attributes-tag group.""" 
    495         self._curattributes = self.job_attributes 
     541        self._curattributes = self._job_attributes 
    496542        return self.parseTag() 
    497543         
    498544    def printer_attributes_tag(self) :  
    499545        """Indicates that the parser enters into a printer-attributes-tag group.""" 
    500         self._curattributes = self.printer_attributes 
     546        self._curattributes = self._printer_attributes 
    501547        return self.parseTag() 
    502548         
    503549    def unsupported_attributes_tag(self) :  
    504550        """Indicates that the parser enters into an unsupported-attributes-tag group.""" 
    505         self._curattributes = self.unsupported_attributes 
     551        self._curattributes = self._unsupported_attributes 
    506552        return self.parseTag() 
    507553         
    508554    def subscription_attributes_tag(self) :  
    509555        """Indicates that the parser enters into a subscription-attributes-tag group.""" 
    510         self._curattributes = self.subscription_attributes 
     556        self._curattributes = self._subscription_attributes 
    511557        return self.parseTag() 
    512558         
    513559    def event_notification_attributes_tag(self) :  
    514560        """Indicates that the parser enters into an event-notification-attributes-tag group.""" 
    515         self._curattributes = self.event_notification_attributes 
     561        self._curattributes = self._event_notification_attributes 
    516562        return self.parseTag() 
    517563         
    518     def doRequest(self, url=None, username=None, password=None) : 
     564    def doRequest(self, url=None, username=None, password=None, samerequestid=False) : 
    519565        """Sends the current request to the URL. 
    520566           NB : only ipp:// URLs are currently unsupported so use 
     
    523569           returns a new IPPRequest object, containing the parsed answer. 
    524570        """    
    525         cx = urllib2.Request(url=url or "http://localhost:631/",  
     571        if not samerequestid : 
     572            self.nextRequestId() 
     573        cx = urllib2.Request(url=url or self.url or "http://localhost:631/",  
    526574                             data=self.dump()) 
    527575        cx.add_header("Content-Type", "application/ipp") 
     
    531579        ippresponse.parse() 
    532580        return ippresponse 
     581         
     582             
     583class CUPS : 
     584    """A class for a CUPS instance.""" 
     585    def __init__(self, url="http://localhost:631", username=None, password=None, charset="utf-8", language="en-us") : 
     586        """Initializes the CUPS instance.""" 
     587        self.url = url 
     588        self.username = username 
     589        self.password = password 
     590        self.charset = charset 
     591        self.language = language 
     592         
     593    def newRequest(self, operationid=None) : 
     594        """Generates a new empty request.""" 
     595        if operationid is not None : 
     596            req = IPPRequest(operation_id=operationid, \ 
     597                             url=self.url, \ 
     598                             username=self.username, \ 
     599                             password=self.password) 
     600            req.operation["attributes-charset"] = ("charset", self.charset) 
     601            req.operation["attributes-natural-language"] = ("naturalLanguage", self.language) 
     602            return req 
     603     
     604    def getDefault(self) : 
     605        """Retrieves CUPS' default printer.""" 
     606        return self.newRequest(CUPS_GET_DEFAULT).doRequest() 
     607     
     608    def getJobAttributes(self, jobid) :     
     609        """Retrieves a print job's attributes.""" 
     610        req = self.newRequest(IPP_GET_JOB_ATTRIBUTES) 
     611        req.operation["job-uri"] = ("uri", "ipp://localhost:631/jobs/%s" % jobid) 
     612        return req.doRequest() 
     613         
    533614             
    534615if __name__ == "__main__" :