Changeset 1037115


Ignore:
Timestamp:
Dec 24, 2011, 1:33:26 AM (12 years ago)
Author:
Jessica B. Hamrick <jhamrick@…>
Branches:
no-cups
Children:
ee8e6d0
Parents:
793432f
git-author:
Jessica B. Hamrick <jhamrick@…> (12/24/11 01:33:26)
git-committer:
Jessica B. Hamrick <jhamrick@…> (12/24/11 01:33:26)
Message:

Get rid of individual operations files -- too messy. Go back to having a single requests file for handling requests.

Location:
server/lib/gutenbach
Files:
20 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • server/lib/gutenbach/ipp/__init__.py

    r793432f r1037115  
    33__all__ = ['core']
    44__all__.extend(core.__all__)
    5 print __all__
    65
    76import attributes
     
    98__all__.append('attributes')
    109__all__.extend(attributes.__all__)
    11 
    12 # this import needs to come last
    13 import operations
    14 from operations import *
    15 __all__.append('operations')
    16 __all__.extend(operations.__all__)
  • server/lib/gutenbach/ipp/core/__init__.py

    r793432f r1037115  
    1111
    1212import errors
     13from errors import *
    1314__all__.append('errors')
     15__all__.extend(errors.__all__)
  • server/lib/gutenbach/ipp/core/errors.py

    r793432f r1037115  
     1__all__ = [
     2    'IPPException',
     3    'IPPClientException',
     4    'IPPServerException',
     5
     6    'ClientErrorBadRequest',
     7    'ClientErrorForbidden',
     8    'ClientErrorNotAuthenticated',
     9    'ClientErrorNotAuthorized',
     10    'ClientErrorNotPossible',
     11    'ClientErrorTimeout',
     12    'ClientErrorNotFound',
     13    'ClientErrorGone',
     14    'ClientErrorRequestEntity',
     15    'ClientErrorRequestValue',
     16    'ClientErrorDocumentFormatNotSupported',
     17    'ClientErrorAttributes',
     18    'ClientErrorUriSchemeNotSupported',
     19    'ClientErrorCharsetNotSupported',
     20    'ClientErrorConflict',
     21    'ClientErrorCompressionNotSupported',
     22    'ClientErrorCompressionError',
     23    'ClientErrorDocumentFormatError',
     24    'ClientErrorDocumentAccessError',
     25    'ClientErrorAttributesNotSettable',
     26    'ClientErrorIgnoredAllSubscriptions',
     27    'ClientErrorTooManySubscriptions',
     28    'ClientErrorIgnoredAllNotifications',
     29    'ClientErrorPrintSupportFileNotFound',
     30
     31    'ServerErrorInternalError',
     32    'ServerErrorOperationNotSupported',
     33    'ServerErrorServiceUnavailable',
     34    'ServerErrorVersionNotSupported',
     35    'ServerErrorDeviceError',
     36    'ServerErrorTemporaryError',
     37    'ServerErrorNotAccepting',
     38    'ServerErrorPrinterBusy',
     39    'ServerErrorJobCancelled',
     40    'ServerErrorMultipleJobsNotSupported',
     41    'ServerErrorPrinterIsDeactivated',
     42]
     43   
     44
    145from .constants import ErrorCodes
    246
     
    129173    ipp_error_code = ErrorCodes.PRINTER_BUSY
    130174
    131 class ServerErrorErrorJobCancelled(IPPServerException):
     175class ServerErrorJobCancelled(IPPServerException):
    132176    ipp_error_code = ErrorCodes.ERROR_JOB_CANCELLED
    133177
  • server/lib/gutenbach/server/requests.py

    r793432f r1037115  
    2020    return f
    2121
     22def make_empty_response(request):
     23    # Operation attributes -- typically the same for any request
     24    attribute_group = ipp.AttributeGroup(
     25        ipp.AttributeTags.OPERATION,
     26        [ipp.AttributesCharset('utf-8'),
     27         ipp.AttributesNaturalLanguage('en-us')])
     28   
     29    # Set up the default response -- handlers will override these
     30    # values if they need to
     31    response_kwargs = {}
     32    response_kwargs['version']          = request.version
     33    response_kwargs['operation_id']     = ipp.StatusCodes.OK
     34    response_kwargs['request_id']       = request.request_id
     35    response_kwargs['attribute_groups'] = [attribute_group]
     36    response = ipp.Request(**response_kwargs)
     37   
     38    return response
     39
    2240class GutenbachRequestHandler(object):
    2341
     
    2745            }
    2846        self.default = "test"
     47
     48    def generic_handle(self, request):
     49        # check the IPP version number
     50        if request.version != (1, 1):
     51            raise ipp.errors.ServerErrorVersionNotSupported(str(request.version))
     52
     53        # make sure the operation attribute group has the correct tag
     54        operation = request.attribute_groups[0]
     55        if operation.tag != ipp.AttributeTags.OPERATION:
     56            raise ipp.errors.ClientErrorBadRequest(
     57                "Attribute group does not have OPERATION tag: 0x%x" % operation.tag)
     58
     59        # check charset
     60        charset_attr = operation.attributes[0]
     61        expected = ipp.AttributesCharset(charset_attr.values[0].value)
     62        if charset_attr != expected:
     63            raise ipp.errors.ClientErrorBadRequest(str(charset_attr))
     64        if charset_attr.values[0].value != 'utf-8':
     65            raise ipp.errors.ClientErrorAttributes(str(charset_attr))
     66
     67        # check for attributes-natural-language
     68        natlang_attr = operation.attributes[1]
     69        expected = ipp.AttributesNaturalLanguage(natlang_attr.values[0].value)
     70        if natlang_attr != expected:
     71            raise ipp.errors.ClientErrorBadRequest(str(natlang_attr))
     72        if natlang_attr.values[0].value != 'en-us':
     73            raise ipp.errors.ClientErrorAttributes(str(natlang_attr))
    2974   
    3075    def handle(self, request):
     
    3681                handler_name = d
    3782                break
     83
    3884        # we couldn't find a handler, so default to unknown operation
    3985        if handler_name is None:
    4086            handler_name = "unknown_operation"
    41         # call the handler
     87
     88        # actually get the handler
    4289        handler = getattr(self, handler_name)
    4390        logger.info("Handling request of type '%s'" % handler_name)
    4491
    45         # Try to handle the request
     92        # try to handle the request
    4693        try:
    47             response = handler(request)
     94            self.generic_handle(request)
     95            response = make_empty_response(request)
     96            handler(request, response)
    4897
    4998        # Handle any errors that occur.  If an exception occurs that
     
    53102            exctype, excval, exctb = sys.exc_info()
    54103            logger.error("%s: %s" % (exctype.__name__, excval.message))
    55             response = ipp.operations.make_empty_response(request)
     104            response = make_empty_response(request)
    56105            excval.update_response(response)
    57106
     
    60109        except Exception:
    61110            logger.error(traceback.format_exc())
    62             response = ipp.operations.make_empty_response(request)
     111            response = make_empty_response(request)
    63112            response.operation_id = ipp.StatusCodes.INTERNAL_ERROR
    64113
    65114        return response
    66115
    67     def unknown_operation(self, request):
     116    def unknown_operation(self, request, response):
    68117        logger.warning("Received unknown operation 0x%x" % request.operation_id)
    69         response = ipp.operations.make_empty_response(request)
     118        response = make_empty_response(request)
    70119        response.operation_id = ipp.StatusCodes.OPERATION_NOT_SUPPORTED
    71120        return response
     
    74123
    75124    @handler_for(ipp.OperationCodes.PRINT_JOB)
    76     def print_job(self, request):
     125    def print_job(self, request, response):
    77126        """RFC 2911: 3.2.1 Print-Job Operation
    78127
     
    83132        Operation and Job Template attributes.
    84133
     134        Request
     135        -------
     136        Group 1: Operation Attributes
     137            REQUIRED 'attributes-charset'
     138            REQUIRED 'attributes-natural-language'
     139            REQUIRED 'printer-uri' (uri)
     140            OPTIONAL 'requesting-user-name' (name(MAX))
     141            OPTIONAL 'job-name' (name(MAX))
     142            OPTIONAL 'ipp-attribute-fidelity' (boolean)
     143            OPTIONAL 'document-name' (name(MAX))
     144            OPTIONAL 'compression' (type3 keyword)
     145            OPTIONAL 'document-format' (mimeMediaType)
     146            OPTIONAL 'document-natural-language' (naturalLanguage)
     147            OPTIONAL 'job-k-octets' (integer(0:MAX))
     148            OPTIONAL 'job-impressions' (integer(0:MAX))
     149            OPTIONAL 'job-media-sheets' (integer(0:MAX))
     150        Group 2: Job Template Attributes
     151        Group 3: Document Content
     152
     153        Response
     154        --------
     155        Group 1: Operation Attributes
     156            OPTIONAL 'status-message' (text(255))
     157            OPTIONAL 'detailed-status-message' (text(MAX))
     158            REQUIRED 'attributes-charset'
     159            REQUIRED 'attributes-natural-language'
     160        Group 2: Unsupported Attributes
     161        Group 3: Job Object Attributes
     162            REQUIRED 'job-uri' (uri)
     163            REQUIRED 'job-id' (integer(1:MAX))
     164            REQUIRED 'job-state' (type1 enum)
     165            REQUIRED 'job-state-reasons' (1setOf type2 keyword)
     166            OPTIONAL 'job-state-message' (text(MAX))
     167            OPTIONAL 'number-of-intervening-jobs' (integer(0:MAX))
     168
    85169        """
    86170       
     
    88172
    89173    @handler_for(ipp.OperationCodes.VALIDATE_JOB)
    90     def validate_job(self, request):
     174    def validate_job(self, request, response):
    91175
    92176        raise ipp.errors.ServerErrorOperationNotSupported
    93177
    94178    @handler_for(ipp.OperationCodes.GET_JOBS)
    95     def get_jobs(self, request):
    96         """RFC 2911: 3.2.6 Get-Jobs Operation
     179    def get_jobs(self, request, response):
     180        """3.2.6 Get-Jobs Operation
    97181       
    98182        This REQUIRED operation allows a client to retrieve the list
     
    106190        possibly more than one object.
    107191
    108         """
    109 
    110         # verify the request and get an attribute dictionary
    111         req_dict = ipp.operations.verify_get_jobs_request(request)
    112 
    113         # lookup printer name
    114         printer_name = req_dict['printer-uri']
     192        Request
     193        -------
     194        Group 1: Operation Attributes
     195            REQUIRED 'attributes-charset'
     196            REQUIRED 'attributes-natural-language'
     197            REQUIRED 'printer-uri' (uri)
     198            OPTIONAL 'requesting-user-name' (name(MAX))
     199            OPTIONAL 'limit' (integer(1:MAX))
     200            OPTIONAL 'requested-attributes' (1setOf type2 keyword)
     201            OPTIONAL 'which-jobs' (type2 keyword)
     202            OPTIONAL 'my-jobs' (boolean)
     203
     204        Response
     205        --------
     206        Group 1: Operation Attributes
     207            OPTIONAL 'status-message' (text(255))
     208            OPTIONAL 'detailed-status-message' (text(MAX))
     209            REQUIRED 'attributes-charset'
     210            REQUIRED 'attributes-natural-language'
     211        Group 2: Unsupported Attributes
     212        Groups 3 to N: Job Object Attributes
     213
     214        """
     215
     216        operation = request.attribute_groups[0]
     217
     218        # requested printer uri
     219        if 'printer-uri' not in operation:
     220            raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
     221        uri_attr = operation['printer-uri']
     222        printer_name = uri_attr.values[0].value.split("/")[-1]
     223        if uri_attr != ipp.PrinterUri(uri_attr.values[0].value):
     224            raise ipp.errors.ClientErrorBadRequest(str(uri_attr))
    115225        if printer_name not in self.printers:
    116             raise ipp.errors.ClientErrorAttributes(
    117                 "Invalid printer uri: %s" % printer_name,
    118                 [request.attribute_groups[0].attributes[2]])
    119 
    120         # get the job attributes
    121         jobs = [job.get_job_attributes(request) for job in \
    122                 self.printers[printer_name].get_jobs()]
    123 
    124         # build the response
    125         response = ipp.operations.make_get_jobs_response(jobs, request)
    126         return response
     226            raise ipp.errors.ClientErrorAttributes(str(uri_attr), uri_attr)
     227        jobs = self.printers[printer_name].get_jobs()
     228
     229        # requesting username
     230        if 'requesting-user-name' in operation:
     231            username_attr = operation['requesting-user-name']
     232            username = username_attr.values[0].value
     233            if username_attr != ipp.RequestingUserName(username):
     234                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
     235
     236        # get the job attributes and add them to the response
     237        for job in self.printers[printer_name].get_jobs():
     238            attrs = job.get_job_attributes(request)
     239            response.attribute_groups.append(ipp.AttributeGroup(
     240                ipp.AttributeTags.JOB, attrs))
    127241
    128242    @handler_for(ipp.OperationCodes.PRINT_URI)
    129     def print_uri(self, request):
     243    def print_uri(self, request, response):
    130244        raise ipp.errors.ServerErrorOperationNotSupported
    131245
    132246    @handler_for(ipp.OperationCodes.CREATE_JOB)
    133     def create_job(self, request):
     247    def create_job(self, request, response):
    134248        """RFC 2911: 3.2.4 Create-Job Operation
    135249
     
    146260        in the multi-document Job object.
    147261
    148         If a Printer object supports the Create-Job operation, it MUST
    149         also support the Send-Document operation and also MAY support
    150         the Send-URI operation.
    151        
    152         If the Printer object supports this operation, it MUST support
    153         the 'multiple-operation-time-out' Printer attribute (see
    154         section 4.4.31).  If the Printer object supports this
    155         operation, then it MUST support the
    156         'multiple-document-jobs-supported' Printer Description
    157         attribute (see section 4.4.16) and indicate whether or not it
    158         supports multiple-document jobs.
    159        
    160         If the Printer object supports this operation and supports
    161         multiple documents in a job, then it MUST support the
    162         'multiple-document- handling' Job Template job attribute with
    163         at least one value (see section 4.2.4) and the associated
    164         'multiple-document-handling- default' and
    165         'multiple-document-handling-supported' Job Template Printer
    166         attributes (see section 4.2).
    167        
    168         After the Create-Job operation has completed, the value of the
    169         'job- state' attribute is similar to the 'job-state' after a
    170         Print-Job, even though no document-data has arrived. A Printer
    171         MAY set the 'job-data-insufficient' value of the job's
    172         'job-state-reason' attribute to indicate that processing
    173         cannot begin until sufficient data has arrived and set the
    174         'job-state' to either 'pending' or 'pending-held'. A
    175         non-spooling printer that doesn't implement the 'pending' job
    176         state may even set the 'job-state' to 'processing', even
    177         though there is not yet any data to process. See sections
    178         4.3.7 and 4.3.8.
     262        Group 1: Operation Attributes
    179263       
    180264        """
     
    183267   
    184268    @handler_for(ipp.OperationCodes.PAUSE_PRINTER)
    185     def pause_printer(self, request):
     269    def pause_printer(self, request, response):
    186270        raise ipp.errors.ServerErrorOperationNotSupported
    187271
    188272    @handler_for(ipp.OperationCodes.RESUME_PRINTER)
    189     def resume_printer(self, request):
     273    def resume_printer(self, request, response):
    190274        raise ipp.errors.ServerErrorOperationNotSupported
    191275
    192276    @handler_for(ipp.OperationCodes.GET_PRINTER_ATTRIBUTES)
    193     def get_printer_attributes(self, request):
     277    def get_printer_attributes(self, request, response):
    194278        """RFC 2911: 3.2.5 Get-Printer-Attributes Operation
    195279
     
    203287        attribute values filled in.
    204288
    205         For Printer objects, the possible names of attribute groups are:
     289        Request
     290        -------
     291
     292        Group 1: Operation Attributes
     293            REQUIRED 'attributes-charset'
     294            REQUIRED 'attributes-natural-language'
     295            REQUIRED 'printer-uri' (uri)
     296            OPTIONAL 'requesting-user-name' (name(MAX))
     297            OPTIONAL 'requested-attributes' (1setOf type2 keyword)
     298            OPTIONAL 'document-format' (mimeMediaType):
     299
     300        Response
     301        --------
     302
     303        Group 1: Operation Attributes
     304            OPTIONAL 'status-message' (text(255))
     305            OPTIONAL 'detailed-status-message' (text(MAX))
     306            REQUIRED 'attributes-charset'
     307            REQUIRED 'attributes-natural-language'
     308        Group 2: Unsupported Attributes
     309        Group 3: Printer Object Attributes
     310
     311        """
     312
     313        operation = request.attribute_groups[0]
     314
     315        # requested printer uri
     316        if 'printer-uri' not in operation:
     317            raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
     318        uri_attr = operation['printer-uri']
     319        printer_name = uri_attr.values[0].value.split("/")[-1]
     320        if uri_attr != ipp.PrinterUri(uri_attr.values[0].value):
     321            raise ipp.errors.ClientErrorBadRequest(str(uri_attr))
     322        if printer_name not in self.printers:
     323            raise ipp.errors.ClientErrorAttributes(str(uri_attr), uri_attr)
     324        printer = self.printers[printer_name]
     325
     326        # requesting username
     327        if 'requesting-user-name' in operation:
     328            username_attr = operation['requesting-user-name']
     329            username = username_attr.values[0].value
     330            if username_attr != ipp.RequestingUserName(username):
     331                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
     332
     333        # get attributes from the printer and add to response
     334        response.attribute_groups.append(ipp.AttributeGroup(
     335            ipp.AttributeTags.PRINTER, printer.get_printer_attributes(request)))
     336
     337    @handler_for(ipp.OperationCodes.SET_PRINTER_ATTRIBUTES)
     338    def set_printer_attributes(self, request, response):
     339        raise ipp.errors.ServerErrorOperationNotSupported
     340
     341    ##### Job Commands
     342
     343    @handler_for(ipp.OperationCodes.CANCEL_JOB)
     344    def cancel_job(self, request, response):
     345        raise ipp.errors.ServerErrorOperationNotSupported
     346
     347    @handler_for(ipp.OperationCodes.SEND_DOCUMENT)
     348    def send_document(self, request, response):
     349        raise ipp.errors.ServerErrorOperationNotSupported
     350
     351    @handler_for(ipp.OperationCodes.SEND_URI)
     352    def send_uri(self, request, response):
     353        raise ipp.errors.ServerErrorOperationNotSupported
     354
     355    @handler_for(ipp.OperationCodes.GET_JOB_ATTRIBUTES)
     356    def get_job_attributes(self, request, response):
    206357       
    207         - 'job-template': the subset of the Job Template attributes
    208           that apply to a Printer object (the last two columns of the
    209           table in Section 4.2) that the implementation supports for
    210           Printer objects.
    211 
    212         - 'printer-description': the subset of the attributes
    213           specified in Section 4.4 that the implementation supports
    214           for Printer objects.
    215 
    216         - 'all': the special group 'all' that includes all attributes
    217           that the implementation supports for Printer objects.
    218        
    219         Since a client MAY request specific attributes or named
    220         groups, there is a potential that there is some overlap. For
    221         example, if a client requests, 'printer-name' and 'all', the
    222         client is actually requesting the 'printer-name' attribute
    223         twice: once by naming it explicitly, and once by inclusion in
    224         the 'all' group. In such cases, the Printer object NEED NOT
    225         return each attribute only once in the response even if it is
    226         requested multiple times. The client SHOULD NOT request the
    227         same attribute in multiple ways.
    228 
    229         It is NOT REQUIRED that a Printer object support all
    230         attributes belonging to a group (since some attributes are
    231         OPTIONAL). However, it is REQUIRED that each Printer object
    232         support all group names.
    233 
    234         """
    235 
    236         # verify the request and get the attributes dictionary
    237         req_dict = ipp.operations.verify_get_printer_attributes_request(request)
    238 
    239         # lookup the printer name
    240         printer_name = req_dict['printer-uri']
     358        operation = request.attribute_groups[0]
     359
     360        # requested printer uri
     361        if 'printer-uri' not in operation:
     362            raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
     363        uri_attr = operation['printer-uri']
     364        printer_name = uri_attr.values[0].value.split("/")[-1]
     365        if uri_attr != ipp.PrinterUri(uri_attr.values[0].value):
     366            raise ipp.errors.ClientErrorBadRequest(str(uri_attr))
    241367        if printer_name not in self.printers:
    242             raise ipp.errors.ClientErrorAttributes(
    243                 "Invalid printer uri: %s" % printer_name,
    244                 [request.attribute_groups[0].attributes[2]])
    245 
    246         # bulid response
    247         response = ipp.operations.make_get_printer_attributes_response(
    248             self.printers[printer_name].get_printer_attributes(request), request)
    249         return response
    250 
    251     @handler_for(ipp.OperationCodes.SET_PRINTER_ATTRIBUTES)
    252     def set_printer_attributes(self, request):
    253         raise ipp.errors.ServerErrorOperationNotSupported
    254 
    255     ##### Job Commands
    256 
    257     @handler_for(ipp.OperationCodes.CANCEL_JOB)
    258     def cancel_job(self, request):
    259         raise ipp.errors.ServerErrorOperationNotSupported
    260 
    261     @handler_for(ipp.OperationCodes.SEND_DOCUMENT)
    262     def send_document(self, request):
    263         raise ipp.errors.ServerErrorOperationNotSupported
    264 
    265     @handler_for(ipp.OperationCodes.SEND_URI)
    266     def send_uri(self, request):
    267         raise ipp.errors.ServerErrorOperationNotSupported
    268 
    269     @handler_for(ipp.OperationCodes.GET_JOB_ATTRIBUTES)
    270     def get_job_attributes(self, request):
    271        
    272         # verify the request and get the attributes dictionary
    273         req_dict = ipp.operations.verify_get_jobs_request(request)
    274        
    275         # lookup the printer name
    276         printer_name = req_dict['printer-uri']
    277         if printer_name not in self.printers:
    278             raise ipp.errors.ClientErrorAttributes(
    279                 "Invalid printer uri: %s" % printer_name,
    280                 [request.attribute_groups[0].attributes[2]])
    281 
    282         # lookup the job id
    283         job_id = req_dict['job-id']
    284         try: job = self.printers[printer_name].get_job(job_id)
    285         except InvalidJobException:
    286             raise ipp.errors.ClientErrorAttributes(
    287                 "Invalid job id: %d" % job_id,
    288                 [request.attribute_groups[0].attributes[2]]) # XXX: this is wrong
    289 
    290         # XXX: we need to honor the things that the request actually asks for
    291         # build the response
    292         response = ipp.operations.make_get_job_attributes_response(
    293             job.get_job_attributes(request), request)
    294         return response
     368            raise ipp.errors.ClientErrorAttributes(str(uri_attr), uri_attr)
     369        printer = self.printers[printer_name]
     370
     371        if 'job-id' not in operation:
     372            raise ipp.errors.ClientErrorBadRequest("Missing 'job-id' attribute")
     373        job_id_attr = operation['job-id']
     374        job_id = job_id_attr.values[0].value
     375        if job_id_attr != ipp.JobId(job_id_attr.values[0].value):
     376            raise ipp.errors.ClientErrorBadRequest(str(job_id_attr))
     377        if job_id not in printer.jobs:
     378            raise ipp.errors.ClientErrorAttributes(str(job_id_attr))
     379        job = printer.get_job(job_id)
     380
     381        # requesting username
     382        if 'requesting-user-name' in operation:
     383            username_attr = operation['requesting-user-name']
     384            username = username_attr.values[0].value
     385            if username_attr != ipp.RequestingUserName(username):
     386                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
     387
     388        # get the job attributes and add them to the response
     389        attrs = job.get_job_attributes(request)
     390        response.attribute_groups.append(ipp.AttributeGroup(
     391            ipp.AttributeTags.JOB, attrs))
    295392
    296393    @handler_for(ipp.OperationCodes.SET_JOB_ATTRIBUTES)
    297     def set_job_attributes(self, request):
     394    def set_job_attributes(self, request, response):
    298395        raise ipp.errors.ServerErrorOperationNotSupported
    299396
    300397    @handler_for(ipp.OperationCodes.RESTART_JOB)
    301     def restart_job(self, request):
     398    def restart_job(self, request, response):
    302399        raise ipp.errors.ServerErrorOperationNotSupported
    303400
    304401    @handler_for(ipp.OperationCodes.PROMOTE_JOB)
    305     def promote_job(self, request):
     402    def promote_job(self, request, response):
    306403        raise ipp.errors.ServerErrorOperationNotSupported
    307404
     
    309406
    310407    @handler_for(ipp.OperationCodes.CUPS_GET_DOCUMENT)
    311     def cups_get_document(self, request):
     408    def cups_get_document(self, request, response):
    312409        raise ipp.errors.ServerErrorOperationNotSupported
    313410
    314411    @handler_for(ipp.OperationCodes.CUPS_GET_DEFAULT)
    315     def cups_get_default(self, request):
     412    def cups_get_default(self, request, response):
    316413        """The CUPS-Get-Default operation (0x4001) returns the default
    317414        printer URI and attributes.
    318415
     416        Request
     417        -------
     418
     419        Group 1: Operation Attributes
     420            REQUIRED 'attributes-charset'
     421            REQUIRED 'attributes-natural-language'
     422            OPTIONAL 'requested-attributes' (1setOf type2 keyword)
     423
     424        Response
     425        --------
     426
     427        Group 1: Operation Attributes
     428            OPTIONAL 'status-message' (text(255))
     429            REQUIRED 'attributes-charset'
     430            REQUIRED 'attributes-natural-language'
     431        Group 2: Printer Object Attributes
     432
    319433        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_DEFAULT )
    320434
    321435        """
    322436
    323         # verify the request and get the attributes dictionary
    324         req_dict = ipp.operations.verify_cups_get_default_request(request)
    325         # build the response
    326         response = ipp.operations.make_get_printer_attributes_response(
    327             self.printers[self.default].get_printer_attributes(request), request)
    328         return response
     437        operation = request.attribute_groups[0]
     438        printer = self.printers[self.default]
     439
     440        # requesting username
     441        if 'requesting-user-name' in operation:
     442            username_attr = operation['requesting-user-name']
     443            username = username_attr.values[0].value
     444            if username_attr != ipp.RequestingUserName(username):
     445                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
     446
     447        # get attributes from the printer and add to response
     448        response.attribute_groups.append(ipp.AttributeGroup(
     449            ipp.AttributeTags.PRINTER, printer.get_printer_attributes(request)))
    329450
    330451    @handler_for(ipp.OperationCodes.CUPS_GET_PRINTERS)
    331     def cups_get_printers(self, request):
     452    def cups_get_printers(self, request, response):
    332453        """The CUPS-Get-Printers operation (0x4002) returns the
    333454        printer attributes for every printer known to the system. This
     
    339460        """
    340461
    341         # verify the request and get the attributes dictionary
    342         req_dict = ipp.operations.verify_cups_get_printers_request(request)
    343         # get the printer attributes
    344         attrs = [self.printers[printer].get_printer_attributes(request) \
    345                  for printer in self.printers]
    346         # build the response
    347         response = ipp.operations.make_cups_get_printers_response(attrs, request)
    348         return response
     462        operation = request.attribute_groups[0]
     463
     464        # requesting username
     465        if 'requesting-user-name' in operation:
     466            username_attr = operation['requesting-user-name']
     467            username = username_attr.values[0].value
     468            if username_attr != ipp.RequestingUserName(username):
     469                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
     470
     471        # get attributes from the printer and add to response
     472        for printer in self.printers.values():
     473            response.attribute_groups.append(ipp.AttributeGroup(
     474                ipp.AttributeTags.PRINTER, printer.get_printer_attributes(request)))
    349475
    350476    @handler_for(ipp.OperationCodes.CUPS_GET_CLASSES)
    351     def cups_get_classes(self, request):
     477    def cups_get_classes(self, request, response):
    352478        """The CUPS-Get-Classes operation (0x4005) returns the printer
    353479        attributes for every printer class known to the system. This
    354480        may include printer classes that are not served directly by
    355481        the server.
    356        
     482
     483        Request
     484        -------
     485
     486        Group 1: Operation Attributes
     487            REQUIRED 'attributes-charset'
     488            REQUIRED 'attributes-natural-language'
     489            OPTIONAL 'first-printer-name' (name(127)) CUPS 1.2/Mac OS X 10.5
     490            OPTIONAL 'limit' (integer (1:MAX))
     491            OPTIONAL 'printer-location' (text(127)) CUPS 1.1.7
     492            OPTIONAL 'printer-type' (type2 enum) CUPS 1.1.7
     493            OPTIONAL 'printer-type-mask' (type2 enum) CUPS 1.1.7
     494            OPTIONAL 'requested-attributes' (1setOf keyword)
     495            OPTOINAL 'requested-user-name' (name(127)) CUPS 1.2/Mac OS X 10.5
     496            OPTIONAL 'requested-attributes' (1setOf type2 keyword)
     497
     498        Response
     499        --------
     500
     501        Group 1: Operation Attributes
     502            OPTIONAL 'status-message' (text(255))
     503            REQUIRED 'attributes-charset'
     504            REQUIRED 'attributes-natural-language'
     505        Group 2: Printer Class Object Attributes
     506
    357507        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_CLASSES )
    358508
    359509        """
    360510
    361         # verify the request and get the attributes dictionaryu
    362         req_dict = ipp.operations.verify_cups_get_classes_request(request)
    363         # build the response
    364         response = ipp.operations.make_cups_get_classes_response(request)
    365         return response
     511        raise ipp.errors.ServerErrorOperationNotSupported
     512
Note: See TracChangeset for help on using the changeset viewer.