source: server/lib/gutenbach/server/requests.py @ cad7502

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

Fix bugs; can now again do 'lpq' and get back a reasonable response

  • Property mode set to 100644
File size: 16.4 KB
Line 
1from gutenbach.server.printer import GutenbachPrinter
2import gutenbach.ipp as ipp
3import gutenbach.ipp.constants as const
4from gutenbach.ipp.constants import job_attribute_value_tags, printer_attribute_value_tags
5import logging
6
7# initialize logger
8logger = logging.getLogger(__name__)
9
10def handler_for(operation):
11    """A decorator method to mark a function with the operation id
12    that it handles.  This value will be stored in
13    'func.ipp_operation'.
14
15    """
16   
17    def f(func):
18        func.ipp_operation = operation
19        return func
20    return f
21
22class GutenbachRequestHandler(object):
23
24    def __init__(self):
25        self.printers = {
26            "test": GutenbachPrinter(name="test")
27            }
28        self.default = "test"
29   
30    def handle(self, request, response):
31        # look up the handler
32        handler = None
33        handler_name = None
34        for d in dir(self):
35            if getattr(getattr(self, d), "ipp_operation", None) == request.operation_id:
36                handler_name = d
37                break
38        # we couldn't find a handler, so default to unknown operation
39        if handler_name is None:
40            handler_name = "unknown_operation"
41        # call the handler
42        handler = getattr(self, handler_name)
43        logger.info("Handling request of type '%s'" % handler_name)
44        handler(request, response)
45
46    def unknown_operation(self, request, response):
47        logger.warning("Received unknown operation 0x%x" % request.operation_id)
48        response.operation_id = const.StatusCodes.OPERATION_NOT_SUPPORTED
49
50    ##### Helper functions
51
52    def _get_printer_attributes(self, printer, request, response):
53        attrs = printer.get_printer_attributes(request)
54        ipp_attrs = []
55        for attr, vals in attrs:
56            ipp_vals = [ipp.Value(
57                tag=printer_attribute_value_tags[attr],
58                value=val) for val in vals]
59            ipp_attrs.append(ipp.Attribute(name=attr, values=ipp_vals))
60        response.attribute_groups.append(ipp.AttributeGroup(
61            const.AttributeTags.PRINTER, ipp_attrs))
62
63    def _get_job_attributes(self, job, request, response):
64        attrs = job.get_job_attributes(request)
65        ipp_attrs = []
66        for attr, vals in attrs:
67            ipp_vals = [ipp.Value(
68                tag=job_attribute_value_tags[attr],
69                value=val) for val in vals]
70            ipp_attrs.append(ipp.Attribute(name=attr, values=ipp_vals))
71        response.attribute_groups.append(ipp.AttributeGroup(
72            const.AttributeTags.JOB, ipp_attrs))
73
74    def _get_job_id(self, request):
75        pass
76       
77    ##### Printer Commands
78
79    def print_job(self, request, response):
80        pass
81
82    def validate_job(self, request, response):
83        pass
84
85    @handler_for(const.Operations.GET_JOBS)
86    def get_jobs(self, request, response):
87        """RFC 2911: 3.2.6 Get-Jobs Operation
88       
89        This REQUIRED operation allows a client to retrieve the list
90        of Job objects belonging to the target Printer object. The
91        client may also supply a list of Job attribute names and/or
92        attribute group names. A group of Job object attributes will
93        be returned for each Job object that is returned.
94
95        This operation is similar to the Get-Job-Attributes operation,
96        except that this Get-Jobs operation returns attributes from
97        possibly more than one object.
98
99        """
100       
101        reqdict = ipp.ops.verify_get_jobs_request(request)
102        printer_name = reqdict['printer-uri']
103        if printer_name not in self.printers:
104            raise ipp.errors.Attributes(
105                "Invalid printer uri: %s" % printer_name,
106                [request.attribute_groups[0].attributes[2]])
107
108        # Each job will append a new job attribute group.
109        # XXX: we need to honor the things that the request actually asks for
110        for job in self.printers[printer_name].get_jobs():
111            self._get_job_attributes(job, request, response)
112
113    def print_uri(self, request, response):
114        pass
115
116    def create_job(self, request, response):
117        pass
118
119    def pause_printer(self, request, response):
120        pass
121
122    def resume_printer(self, request, response):
123        pass
124
125    @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES)
126    def get_printer_attributes(self, request, response):
127        """RFC 2911: 3.2.5 Get-Printer-Attributes Operation
128
129        This REQUIRED operation allows a client to request the values
130        of the attributes of a Printer object.
131       
132        In the request, the client supplies the set of Printer
133        attribute names and/or attribute group names in which the
134        requester is interested. In the response, the Printer object
135        returns a corresponding attribute set with the appropriate
136        attribute values filled in.
137
138        For Printer objects, the possible names of attribute groups are:
139       
140        - 'job-template': the subset of the Job Template attributes
141          that apply to a Printer object (the last two columns of the
142          table in Section 4.2) that the implementation supports for
143          Printer objects.
144
145        - 'printer-description': the subset of the attributes
146          specified in Section 4.4 that the implementation supports
147          for Printer objects.
148
149        - 'all': the special group 'all' that includes all attributes
150          that the implementation supports for Printer objects.
151       
152        Since a client MAY request specific attributes or named
153        groups, there is a potential that there is some overlap. For
154        example, if a client requests, 'printer-name' and 'all', the
155        client is actually requesting the 'printer-name' attribute
156        twice: once by naming it explicitly, and once by inclusion in
157        the 'all' group. In such cases, the Printer object NEED NOT
158        return each attribute only once in the response even if it is
159        requested multiple times. The client SHOULD NOT request the
160        same attribute in multiple ways.
161
162        It is NOT REQUIRED that a Printer object support all
163        attributes belonging to a group (since some attributes are
164        OPTIONAL). However, it is REQUIRED that each Printer object
165        support all group names.
166
167        """
168
169        # this is just like cups_get_default, except the printer name
170        # is given
171        reqdict = ipp.ops.verify_get_printer_attributes_request(request)
172        printer_name = reqdict['printer-uri']
173        if printer_name not in self.printers:
174            raise ipp.errors.Attributes(
175                "Invalid printer uri: %s" % printer_name,
176                [request.attribute_groups[0].attributes[2]])
177       
178        self._get_printer_attributes(self.printers[printer_name], request, response)
179
180    def set_printer_attributes(self, request, response):
181        pass
182
183    ##### Job Commands
184
185    def cancel_job(self, request, response):
186        pass
187
188    def send_document(self, request, response):
189        pass
190
191    def send_uri(self, request, response):
192        pass
193
194    def get_job_attributes(self, request, response):
195        reqdict = ipp.ops.verify_get_jobs_request(request)
196        printer_name = reqdict['printer-uri']
197        job_id = reqdict['job-id']
198       
199        if printer_name not in self.printers:
200            raise ipp.errors.Attributes(
201                "Invalid printer uri: %s" % printer_name,
202                [request.attribute_groups[0].attributes[2]])
203        try:
204            job = self.printers[printer_name].get_job(job_id)
205        except InvalidJobException:
206            raise ipp.errors.Attributes(
207                "Invalid job id: %d" % job_id,
208                [request.attribute_groups[0].attributes[2]]) # XXX: this is wrong
209
210        # Each job will append a new job attribute group.
211        # XXX: we need to honor the things that the request actually asks for
212        self._get_job_attributes(job, request, response)
213
214    def set_job_attributes(self, request, response):
215        pass
216
217    def cups_get_document(self, request, response):
218        pass
219
220    def restart_job(self, request, response):
221        pass
222
223    def promote_job(self, request, response):
224        pass
225
226    ##### CUPS Specific Commands
227
228    @handler_for(const.Operations.CUPS_GET_DEFAULT)
229    def cups_get_default(self, request, response):
230        """The CUPS-Get-Default operation (0x4001) returns the default
231        printer URI and attributes.
232
233        CUPS-Get-Default Request
234        ------------------------
235
236        The following groups of attributes are supplied as part of the
237        CUPS-Get-Default request:
238
239        Group 1: Operation Attributes
240            Natural Language and Character Set:
241                The 'attributes-charset' and
242                'attributes-natural-language' attributes as described
243                in section 3.1.4.1 of the IPP Model and Semantics
244                document.
245            'requested-attributes' (1setOf keyword):
246                The client OPTIONALLY supplies a set of attribute
247                names and/or attribute group names in whose values the
248                requester is interested. If the client omits this
249                attribute, the server responds as if this attribute
250                had been supplied with a value of 'all'.
251       
252        CUPS-Get-Default Response
253        -------------------------
254
255        The following groups of attributes are send as part of the
256        CUPS-Get-Default Response:
257
258        Group 1: Operation Attributes
259            Status Message:
260                The standard response status message.
261            Natural Language and Character Set:
262                The 'attributes-charset' and
263                'attributes-natural-language' attributes as described
264                in section 3.1.4.2 of the IPP Model and Semantics
265                document.
266
267        Group 2: Printer Object Attributes
268            The set of requested attributes and their current values.
269
270        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_DEFAULT )
271
272        """
273           
274        self._get_printer_attributes(self.printers[self.default], request, response)
275
276    @handler_for(const.Operations.CUPS_GET_PRINTERS)
277    def cups_get_printers(self, request, response):
278        """
279        The CUPS-Get-Printers operation (0x4002) returns the printer
280        attributes for every printer known to the system. This may
281        include printers that are not served directly by the server.
282
283        CUPS-Get-Printers Request
284        -------------------------
285       
286        The following groups of attributes are supplied as part of the
287        CUPS-Get-Printers request:
288
289        Group 1: Operation Attributes
290            Natural Language and Character Set:
291                The 'attributes-charset' and
292                'attributes-natural-language' attributes as described
293                in section 3.1.4.1 of the IPP Model and Semantics
294                document.
295            'first-printer-name' (name(127)):CUPS 1.2/Mac OS X 10.5
296                The client OPTIONALLY supplies this attribute to
297                select the first printer that is returned.
298            'limit' (integer (1:MAX)):
299                The client OPTIONALLY supplies this attribute limiting
300                the number of printers that are returned.
301            'printer-location' (text(127)): CUPS 1.1.7
302                The client OPTIONALLY supplies this attribute to
303                select which printers are returned.
304            'printer-type' (type2 enum): CUPS 1.1.7
305                The client OPTIONALLY supplies a printer type
306                enumeration to select which printers are returned.
307            'printer-type-mask' (type2 enum): CUPS 1.1.7
308                The client OPTIONALLY supplies a printer type mask
309                enumeration to select which bits are used in the
310                'printer-type' attribute.
311            'requested-attributes' (1setOf keyword) :
312                The client OPTIONALLY supplies a set of attribute
313                names and/or attribute group names in whose values the
314                requester is interested. If the client omits this
315                attribute, the server responds as if this attribute
316                had been supplied with a value of 'all'.
317            'requested-user-name' (name(127)) : CUPS 1.2/Mac OS X 10.5
318                The client OPTIONALLY supplies a user name that is
319                used to filter the returned printers.
320
321        CUPS-Get-Printers Response
322        --------------------------
323
324        The following groups of attributes are send as part of the
325        CUPS-Get-Printers Response:
326
327        Group 1: Operation Attributes
328            Status Message:
329                The standard response status message.
330            Natural Language and Character Set:
331                The 'attributes-charset' and
332                'attributes-natural-language' attributes as described
333                in section 3.1.4.2 of the IPP Model and Semantics
334                document.
335               
336        Group 2: Printer Object Attributes
337            The set of requested attributes and their current values
338            for each printer.
339
340        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_PRINTERS )
341           
342        """
343
344        # Each printer will append a new printer attribute group.
345        for printer in self.printers:
346            self._get_printer_attributes(self.printers[printer], request, response)
347
348    @handler_for(const.Operations.CUPS_GET_CLASSES)
349    def cups_get_classes(self, request, response):
350        """The CUPS-Get-Classes operation (0x4005) returns the printer
351        attributes for every printer class known to the system. This
352        may include printer classes that are not served directly by
353        the server.
354
355        CUPS-Get-Classes Request
356        ------------------------
357
358        The following groups of attributes are supplied as part of the
359        CUPS-Get-Classes request:
360
361        Group 1: Operation Attributes
362            Natural Language and Character Set:
363                The 'attributes-charset' and
364                'attributes-natural-language' attributes as described
365                in section 3.1.4.1 of the IPP Model and Semantics
366                document.
367            'first-printer-name' (name(127)):CUPS 1.2/Mac OS X 10.5
368                The client OPTIONALLY supplies this attribute to
369                select the first printer that is returned.
370            'limit' (integer (1:MAX)):
371                The client OPTIONALLY supplies this attribute limiting
372                the number of printer classes that are returned.
373            'printer-location' (text(127)): CUPS 1.1.7
374                The client OPTIONALLY supplies this attribute to
375                select which printer classes are returned.
376            'printer-type' (type2 enum): CUPS 1.1.7
377                The client OPTIONALLY supplies a printer type
378                enumeration to select which printer classes are
379                returned.
380            'printer-type-mask' (type2 enum): CUPS 1.1.7
381                The client OPTIONALLY supplies a printer type mask
382                enumeration to select which bits are used in the
383                'printer-type' attribute.
384            'requested-attributes' (1setOf keyword) :
385                The client OPTIONALLY supplies a set of attribute
386                names and/or attribute group names in whose values the
387                requester is interested. If the client omits this
388                attribute, the server responds as if this attribute
389                had been supplied with a value of 'all'.
390            'requested-user-name' (name(127)) : CUPS 1.2/Mac OS X 10.5
391                The client OPTIONALLY supplies a user name that is
392                used to filter the returned printers.
393               
394        CUPS-Get-Classes Response
395        -------------------------
396
397        The following groups of attributes are send as part of the
398        CUPS-Get-Classes Response:
399
400        Group 1: Operation Attributes
401            Status Message:
402                The standard response status message.
403            Natural Language and Character Set:
404                The 'attributes-charset' and
405                'attributes-natural-language' attributes as described
406                in section 3.1.4.2 of the IPP Model and Semantics
407                document.
408
409        Group 2: Printer Class Object Attributes
410            The set of requested attributes and their current values
411            for each printer class.
412
413        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_CLASSES )
414
415        """
416       
417        # We have no printer classes, so we don't need to do anything
418        pass
Note: See TracBrowser for help on using the repository browser.