source: server/lib/gutenbach/server/requests.py @ 5fe360e

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

Converting server code to rely more on the ipp/ code

  • Property mode set to 100644
File size: 14.5 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 enumerate(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 enumerate(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        # this is just like cups_get_default, except the printer name
128        # is given
129        reqdict = ipp.ops.verify_get_printer_attributes_request(request)
130        printer_name = reqdict['printer-uri']
131        if printer_name not in self.printers:
132            raise ipp.errors.Attributes(
133                "Invalid printer uri: %s" % printer_name,
134                [request.attribute_groups[0].attributes[2]])
135       
136        self._get_printer_attributes(self.printers[printer_name], request, response)
137
138    def set_printer_attributes(self, request, response):
139        pass
140
141    ##### Job Commands
142
143    def cancel_job(self, request, response):
144        pass
145
146    def send_document(self, request, response):
147        pass
148
149    def send_uri(self, request, response):
150        pass
151
152    def get_job_attributes(self, request, response):
153        reqdict = ipp.ops.verify_get_jobs_request(request)
154        printer_name = reqdict['printer-uri']
155        job_id = reqdict['job-id']
156       
157        if printer_name not in self.printers:
158            raise ipp.errors.Attributes(
159                "Invalid printer uri: %s" % printer_name,
160                [request.attribute_groups[0].attributes[2]])
161        try:
162            job = self.printers[printer_name].get_job(job_id)
163        except InvalidJobException:
164            raise ipp.errors.Attributes(
165                "Invalid job id: %d" % job_id,
166                [request.attribute_groups[0].attributes[2]]) # XXX: this is wrong
167
168        # Each job will append a new job attribute group.
169        # XXX: we need to honor the things that the request actually asks for
170        self._get_job_attributes(job, request, response)
171
172    def set_job_attributes(self, request, response):
173        pass
174
175    def cups_get_document(self, request, response):
176        pass
177
178    def restart_job(self, request, response):
179        pass
180
181    def promote_job(self, request, response):
182        pass
183
184    ##### CUPS Specific Commands
185
186    @handler_for(const.Operations.CUPS_GET_DEFAULT)
187    def cups_get_default(self, request, response):
188        """The CUPS-Get-Default operation (0x4001) returns the default
189        printer URI and attributes.
190
191        CUPS-Get-Default Request
192        ------------------------
193
194        The following groups of attributes are supplied as part of the
195        CUPS-Get-Default request:
196
197        Group 1: Operation Attributes
198            Natural Language and Character Set:
199                The 'attributes-charset' and
200                'attributes-natural-language' attributes as described
201                in section 3.1.4.1 of the IPP Model and Semantics
202                document.
203            'requested-attributes' (1setOf keyword):
204                The client OPTIONALLY supplies a set of attribute
205                names and/or attribute group names in whose values the
206                requester is interested. If the client omits this
207                attribute, the server responds as if this attribute
208                had been supplied with a value of 'all'.
209       
210        CUPS-Get-Default Response
211        -------------------------
212
213        The following groups of attributes are send as part of the
214        CUPS-Get-Default Response:
215
216        Group 1: Operation Attributes
217            Status Message:
218                The standard response status message.
219            Natural Language and Character Set:
220                The 'attributes-charset' and
221                'attributes-natural-language' attributes as described
222                in section 3.1.4.2 of the IPP Model and Semantics
223                document.
224
225        Group 2: Printer Object Attributes
226            The set of requested attributes and their current values.
227
228        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_DEFAULT )
229
230        """
231           
232        self._get_printer_attributes(self.printers[self.default], request, response)
233
234    @handler_for(const.Operations.CUPS_GET_PRINTERS)
235    def cups_get_printers(self, request, response):
236        """
237        The CUPS-Get-Printers operation (0x4002) returns the printer
238        attributes for every printer known to the system. This may
239        include printers that are not served directly by the server.
240
241        CUPS-Get-Printers Request
242        -------------------------
243       
244        The following groups of attributes are supplied as part of the
245        CUPS-Get-Printers request:
246
247        Group 1: Operation Attributes
248            Natural Language and Character Set:
249                The 'attributes-charset' and
250                'attributes-natural-language' attributes as described
251                in section 3.1.4.1 of the IPP Model and Semantics
252                document.
253            'first-printer-name' (name(127)):CUPS 1.2/Mac OS X 10.5
254                The client OPTIONALLY supplies this attribute to
255                select the first printer that is returned.
256            'limit' (integer (1:MAX)):
257                The client OPTIONALLY supplies this attribute limiting
258                the number of printers that are returned.
259            'printer-location' (text(127)): CUPS 1.1.7
260                The client OPTIONALLY supplies this attribute to
261                select which printers are returned.
262            'printer-type' (type2 enum): CUPS 1.1.7
263                The client OPTIONALLY supplies a printer type
264                enumeration to select which printers are returned.
265            'printer-type-mask' (type2 enum): CUPS 1.1.7
266                The client OPTIONALLY supplies a printer type mask
267                enumeration to select which bits are used in the
268                'printer-type' attribute.
269            'requested-attributes' (1setOf keyword) :
270                The client OPTIONALLY supplies a set of attribute
271                names and/or attribute group names in whose values the
272                requester is interested. If the client omits this
273                attribute, the server responds as if this attribute
274                had been supplied with a value of 'all'.
275            'requested-user-name' (name(127)) : CUPS 1.2/Mac OS X 10.5
276                The client OPTIONALLY supplies a user name that is
277                used to filter the returned printers.
278
279        CUPS-Get-Printers Response
280        --------------------------
281
282        The following groups of attributes are send as part of the
283        CUPS-Get-Printers Response:
284
285        Group 1: Operation Attributes
286            Status Message:
287                The standard response status message.
288            Natural Language and Character Set:
289                The 'attributes-charset' and
290                'attributes-natural-language' attributes as described
291                in section 3.1.4.2 of the IPP Model and Semantics
292                document.
293               
294        Group 2: Printer Object Attributes
295            The set of requested attributes and their current values
296            for each printer.
297
298        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_PRINTERS )
299           
300        """
301
302        # Each printer will append a new printer attribute group.
303        for printer in self.printers:
304            self._get_printer_attributes(self.printers[printer], request, response)
305
306    @handler_for(const.Operations.CUPS_GET_CLASSES)
307    def cups_get_classes(self, request, response):
308        """The CUPS-Get-Classes operation (0x4005) returns the printer
309        attributes for every printer class known to the system. This
310        may include printer classes that are not served directly by
311        the server.
312
313        CUPS-Get-Classes Request
314        ------------------------
315
316        The following groups of attributes are supplied as part of the
317        CUPS-Get-Classes request:
318
319        Group 1: Operation Attributes
320            Natural Language and Character Set:
321                The 'attributes-charset' and
322                'attributes-natural-language' attributes as described
323                in section 3.1.4.1 of the IPP Model and Semantics
324                document.
325            'first-printer-name' (name(127)):CUPS 1.2/Mac OS X 10.5
326                The client OPTIONALLY supplies this attribute to
327                select the first printer that is returned.
328            'limit' (integer (1:MAX)):
329                The client OPTIONALLY supplies this attribute limiting
330                the number of printer classes that are returned.
331            'printer-location' (text(127)): CUPS 1.1.7
332                The client OPTIONALLY supplies this attribute to
333                select which printer classes are returned.
334            'printer-type' (type2 enum): CUPS 1.1.7
335                The client OPTIONALLY supplies a printer type
336                enumeration to select which printer classes are
337                returned.
338            'printer-type-mask' (type2 enum): CUPS 1.1.7
339                The client OPTIONALLY supplies a printer type mask
340                enumeration to select which bits are used in the
341                'printer-type' attribute.
342            'requested-attributes' (1setOf keyword) :
343                The client OPTIONALLY supplies a set of attribute
344                names and/or attribute group names in whose values the
345                requester is interested. If the client omits this
346                attribute, the server responds as if this attribute
347                had been supplied with a value of 'all'.
348            'requested-user-name' (name(127)) : CUPS 1.2/Mac OS X 10.5
349                The client OPTIONALLY supplies a user name that is
350                used to filter the returned printers.
351               
352        CUPS-Get-Classes Response
353        -------------------------
354
355        The following groups of attributes are send as part of the
356        CUPS-Get-Classes Response:
357
358        Group 1: Operation Attributes
359            Status Message:
360                The standard response status message.
361            Natural Language and Character Set:
362                The 'attributes-charset' and
363                'attributes-natural-language' attributes as described
364                in section 3.1.4.2 of the IPP Model and Semantics
365                document.
366
367        Group 2: Printer Class Object Attributes
368            The set of requested attributes and their current values
369            for each printer class.
370
371        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_CLASSES )
372
373        """
374       
375        # We have no printer classes, so we don't need to do anything
376        pass
Note: See TracBrowser for help on using the repository browser.