source: server/lib/gutenbach/ipp/operations.py @ cf32fee

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

Add/update helper functions in ipp/operations

  • Property mode set to 100644
File size: 13.0 KB
Line 
1from .value import Value
2from .attribute import Attribute
3from .attributegroup import AttributeGroup
4from .request import Request
5from .constants import AttributeTags, Tags
6import exceptions as err
7
8from collections import OrderedDictionary as odict
9
10def verify_operations(request):
11    """Pretty much all requests have the first attribute group for
12    operation attributes, and these all have 'attributes-charset' and
13    'attributes-natural-language' as the first two attributes.  This
14    method just generically verifies that these attributes are there.
15
16    """
17
18    # check operation attributes tag
19    op_attrs = request.attribute_groups[0]
20    if op_attrs.tag != AttributeTags.OPERATION:
21        raise err.BadRequest(
22            "Attribute group does not have OPERATION tag: 0x%x" % op_attrs.tag)
23
24    # XXX: check version
25    if False:
26        raise err.VersionNotSupported(str(request.version))
27
28    # check operation id
29    if False:
30        raise err.OperationNotSupported(str(request.operation_id))
31
32    # # check compression
33    # if False:
34    #     raise err.CompressionNotSupported
35
36    # # check document format
37    # if False:
38    #     raise err.DocumentFormatNotSupported
39
40    # # check document uri
41    # if False:
42    #     raise err.UriSchemeNotSupported
43
44    # check charset
45    charset attribute
46    charset_attr = op_attrs.attributes[0]
47    if charset_attr.name != 'attributes-charset':
48        raise err.BadRequest(
49            "Attribute is not attributes-charset: %s" % charset_attr.name)
50    if len(charset_attr.values) != 1:
51        raise err.BadRequest(
52            "Too many values for attributes-charset: %d" % len(charset_attr.values))
53
54    # check charset value
55    charset_value = charset_attr.values[0]
56    if charset_value.tag != Tags.CHARSET:
57        raise err.BadRequest(
58            "Charset value does not have CHARSET tag: 0x%x" % charset_value.tag)
59    if charset_value.value != 'utf-8':
60        raise err.CharsetNotSupported(str(charset_value.value))
61
62    # check for attributes-natural-language
63    natlang_attr = op_attrs.attributes[1]
64    if natlang_attr.name != 'attributes-natural-language':
65        raise err.BadRequest(
66            "Attribute is not attributes-natural-language: %s" % natlang_attr.name)
67    if len(charset_attr.values) != 1:
68        raise err.BadRequest(
69            "Too many values for attributes-natural-language: %s" % len(natlang_attr.values))
70
71    # check natural language value
72    natlang_value = natlang_attr.values[0]
73    if natlang_value.tag != Tags.NATURAL_LANGUAGE:
74        raise err.BadRequest(
75            "Natural language value does not have NATURAL_LANGUAGE tag: 0x%x" natlang_value.tag)
76    if natlang_value.value != 'en-us':
77        raise err.Attributes(
78            "Invalid natural language value: %s" % natlang_value.value, [natlang_attr])
79
80def verify_requesting_username(requser_attr):
81    if requser_attr.tag != Tags.NAME_WITHOUT_LANGUAGE:
82        raise err.BadRequest(
83            "Requesting user name attribute tag is not NAME_WITHOUT_LANGUAGE: 0x%x" % \
84            requser_attr.tag)
85    if len(requser_attr.values) != 1:
86        raise err.BadRequest(
87            "Requesting user name attribute has too many values: %d" % len(requser_attr.values))
88    requser_value = requser_attr.values[0]
89    if requser_value.tag != Tags.NAME_WITHOUT_LANGUAGE:
90        raise err.BadRequest(
91            "Requesting user name value tag is not NAME_WITHOUT_LANGUAGE: 0x%x" % \
92            requser_value.tag)
93    return requser_value.value
94
95def make_empty_response(request):
96    # Operation attributes -- typically the same for any request
97    attributes = [
98        ipp.Attribute(
99            'attributes-charset',
100            [ipp.Value(ipp.Tags.CHARSET, 'utf-8')]),
101        ipp.Attribute(
102            'attributes-natural-language',
103            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, 'en-us')])
104        ]
105    # Put the operation attributes in a group
106    attribute_group = ipp.AttributeGroup(
107        const.AttributeTags.OPERATION,
108        attributes)
109
110    # Set up the default response -- handlers will override these
111    # values if they need to
112    response_kwargs = {}
113    response_kwargs['version']          = request.version
114    response_kwargs['operation_id']     = const.StatusCodes.OK
115    response_kwargs['request_id']       = request.request_id
116    response_kwargs['attribute_groups'] = [attribute_group]
117    response = ipp.Request(**response_kwargs)
118
119    return response
120
121#### GET-JOBS
122
123def verify_get_jobs_request(request):
124    """RFC 2911 3.2.6.1 Get-Jobs Request
125
126    The client submits the Get-Jobs request to a Printer object.
127   
128    The following groups of attributes are part of the Get-Jobs
129    Request:
130
131    Group 1: Operation Attributes
132        Natural Language and Character Set:
133            The 'attributes-charset' and
134            'attributes-natural-language' attributes as described
135            in section 3.1.4.1.
136        Target:
137            The 'printer-uri' (uri) operation attribute which is
138            the target for this operation as described in section
139            3.1.5.
140        Requesting User Name:
141            The 'requesting-user-name' (name(MAX)) attribute
142            SHOULD be supplied by the client as described in
143            section 8.3.
144        'limit' (integer(1:MAX)):
145            The client OPTIONALLY supplies this attribute. The
146            Printer object MUST support this attribute. It is an
147            integer value that determines the maximum number of
148            jobs that a client will receive from the Printer even
149            if 'which-jobs' or 'my-jobs' constrain which jobs are
150            returned. The limit is a 'stateless limit' in that if
151            the value supplied by the client is ’N’, then only the
152            first ’N’ jobs are returned in the Get-Jobs Response.
153            There is no mechanism to allow for the next ’M’ jobs
154            after the first ’N’ jobs. If the client does not
155            supply this attribute, the Printer object responds
156            with all applicable jobs.
157        'requested-attributes' (1setOf type2 keyword):
158            The client OPTIONALLY supplies this attribute. The
159            Printer object MUST support this attribute. It is a
160            set of Job attribute names and/or attribute groups
161            names in whose values the requester is
162            interested. This set of attributes is returned for
163            each Job object that is returned. The allowed
164            attribute group names are the same as those defined in
165            the Get-Job-Attributes operation in section 3.3.4. If
166            the client does not supply this attribute, the Printer
167            MUST respond as if the client had supplied this
168            attribute with two values: ’job-uri’ and ’job-id’.
169        'which-jobs' (type2 keyword):
170            The client OPTIONALLY supplies this attribute. The
171            Printer object MUST support this attribute. It
172            indicates which Job objects MUST be returned by the
173            Printer object. The values for this attribute are:
174             - ’completed’: This includes any Job object whose
175               state is ’completed’, ’canceled’, or ’aborted’.
176             - ’not-completed’: This includes any Job object whose
177               state is ’pending’, ’processing’,
178               ’processing-stopped’, or ’pending-held’.
179            A Printer object MUST support both values. However, if
180            the implementation does not keep jobs in the
181            ’completed’, ’canceled’, and ’aborted’ states, then it
182            returns no jobs when the ’completed’ value is
183            supplied.  If a client supplies some other value, the
184            Printer object MUST copy the attribute and the
185            unsupported value to the Unsupported Attributes
186            response group, reject the request, and return the
187            ’client-error-attributes-or-values-not-supported’
188            status code.  If the client does not supply this
189            attribute, the Printer object MUST respond as if the
190            client had supplied the attribute with a value of
191            ’not-completed’.
192        'my-jobs' (boolean):
193            The client OPTIONALLY supplies this attribute. The
194            Printer object MUST support this attribute. It
195            indicates whether jobs from all users or just the jobs
196            submitted by the requesting user of this request MUST
197            be considered as candidate jobs to be returned by the
198            Printer object. If the client does not supply this
199            attribute, the Printer object MUST respond as if the
200            client had supplied the attribute with a value of
201            ’false’, i.e., jobs from all users. The means for
202            authenticating the requesting user and matching the
203            jobs is described in section 8.
204
205    """
206
207    # generic operations verification
208    verify_operations(request)
209
210    # requesting username
211    requser = verify_requesting_username(request.attributes[2])
212    out = {'requesting-user-name': requser}
213
214    # make the rest of the attributes into a dictionary
215    attrs = dict([(attr.name, attr.values) for attr in request.attributes[3:]])
216   
217    if 'limit' in attrs:
218        out['limit'] = None # XXX
219
220    if 'requested-attributes' in attrs:
221        out['requested-attributes'] = None # XXX
222
223    if 'which-jobs' in attrs:
224        out['which-jobs'] = None # XXX
225
226    if 'my-jobs' in attrs:
227        out['my-jobs'] = None # XXX
228
229    return out
230
231def make_get_jobs_response(self, request):
232    """3.2.6.2 Get-Jobs Response
233       
234    The Printer object returns all of the Job objects up to the number
235    specified by the 'limit' attribute that match the criteria as
236    defined by the attribute values supplied by the client in the
237    request. It is possible that no Job objects are returned since
238    there may literally be no Job objects at the Printer, or there may
239    be no Job objects that match the criteria supplied by the
240    client. If the client requests any Job attributes at all, there is
241    a set of Job Object Attributes returned for each Job object.
242
243    It is not an error for the Printer to return 0 jobs. If the
244    response returns 0 jobs because there are no jobs matching the
245    criteria, and the request would have returned 1 or more jobs
246    with a status code of ’successful-ok’ if there had been jobs
247    matching the criteria, then the status code for 0 jobs MUST be
248    ’successful-ok’.
249
250    Group 1: Operation Attributes
251        Status Message:
252            In addition to the REQUIRED status code returned in
253            every response, the response OPTIONALLY includes a
254            'status-message' (text(255)) and/or a
255            'detailed-status-message' (text(MAX)) operation
256            attribute as described in sections 13 and 3.1.6.
257        Natural Language and Character Set:
258            The 'attributes-charset' and
259            'attributes-natural-language' attributes as described
260            in section 3.1.4.2.
261
262    Group 2: Unsupported Attributes
263        See section 3.1.7 for details on returning Unsupported
264        Attributes.  The response NEED NOT contain the
265        'requested-attributes' operation attribute with any
266        supplied values (attribute keywords) that were requested
267        by the client but are not supported by the IPP object.  If
268        the Printer object does return unsupported attributes
269        referenced in the 'requested-attributes' operation
270        attribute and that attribute included group names, such as
271        ’all’, the unsupported attributes MUST NOT include
272        attributes described in the standard but not supported by
273        the implementation.
274
275    Groups 3 to N: Job Object Attributes
276        The Printer object responds with one set of Job Object
277        Attributes for each returned Job object. The Printer
278        object ignores (does not respond with) any requested
279        attribute or value which is not supported or which is
280        restricted by the security policy in force, including
281        whether the requesting user is the user that submitted the
282        job (job originating user) or not (see section
283        8). However, the Printer object MUST respond with the
284        ’unknown’ value for any supported attribute (including all
285        REQUIRED attributes) for which the Printer object does not
286        know the value, unless it would violate the security
287        policy. See the description of the 'out-of- band' values
288        in the beginning of Section 4.1.
289
290        Jobs are returned in the following order:
291        - If the client requests all ’completed’ Jobs (Jobs in the
292          ’completed’, ’aborted’, or ’canceled’ states), then the
293          Jobs are returned newest to oldest (with respect to
294          actual completion time)
295        - If the client requests all ’not-completed’ Jobs (Jobs in
296          the ’pending’, ’processing’, ’pending-held’, and
297          ’processing- stopped’ states), then Jobs are returned in
298          relative chronological order of expected time to
299          complete (based on whatever scheduling algorithm is
300          configured for the Printer object).
301
302    """
303
304    pass
Note: See TracBrowser for help on using the repository browser.