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
Line 
1from gutenbach.server.printer import GutenbachPrinter
2import gutenbach.ipp as ipp
3import gutenbach.ipp.constants as const
4import logging
5
6# initialize logger
7logger = logging.getLogger(__name__)
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
21class GutenbachRequestHandler(object):
22
23    def __init__(self):
24        self.printers = {
25            "test": GutenbachPrinter(name="test")
26            }
27        self.default = "test"
28   
29    def handle(self, request):
30        # look up the handler
31        handler = None
32        handler_name = None
33        for d in dir(self):
34            if getattr(getattr(self, d), "ipp_operation", None) == request.operation_id:
35                handler_name = d
36                break
37        # we couldn't find a handler, so default to unknown operation
38        if handler_name is None:
39            handler_name = "unknown_operation"
40        # call the handler
41        handler = getattr(self, handler_name)
42        logger.info("Handling request of type '%s'" % handler_name)
43        response = handler(request)
44        return response
45
46    def unknown_operation(self, request):
47        logger.warning("Received unknown operation 0x%x" % request.operation_id)
48        response = ipp.ops.make_empty_response(request)
49        response.operation_id = const.StatusCodes.OPERATION_NOT_SUPPORTED
50        return response
51       
52    ##### Printer Commands
53
54    def print_job(self, request):
55        pass
56
57    def validate_job(self, request):
58        pass
59
60    @handler_for(const.Operations.GET_JOBS)
61    def get_jobs(self, request):
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        """
75
76        # verify the request and get an attribute dictionary
77        req_dict = ipp.ops.verify_get_jobs_request(request)
78
79        # lookup printer name
80        printer_name = req_dict['printer-uri']
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]])
85
86        # get the job attributes
87        jobs = [job.get_job_attributes(request) for job in \
88                self.printers[printer_name].get_jobs()]
89
90        # build the response
91        response = ipp.ops.make_get_jobs_response(jobs, request)
92        return response
93
94    def print_uri(self, request):
95        pass
96
97    def create_job(self, request):
98        pass
99
100    def pause_printer(self, request):
101        pass
102
103    def resume_printer(self, request):
104        pass
105
106    @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES)
107    def get_printer_attributes(self, request):
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
150        # verify the request and get the attributes dictionary
151        req_dict = ipp.ops.verify_get_printer_attributes_request(request)
152
153        # lookup the printer name
154        printer_name = req_dict['printer-uri']
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]])
159
160        # bulid response
161        response = ipp.ops.make_get_printer_attributes_response(
162            self.printers[printer_name].get_printer_attributes(request), request)
163        return response
164
165    def set_printer_attributes(self, request):
166        pass
167
168    ##### Job Commands
169
170    def cancel_job(self, request):
171        pass
172
173    def send_document(self, request):
174        pass
175
176    def send_uri(self, request):
177        pass
178
179    def get_job_attributes(self, request):
180       
181        # verify the request and get the attributes dictionary
182        req_dict = ipp.ops.verify_get_jobs_request(request)
183       
184        # lookup the printer name
185        printer_name = req_dict['printer-uri']
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]])
190
191        # lookup the job id
192        job_id = req_dict['job-id']
193        try: job = self.printers[printer_name].get_job(job_id)
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
200        # build the response
201        response = ipp.ops.make_get_job_attributes_response(
202            job.get_job_attributes(request), request)
203        return response
204
205    def set_job_attributes(self, request):
206        pass
207
208    def cups_get_document(self, request):
209        pass
210
211    def restart_job(self, request):
212        pass
213
214    def promote_job(self, request):
215        pass
216
217    ##### CUPS Specific Commands
218
219    @handler_for(const.Operations.CUPS_GET_DEFAULT)
220    def cups_get_default(self, request):
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        """
227
228        # verify the request and get the attributes dictionary
229        req_dict = ipp.ops.verify_cups_get_default_request(request)
230        # build the response
231        response = ipp.ops.make_get_printer_attributes_response(
232            self.printers[self.default].get_printer_attributes(request), request)
233        return response
234
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.
241
242        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_PRINTERS )
243           
244        """
245
246        # verify the request and get the attributes dictionary
247        req_dict = ipp.ops.verify_cups_get_printers_request(request)
248        # get the printer attributes
249        attrs = [self.printers[printer].get_printer_attributes(request) \
250                 for printer in self.printers]
251        # build the response
252        response = ipp.ops.make_cups_get_printers_response(attrs, request)
253        return response
254
255    @handler_for(const.Operations.CUPS_GET_CLASSES)
256    def cups_get_classes(self, request):
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.
261       
262        (Source: http://www.cups.org/documentation.php/spec-ipp.html#CUPS_GET_CLASSES )
263
264        """
265
266        # verify the request and get the attributes dictionaryu
267        req_dict = ipp.ops.verify_cups_get_classes_request(request)
268        # build the response
269        response = ipp.ops.make_cups_get_classes_response(request)
270        return response
Note: See TracBrowser for help on using the repository browser.