source: server/lib/gutenbach/server/requests.py @ 59a1d4a

no-cups
Last change on this file since 59a1d4a was 59a1d4a, checked in by Jessica B. Hamrick <jhamrick@…>, 12 years ago

A litte bit of documentation

  • Property mode set to 100644
File size: 9.4 KB
RevLine 
[738d179]1from gutenbach.server.printer import GutenbachPrinter
[b2e077a]2import gutenbach.ipp as ipp
[287d6ec]3import gutenbach.ipp.constants as const
4import logging
5
[d04a689]6# initialize logger
7logger = logging.getLogger(__name__)
[287d6ec]8
9def handler_for(operation):
10    """A decorator method to mark a function with the operation id
11    that it handles.  This value will be stored in
12    'func.ipp_operation'.
13
14    """
15   
16    def f(func):
17        func.ipp_operation = operation
18        return func
19    return f
20
[b2e077a]21class GutenbachRequestHandler(object):
[287d6ec]22
[b2e077a]23    def __init__(self):
24        self.printers = {
25            "test": GutenbachPrinter(name="test")
26            }
27        self.default = "test"
[287d6ec]28   
[ef8df33]29    def handle(self, request):
[b2e077a]30        # look up the handler
31        handler = None
[9eeab06]32        handler_name = None
[287d6ec]33        for d in dir(self):
34            if getattr(getattr(self, d), "ipp_operation", None) == request.operation_id:
[9eeab06]35                handler_name = d
[b2e077a]36                break
37        # we couldn't find a handler, so default to unknown operation
[9eeab06]38        if handler_name is None:
39            handler_name = "unknown_operation"
[b2e077a]40        # call the handler
[9eeab06]41        handler = getattr(self, handler_name)
[7bd1035]42        logger.info("Handling request of type '%s'" % handler_name)
[ef8df33]43        response = handler(request)
44        return response
[287d6ec]45
[ef8df33]46    def unknown_operation(self, request):
[9eeab06]47        logger.warning("Received unknown operation 0x%x" % request.operation_id)
[ef8df33]48        response = ipp.ops.make_empty_response(request)
[287d6ec]49        response.operation_id = const.StatusCodes.OPERATION_NOT_SUPPORTED
[ef8df33]50        return response
[0ede474]51       
[9eeab06]52    ##### Printer Commands
53
[ef8df33]54    def print_job(self, request):
[9eeab06]55        pass
56
[ef8df33]57    def validate_job(self, request):
[9eeab06]58        pass
59
60    @handler_for(const.Operations.GET_JOBS)
[ef8df33]61    def get_jobs(self, request):
[6ed9d7a]62        """RFC 2911: 3.2.6 Get-Jobs Operation
63       
64        This REQUIRED operation allows a client to retrieve the list
65        of Job objects belonging to the target Printer object. The
66        client may also supply a list of Job attribute names and/or
67        attribute group names. A group of Job object attributes will
68        be returned for each Job object that is returned.
69
70        This operation is similar to the Get-Job-Attributes operation,
71        except that this Get-Jobs operation returns attributes from
72        possibly more than one object.
73
74        """
[59a1d4a]75
76        # verify the request and get an attribute dictionary
[ef8df33]77        req_dict = ipp.ops.verify_get_jobs_request(request)
[59a1d4a]78
79        # lookup printer name
[ef8df33]80        printer_name = req_dict['printer-uri']
[5fe360e]81        if printer_name not in self.printers:
82            raise ipp.errors.Attributes(
83                "Invalid printer uri: %s" % printer_name,
84                [request.attribute_groups[0].attributes[2]])
[6ed9d7a]85
[59a1d4a]86        # get the job attributes
[ef8df33]87        jobs = [job.get_job_attributes(request) for job in \
88                self.printers[printer_name].get_jobs()]
[59a1d4a]89
90        # build the response
[ef8df33]91        response = ipp.ops.make_get_jobs_response(jobs, request)
92        return response
[287d6ec]93
[ef8df33]94    def print_uri(self, request):
[9eeab06]95        pass
96
[ef8df33]97    def create_job(self, request):
[9eeab06]98        pass
99
[ef8df33]100    def pause_printer(self, request):
[9eeab06]101        pass
102
[ef8df33]103    def resume_printer(self, request):
[9eeab06]104        pass
105
[287d6ec]106    @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES)
[ef8df33]107    def get_printer_attributes(self, request):
[cad7502]108        """RFC 2911: 3.2.5 Get-Printer-Attributes Operation
109
110        This REQUIRED operation allows a client to request the values
111        of the attributes of a Printer object.
112       
113        In the request, the client supplies the set of Printer
114        attribute names and/or attribute group names in which the
115        requester is interested. In the response, the Printer object
116        returns a corresponding attribute set with the appropriate
117        attribute values filled in.
118
119        For Printer objects, the possible names of attribute groups are:
120       
121        - 'job-template': the subset of the Job Template attributes
122          that apply to a Printer object (the last two columns of the
123          table in Section 4.2) that the implementation supports for
124          Printer objects.
125
126        - 'printer-description': the subset of the attributes
127          specified in Section 4.4 that the implementation supports
128          for Printer objects.
129
130        - 'all': the special group 'all' that includes all attributes
131          that the implementation supports for Printer objects.
132       
133        Since a client MAY request specific attributes or named
134        groups, there is a potential that there is some overlap. For
135        example, if a client requests, 'printer-name' and 'all', the
136        client is actually requesting the 'printer-name' attribute
137        twice: once by naming it explicitly, and once by inclusion in
138        the 'all' group. In such cases, the Printer object NEED NOT
139        return each attribute only once in the response even if it is
140        requested multiple times. The client SHOULD NOT request the
141        same attribute in multiple ways.
142
143        It is NOT REQUIRED that a Printer object support all
144        attributes belonging to a group (since some attributes are
145        OPTIONAL). However, it is REQUIRED that each Printer object
146        support all group names.
147
148        """
149
[59a1d4a]150        # verify the request and get the attributes dictionary
[ef8df33]151        req_dict = ipp.ops.verify_get_printer_attributes_request(request)
[59a1d4a]152
153        # lookup the printer name
[ef8df33]154        printer_name = req_dict['printer-uri']
[5fe360e]155        if printer_name not in self.printers:
156            raise ipp.errors.Attributes(
157                "Invalid printer uri: %s" % printer_name,
158                [request.attribute_groups[0].attributes[2]])
[59a1d4a]159
160        # bulid response
[ef8df33]161        response = ipp.ops.make_get_printer_attributes_response(
162            self.printers[printer_name].get_printer_attributes(request), request)
163        return response
[9eeab06]164
[ef8df33]165    def set_printer_attributes(self, request):
[9eeab06]166        pass
167
168    ##### Job Commands
169
[ef8df33]170    def cancel_job(self, request):
[9eeab06]171        pass
172
[ef8df33]173    def send_document(self, request):
[9eeab06]174        pass
175
[ef8df33]176    def send_uri(self, request):
[9eeab06]177        pass
178
[ef8df33]179    def get_job_attributes(self, request):
[59a1d4a]180       
181        # verify the request and get the attributes dictionary
[ef8df33]182        req_dict = ipp.ops.verify_get_jobs_request(request)
[5fe360e]183       
[59a1d4a]184        # lookup the printer name
185        printer_name = req_dict['printer-uri']
[5fe360e]186        if printer_name not in self.printers:
187            raise ipp.errors.Attributes(
188                "Invalid printer uri: %s" % printer_name,
189                [request.attribute_groups[0].attributes[2]])
[59a1d4a]190
191        # lookup the job id
192        job_id = req_dict['job-id']
193        try: job = self.printers[printer_name].get_job(job_id)
[5fe360e]194        except InvalidJobException:
195            raise ipp.errors.Attributes(
196                "Invalid job id: %d" % job_id,
197                [request.attribute_groups[0].attributes[2]]) # XXX: this is wrong
198
199        # XXX: we need to honor the things that the request actually asks for
[59a1d4a]200        # build the response
[ef8df33]201        response = ipp.ops.make_get_job_attributes_response(
202            job.get_job_attributes(request), request)
203        return response
[9eeab06]204
[ef8df33]205    def set_job_attributes(self, request):
[9eeab06]206        pass
207
[ef8df33]208    def cups_get_document(self, request):
[9eeab06]209        pass
210
[ef8df33]211    def restart_job(self, request):
[9eeab06]212        pass
213
[ef8df33]214    def promote_job(self, request):
[9eeab06]215        pass
216
217    ##### CUPS Specific Commands
218
219    @handler_for(const.Operations.CUPS_GET_DEFAULT)
[ef8df33]220    def cups_get_default(self, request):
[0ede474]221        """The CUPS-Get-Default operation (0x4001) returns the default
222        printer URI and attributes.
223
224        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_DEFAULT )
225
226        """
[287d6ec]227
[59a1d4a]228        # verify the request and get the attributes dictionary
[ef8df33]229        req_dict = ipp.ops.verify_cups_get_default_request(request)
[59a1d4a]230        # build the response
[ef8df33]231        response = ipp.ops.make_get_printer_attributes_response(
232            self.printers[self.default].get_printer_attributes(request), request)
233        return response
[0ede474]234
[ef8df33]235    @handler_for(const.Operations.CUPS_GET_PRINTERS)
236    def cups_get_printers(self, request):
237        """The CUPS-Get-Printers operation (0x4002) returns the
238        printer attributes for every printer known to the system. This
239        may include printers that are not served directly by the
240        server.
[0ede474]241
242        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_PRINTERS )
243           
244        """
245
[59a1d4a]246        # verify the request and get the attributes dictionary
[ef8df33]247        req_dict = ipp.ops.verify_cups_get_printers_request(request)
[59a1d4a]248        # get the printer attributes
[ef8df33]249        attrs = [self.printers[printer].get_printer_attributes(request) \
250                 for printer in self.printers]
[59a1d4a]251        # build the response
[ef8df33]252        response = ipp.ops.make_cups_get_printers_response(attrs, request)
253        return response
[287d6ec]254
255    @handler_for(const.Operations.CUPS_GET_CLASSES)
[ef8df33]256    def cups_get_classes(self, request):
[0ede474]257        """The CUPS-Get-Classes operation (0x4005) returns the printer
258        attributes for every printer class known to the system. This
259        may include printer classes that are not served directly by
260        the server.
[ef8df33]261       
[0ede474]262        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_CLASSES )
263
264        """
[ef8df33]265
[59a1d4a]266        # verify the request and get the attributes dictionaryu
[ef8df33]267        req_dict = ipp.ops.verify_cups_get_classes_request(request)
[59a1d4a]268        # build the response
[ef8df33]269        response = ipp.ops.make_cups_get_classes_response(request)
270        return response
Note: See TracBrowser for help on using the repository browser.