Changeset b2e077a for server/lib/gutenbach/server/requests.py
- Timestamp:
- Dec 18, 2011, 11:18:16 PM (12 years ago)
- Branches:
- no-cups
- Children:
- 9eeab06
- Parents:
- d04a689
- git-author:
- Jessica B. Hamrick <jhamrick@…> (12/18/11 23:18:16)
- git-committer:
- Jessica B. Hamrick <jhamrick@…> (12/18/11 23:18:16)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
server/lib/gutenbach/server/requests.py
rd04a689 rb2e077a 1 1 import BaseHTTPServer 2 import gutenbach.ipp 2 import gutenbach.ipp as ipp 3 3 import gutenbach.ipp.constants as const 4 from gutenbach.server.printer import GutenbachPrinter 5 from gutenbach.server.exceptions import MalformedIPPRequestException 4 6 import logging 5 import time6 7 7 8 # initialize logger … … 20 21 return f 21 22 22 class IPPRequestHandler(object): 23 """A generic base class for IPP requests. Provides a dispatch 24 function to conver request operation ids to handler functions. 25 26 """ 23 class GutenbachRequestHandler(object): 24 25 def __init__(self): 26 self.printers = { 27 "test": GutenbachPrinter(name="test") 28 } 29 self.default = "test" 27 30 28 def _ipp_dispatch(self, request): 31 def handle(self, request, response): 32 # look up the handler 33 handler = None 29 34 for d in dir(self): 30 35 if getattr(getattr(self, d), "ipp_operation", None) == request.operation_id: 31 return getattr(self, d) 32 return self.unknown_operation 36 handler = getattr(self, d) 37 break 38 # we couldn't find a handler, so default to unknown operation 39 if handler is None: 40 handler = self.unknown_operation 41 # call the handler 42 handler(request, response) 33 43 34 44 def unknown_operation(self, request, response): 35 print "Received UNKNOWN OPERATION%x" % request.operation_id45 print "Received unknown operation %x" % request.operation_id 36 46 response.operation_id = const.StatusCodes.OPERATION_NOT_SUPPORTED 37 47 38 class PrinterRequestHandler(IPPRequestHandler): 39 """This handles requests that are printer-specific: for example, 40 the printer's name or state. 41 42 """ 43 44 def __init__(self, name): 45 self.name = name 46 47 @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES) 48 def get_printer_attributes(self, request, response): 49 printer_attributes = ipp.AttributeGroup(const.AttributeTags.PRINTER) 50 printer_attributes.append(ipp.Attribute( 51 "printer-uri-supported", 52 [ipp.Value(ipp.Tags.URI, "ipp://localhost:8000/printers/" + self.name)])) 53 54 printer_attributes.append(ipp.Attribute( 55 "uri-authentication-supported", 56 [ipp.Value(ipp.Tags.KEYWORD, "none")])) 57 58 printer_attributes.append(ipp.Attribute( 59 "uri-security-supported", 60 [ipp.Value(ipp.Tags.KEYWORD, "none")])) 61 62 printer_attributes.append(ipp.Attribute( 63 "printer-name", 64 [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, self.name)])) 65 66 printer_attributes.append(ipp.Attribute( 67 "printer-state", 68 [ipp.Value(ipp.Tags.ENUM, const.PrinterStates.IDLE)])) 69 70 printer_attributes.append(ipp.Attribute( 71 "printer-state-reasons", 72 [ipp.Value(ipp.Tags.KEYWORD, "none")])) 73 74 printer_attributes.append(ipp.Attribute( 75 "ipp-versions-supported", 76 [ipp.Value(ipp.Tags.KEYWORD, "1.0"), 77 ipp.Value(ipp.Tags.KEYWORD, "1.1")])) 78 79 # XXX: We should query ourself for the supported operations 80 printer_attributes.append(ipp.Attribute( 81 "operations-supported", 82 [ipp.Value(ipp.Tags.ENUM, const.Operations.GET_JOBS)])) 83 84 printer_attributes.append(ipp.Attribute( 85 "charset-configured", 86 [ipp.Value(ipp.Tags.CHARSET, "utf-8")])) 87 88 printer_attributes.append(ipp.Attribute( 89 "charset-supported", 90 [ipp.Value(ipp.Tags.CHARSET, "utf-8")])) 91 92 printer_attributes.append(ipp.Attribute( 93 "natural-language-configured", 94 [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")])) 95 96 printer_attributes.append(ipp.Attribute( 97 "generated-natural-language-supported", 98 [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")])) 99 100 printer_attributes.append(ipp.Attribute( 101 "document-format-default", 102 [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream")])) 103 104 printer_attributes.append(ipp.Attribute( 105 "document-format-supported", 106 [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream"), 107 ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "audio/mp3")])) 108 109 printer_attributes.append(ipp.Attribute( 110 "printer-is-accepting-jobs", 111 [ipp.Value(ipp.Tags.BOOLEAN, True)])) 112 113 printer_attributes.append(ipp.Attribute( 114 "queued-job-count", 115 [ipp.Value(ipp.Tags.INTEGER, 1)])) 116 117 printer_attributes.append(ipp.Attribute( 118 "pdl-override-supported", 119 [ipp.Value(ipp.Tags.KEYWORD, "not-attempted")])) 120 121 printer_attributes.append(ipp.Attribute( 122 "printer-up-time", 123 [ipp.Value(ipp.Tags.INTEGER, int(time.time()))])) 124 125 printer_attributes.append(ipp.Attribute( 126 "compression-supported", 127 [ipp.Value(ipp.Tags.KEYWORD, "none")])) 128 129 response.attribute_groups.append(printer_attributes) 130 response.operation_id = const.StatusCodes.OK 131 print "get_printer_attributes called" 132 133 class RootRequestHandler(IPPRequestHandler): 134 printers = [PrinterRequestHandler(name="sipbmp3")] 48 def _get_printer_attributes(self, printer, request, response): 49 response.attribute_groups.append(ipp.AttributeGroup( 50 const.AttributeTags.PRINTER, 51 printer.get_printer_attributes(request))) 52 53 def _get_job_attributes(self, job_id, printer, request, response): 54 response.attribute_groups.append(ipp.AttributeGroup( 55 const.AttributeTags.JOB, 56 job.get_job_attributes(request))) 57 58 def _get_printer_name(self, request): 59 # make sure the first group is an OPERATION group 60 group_tag = request.attribute_groups[0].tag 61 if group_tag != const.AttributeTags.OPERATION: 62 raise MalformedIPPRequestException, \ 63 "Expected OPERATION group tag, got %d\n", group_tag 64 65 # make sure the printer-uri value is appropriate 66 printername_attr = request.attribute_groups[0]['printer-uri'] 67 printername_value_tag = printername_attr.values[0].value_tag 68 if printername_value_tag != const.CharacterStringTags.URI: 69 raise MalformedIPPRequestException, \ 70 "Expected URI value tag, got %s" % printername_value_tag 71 72 # actually get the printer name 73 printername_value = printername_attr.values[0].value 74 # XXX: hack -- CUPS will strip the port from the request, so 75 # we can't do an exact comparison (also the hostname might be 76 # different, depending on the CNAME or whether it's localhost) 77 printername = printername_value.split("/")[-1] 78 79 # make sure the printername is valid 80 if printername not in self.printers: 81 raise ValueError, "Invalid printer uri: %s" % printername_value 82 83 return printername 135 84 136 85 @handler_for(const.Operations.CUPS_GET_DEFAULT) 137 86 def cups_get_default(self, request, response): 138 87 print "get_default called" 139 return self.printers[0].get_printer_attributes(request, response) 88 self._get_printer_attributes(self.printers[self.default], request, response) 89 response.operation_id = const.StatusCodes.OK 90 91 @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES) 92 def get_printer_attributes(self, request, response): 93 print "get_printer_attributes called" 94 95 # this is just like cups_get_default, except the printer name 96 # is given 97 printername = self._get_printer_name(request) 98 self._get_printer_attributes(self.printers[printername], request, response) 99 response.operation_id = const.StatusCodes.OK 140 100 141 101 @handler_for(const.Operations.CUPS_GET_PRINTERS) 142 102 def cups_get_printers(self, request, response): 143 103 print "get_printers called" 144 response.operation_id = const.StatusCodes.OK104 145 105 # Each printer will append a new printer attribute group. 146 for p in self.printers: 147 p.get_printer_attributes(request, response) 106 for printer in self.printers: 107 self._get_printer_attributes(self.printers[printer], request, response) 108 response.operation_id = const.StatusCodes.OK 148 109 149 110 @handler_for(const.Operations.CUPS_GET_CLASSES) … … 153 114 # We have no printer classes, so nothing to return. 154 115 155 class GutenbachIPPHandler(BaseHTTPServer.BaseHTTPRequestHandler): 116 @handler_for(const.Operations.GET_JOBS) 117 def get_jobs(self, request, response): 118 print "get_jobs called" 119 120 printername = self._get_printer_name(request) 121 # Each job will append a new job attribute group. 122 for job in self.printers[printername].get_jobs(): 123 self._get_job_attributes(job, request, response) 124 response.operation_id = const.StatusCodes.OK 125 126 class GutenbachIPPServer(BaseHTTPServer.BaseHTTPRequestHandler): 156 127 def setup(self): 157 self.root = RootRequestHandler()128 self.root = GutenbachRequestHandler() 158 129 BaseHTTPServer.BaseHTTPRequestHandler.setup(self) 159 130 … … 196 167 197 168 # Get the handler and pass it the request and response objects 198 handler = self.root._ipp_dispatch(request) 199 handler(request, response) 169 self.root.handle(request, response) 200 170 print "Sending response:", repr(response) 201 171 … … 207 177 self.wfile.write(response.packed_value) 208 178 209 def get_jobs(self, request, response_kwargs):210 """get-jobs response"""211 212 # Job attributes213 job_attributes = [214 ipp.Attribute(215 'job-id',216 [ipp.Value(ipp.Tags.INTEGER, 12345)]),217 ipp.Attribute(218 'job-name',219 [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, 'foo')]),220 ipp.Attribute(221 'job-originating-user-name',222 [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, 'jhamrick')]),223 ipp.Attribute(224 'job-k-octets',225 [ipp.Value(ipp.Tags.INTEGER, 1)]),226 ipp.Attribute(227 'job-state',228 [ipp.Value(ipp.Tags.ENUM, const.JobStates.HELD)]),229 ipp.Attribute(230 'job-printer-uri',231 [ipp.Value(ipp.Tags.URI, 'ipp://localhost:8000/printers/foo')])232 ]233 # Job attribute group234 job_attribute_group = ipp.AttributeGroup(235 const.AttributeTags.JOB,236 job_attributes)237 238 # Operation attributions239 op_attributes = [240 ipp.Attribute(241 'attributes-charset',242 [ipp.Value(ipp.Tags.CHARSET, 'utf-8')]),243 ipp.Attribute(244 'attributes-natural-language',245 [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, 'en-us')])246 ]247 # Operation attribution group248 op_attributes_group = ipp.AttributeGroup(249 const.AttributeTags.OPERATION,250 op_attributes)251 252 # Setup the actual response dictionary253 response_kwargs['attribute_groups'] = [op_attributes_group,job_attribute_group]254 response_kwargs['operation_id'] = const.StatusCodes.OK255 256 return response_kwargs257 258 179 ##### Printer Commands 259 180
Note: See TracChangeset
for help on using the changeset viewer.