Changeset b2e077a


Ignore:
Timestamp:
Dec 18, 2011, 11:18:16 PM (12 years ago)
Author:
Jessica B. Hamrick <jhamrick@…>
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)
Message:

Refactor code to handle the operations a little bit more logically

Location:
server/lib/gutenbach
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • server/lib/gutenbach/ipp/attributegroup.py

    rd04a689 rb2e077a  
    1616    """
    1717
    18     def __init__(self, attribute_group_tag=None, attributes=[]):
     18    def __init__(self, tag=None, attributes=[]):
    1919        """Initialize an AttributeGroup.  An AttributeGroup can be
    2020        initialized in three ways:
    2121
    2222            AttributeGroup()
    23             AttributeGroup(attribute_group_tag)
    24             AttributeGroup(attribute_group_tag, attributes)
     23            AttributeGroup(tag)
     24            AttributeGroup(tag, attributes)
    2525
    2626        Arguments:
    2727
    28             attribute_group_tag -- a signed char, holds the tag of the
    29                                    attribute group
     28            tag -- a signed char, holds the tag of the
     29                   attribute group
    3030
    3131            attributes -- a list of attributes
     
    3333        """
    3434
    35         if attribute_group_tag is not None:
    36             assert isinstance(attribute_group_tag, int), \
    37                    "attribute_group_tag must be a character!"
    38            
     35        if tag is not None:
     36            assert isinstance(tag, int), \
     37                   "tag must be a character!"
    3938
    40         self.attribute_group_tag = attribute_group_tag
     39        self.tag = tag
    4140        self.attributes = []
    4241        self.extend(attributes)
     
    9796        """
    9897
    99         # conver the attribute_group_tag to binary
    100         tag = struct.pack('>b', self.attribute_group_tag)
     98        # convert the tag to binary
     99        tag = struct.pack('>b', self.tag)
    101100
    102101        # convert each of the attributes to binary
     
    107106
    108107    def __repr__(self):
    109         return '<IPPAttributeGroup (%r, %r)>' % (self.attribute_group_tag, self.attributes)
     108        return '<IPPAttributeGroup (%r, %r)>' % (self.tag, self.attributes)
  • server/lib/gutenbach/server/__init__.py

    rd04a689 rb2e077a  
    1 from requests import GutenbachIPPHandler
     1from requests import GutenbachIPPServer
    22import BaseHTTPServer
    33import logging
     
    88def start():
    99    server_address = ('', 8000)
    10     httpd = BaseHTTPServer.HTTPServer(server_address, GutenbachIPPHandler)
     10    httpd = BaseHTTPServer.HTTPServer(server_address, GutenbachIPPServer)
    1111    httpd.serve_forever()
    1212
  • server/lib/gutenbach/server/exceptions.py

    rdf51061 rb2e077a  
    1212    def __str__(self):
    1313        return self.message
     14
     15class MalformedIPPRequestException(Exception):
     16    def __init__(self, message):
     17        self.message = message
     18
     19    def __str__(self):
     20        return self.message
  • server/lib/gutenbach/server/job.py

    rd04a689 rb2e077a  
    77class Job(object):
    88
     9    attributes = [
     10        "job-id",
     11        "job-name",
     12        "job-originating-user-name",
     13        "job-k-octets",
     14        "job-state",
     15        "job-printer-uri"
     16        ]
     17
    918    def __init__(self, document=None):
    1019        """Initialize a Gutenbach job.
     
    1423        """
    1524         
    16         self._jobid = None
    17         self._status = 'initializing'
     25        self._id = None
     26        self._name = document
     27        self._status = None
    1828        self._document = document
    1929        self._printer = None
    2030
    2131    @property
    22     def jobid(self):
    23         return self._jobid
     32    def job_id(self):
     33        return ipp.Attribute(
     34            'job-id',
     35            [ipp.Value(ipp.Tags.INTEGER, self._id)])
    2436
    25     @jobid.setter
    26     def jobid(self, val):
    27         raise AttributeError("Setting jobid is illegal!")
     37    @property
     38    def job_name(self):
     39        return ipp.Attribute(
     40            'job-name',
     41            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, self._name)])
    2842
     43    # XXX: we need to actually calculate this!
     44    @property
     45    def job_originating_user_name(self):
     46        return ipp.Attribute(
     47            'job-originating-user-name',
     48            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, "jhamrick")])
     49
     50    # XXX: we need to actually calculate this!
     51    @property
     52    def job_k_octets(self):
     53        return ipp.Attribute(
     54            'job-k-octets',
     55            [ipp.Value(ipp.Tags.INTEGER, 1)])
     56
     57    @property
     58    def job_state(self):
     59        return ipp.Attribute(
     60            'job-state',
     61            [ipp.Value(ipp.Tags.ENUM, self._status)])
     62
     63    @property
     64    def job_printer_uri(self):
     65        return ipp.Attribute(
     66            'job-printer-uri',
     67            [ipp.Value(ipp.Tags.URI, self._printer._uri)])
     68
     69    def get_job_attributes(self, request):
     70        attributes = [getattr(self, attr.replace("-", "_")) for attr in self.attributes]
     71        return attributes
     72
     73   
     74    #######
    2975    @property
    3076    def document(self):
     
    4187        return self._status
    4288
    43     @status.setter
    44     def status(self, val):
    45         raise AttributeError(
    46             "Setting status directly is illegal!  " + \
    47             "Please use enqueue(), play(), or finish().")
    48 
    4989    @property
    5090    def printer(self):
    5191        return self._printer
    5292
    53     @printer.setter
    54     def printer(self, val):
    55         raise AttributeError(
    56             "Setting printer directly is illegal!  " + \
    57             "Please use enqueue().")
    58 
    59     def enqueue(self, printer, jobid):
    60         if self.status != 'initializing':
     93    def enqueue(self, printer, job_id):
     94        if self._status != None:
    6195            raise InvalidJobException(
    6296                "Cannot enqueue a job that has " + \
    6397                "already been initialized!")
    6498        self._printer = printer
    65         self._jobid = jobid
    66         self._status = 'active'
     99        self._job_id = job_id
     100        self._status = const.JobStates.PENDING
    67101
    68102    def play(self):
     
    71105                "Cannot play an inactive job!")
    72106       
    73         self._status = 'playing'
     107        self._status = const.JobStates.PROCESSING
    74108        # TODO: add external call to music player
    75109        print "Playing job %s" % str(self)
    76         self.printer.complete_job(self.jobid)
     110        self._printer.complete_job(self._id)
    77111
    78112    def finish(self):
    79         self._status = 'finished'
     113        self._status = const.JobStates.COMPLETE
    80114
    81115    def __repr__(self):
     
    84118    def __str__(self):
    85119        return "<Job %d '%s'>" % \
    86                (self.jobid if self.jobid is not None else -1, \
    87                                   self.document)
     120               (self._id if self._id is not None else -1, \
     121                self._document)
  • server/lib/gutenbach/server/printer.py

    rd04a689 rb2e077a  
     1#import alsaaudio as aa
    12from .exceptions import InvalidJobException, InvalidPrinterStateException
    23from gutenbach.ipp.attribute import Attribute
    3 import alsaaudio as aa
    4 import gutenbach.ipp
     4import gutenbach.ipp as ipp
     5import gutenbach.ipp.constants as const
     6import logging
     7import time
    58
    69# initialize logger
    710logger = logging.getLogger(__name__)
    811
    9 class Printer(object):
    10 
    11     def __init__(self, name, card, mixer):
    12 
    13         self.name = name
    14 
    15         if card >= len(aa.cards()):
    16             raise aa.ALSAAudioError(
    17                 "Audio card at index %d does not exist!" % card)
    18         elif mixer not in aa.mixers(card):
    19             raise aa.ALSAAudioError(
    20                 "Audio mixer '%s' does not exist!" % mixer)
     12class GutenbachPrinter(object):
     13
     14    attributes = [
     15        "printer-uri-supported",
     16        "uri-authentication-supported",
     17        "uri-security-supported",
     18        "printer-name",
     19        "printer-state",
     20        "printer-state-reasons",
     21        "ipp-versions-supported",
     22        "operations-supported",
     23        "charset-configured",
     24        "charset-supported",
     25        "natural-language-configured",
     26        "generated-natural-language-supported",
     27        "document-format-default",
     28        "document-format-supported",
     29        "printer-is-accepting-jobs",
     30        "queued-job-count",
     31        "pdl-override-supported",
     32        "printer-up-time",
     33        "compression-supported"]
     34
     35    #def __init__(self, name, card, mixer):
     36    def __init__(self, name):
     37
     38        self._name = name
     39        self._uri = "ipp://localhost:8000/printers/" + self._name
     40        self._time_created = int(time.time())
     41
     42        # if card >= len(aa.cards()):
     43        #     raise aa.ALSAAudioError(
     44        #       "Audio card at index %d does not exist!" % card)
     45        # elif mixer not in aa.mixers(card):
     46        #     raise aa.ALSAAudioError(
     47        #       "Audio mixer '%s' does not exist!" % mixer)
    2148       
    22         self.card = card
    23         self.mixer = mixer
     49        # self.card = card
     50        # self.mixer = mixer
    2451
    2552        self.finished_jobs = []
     
    2956        self._next_jobid = 0
    3057
     58    ## Printer attributes
     59    @property
     60    def printer_uri_supported(self):
     61        return ipp.Attribute(
     62            "printer-uri-supported",
     63            [ipp.Value(ipp.Tags.URI, self._uri)])
     64   
     65    @property
     66    def uri_authentication_supported(self):
     67        return ipp.Attribute(
     68            "uri-authentication-supported",
     69            [ipp.Value(ipp.Tags.KEYWORD, "none")])
     70
     71    @property
     72    def uri_security_supported(self):
     73        return ipp.Attribute(
     74            "uri-security-supported",
     75            [ipp.Value(ipp.Tags.KEYWORD, "none")])
     76
     77    @property
     78    def printer_name(self):
     79        return ipp.Attribute(
     80            "printer-name",
     81            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, self._name)])
     82       
     83    @property
     84    def printer_state(self):
     85        return ipp.Attribute(
     86            "printer-state",
     87            [ipp.Value(ipp.Tags.ENUM, const.PrinterStates.IDLE)])
     88       
     89    @property
     90    def printer_state_reasons(self):
     91        return ipp.Attribute(
     92            "printer-state-reasons",
     93            [ipp.Value(ipp.Tags.KEYWORD, "none")])
     94
     95    @property
     96    def ipp_versions_supported(self):
     97        return ipp.Attribute(
     98            "ipp-versions-supported",
     99            [ipp.Value(ipp.Tags.KEYWORD, "1.0"),
     100             ipp.Value(ipp.Tags.KEYWORD, "1.1")])
     101
     102    # XXX: We should query ourself for the supported operations
     103    @property
     104    def operations_supported(self):
     105        return ipp.Attribute(
     106            "operations-supported",
     107            [ipp.Value(ipp.Tags.ENUM, const.Operations.GET_JOBS)])
     108
     109    @property
     110    def charset_configured(self):
     111        return ipp.Attribute(
     112            "charset-configured",
     113            [ipp.Value(ipp.Tags.CHARSET, "utf-8")])
     114
     115    @property
     116    def charset_supported(self):
     117        return ipp.Attribute(
     118            "charset-supported",
     119            [ipp.Value(ipp.Tags.CHARSET, "utf-8")])
     120
     121    @property
     122    def natural_language_configured(self):
     123        return ipp.Attribute(
     124            "natural-language-configured",
     125            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")])
     126
     127    @property
     128    def generated_natural_language_supported(self):
     129        return ipp.Attribute(
     130            "generated-natural-language-supported",
     131            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")])
     132
     133    @property
     134    def document_format_default(self):
     135        return ipp.Attribute(
     136            "document-format-default",
     137            [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream")])
     138
     139    @property
     140    def document_format_supported(self):
     141        return ipp.Attribute(
     142            "document-format-supported",
     143            [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream"),
     144             ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "audio/mp3")])
     145
     146    @property
     147    def printer_is_accepting_jobs(self):
     148        return ipp.Attribute(
     149            "printer-is-accepting-jobs",
     150            [ipp.Value(ipp.Tags.BOOLEAN, True)])
     151
     152    @property
     153    def queued_job_count(self):
     154        return ipp.Attribute(
     155            "queued-job-count",
     156            [ipp.Value(ipp.Tags.INTEGER, len(self.active_jobs))])
     157
     158    @property
     159    def pdl_override_supported(self):
     160        return ipp.Attribute(
     161            "pdl-override-supported",
     162            [ipp.Value(ipp.Tags.KEYWORD, "not-attempted")])
     163
     164    @property
     165    def printer_up_time(self):
     166        return ipp.Attribute(
     167            "printer-up-time",
     168            [ipp.Value(ipp.Tags.INTEGER, int(time.time()) - self._time_created)])
     169
     170    @property
     171    def compression_supported(self):
     172        return ipp.Attribute(
     173            "compression-supported",
     174            [ipp.Value(ipp.Tags.KEYWORD, "none")])
     175
     176    def get_printer_attributes(self, request):
     177        attributes = [getattr(self, attr.replace("-", "_")) for attr in self.attributes]
     178        return attributes
     179
     180    ## Printer operations
    31181    @property
    32182    def next_jobid(self):
    33183        self._next_jobid += 1
    34184        return self._next_jobid
    35 
    36     @next_jobid.setter
    37     def next_jobid(self, val):
    38         raise AttributeError("Setting next_jobid is illegal!")
    39185
    40186    def print_job(self, job):
     
    75221        return self.jobs[jobid]
    76222
     223    def get_jobs(self):
     224        jobs = [self.jobs[job_id] for job_id in self.active_jobs]
     225        return jobs           
     226
    77227    def __repr__(self):
    78228        return str(self)
    79229
    80230    def __str__(self):
    81         return "<Printer '%s'>" % self.name
     231        return "<Printer '%s'>" % self._name
  • server/lib/gutenbach/server/requests.py

    rd04a689 rb2e077a  
    11import BaseHTTPServer
    2 import gutenbach.ipp
     2import gutenbach.ipp as ipp
    33import gutenbach.ipp.constants as const
     4from gutenbach.server.printer import GutenbachPrinter
     5from gutenbach.server.exceptions import MalformedIPPRequestException
    46import logging
    5 import time
    67
    78# initialize logger
     
    2021    return f
    2122
    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     """
     23class GutenbachRequestHandler(object):
     24
     25    def __init__(self):
     26        self.printers = {
     27            "test": GutenbachPrinter(name="test")
     28            }
     29        self.default = "test"
    2730   
    28     def _ipp_dispatch(self, request):
     31    def handle(self, request, response):
     32        # look up the handler
     33        handler = None
    2934        for d in dir(self):
    3035            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)
    3343
    3444    def unknown_operation(self, request, response):
    35         print "Received UNKNOWN OPERATION %x" % request.operation_id
     45        print "Received unknown operation %x" % request.operation_id
    3646        response.operation_id = const.StatusCodes.OPERATION_NOT_SUPPORTED
    3747
    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
    13584
    13685    @handler_for(const.Operations.CUPS_GET_DEFAULT)
    13786    def cups_get_default(self, request, response):
    13887        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
    140100
    141101    @handler_for(const.Operations.CUPS_GET_PRINTERS)
    142102    def cups_get_printers(self, request, response):
    143103        print "get_printers called"
    144         response.operation_id = const.StatusCodes.OK
     104       
    145105        # 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
    148109
    149110    @handler_for(const.Operations.CUPS_GET_CLASSES)
     
    153114        # We have no printer classes, so nothing to return.
    154115
    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
     126class GutenbachIPPServer(BaseHTTPServer.BaseHTTPRequestHandler):
    156127    def setup(self):
    157         self.root = RootRequestHandler()
     128        self.root = GutenbachRequestHandler()
    158129        BaseHTTPServer.BaseHTTPRequestHandler.setup(self)
    159130
     
    196167
    197168        # 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)
    200170        print "Sending response:", repr(response)
    201171
     
    207177        self.wfile.write(response.packed_value)
    208178
    209     def get_jobs(self, request, response_kwargs):
    210         """get-jobs response"""
    211 
    212         # Job attributes
    213         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 group
    234         job_attribute_group = ipp.AttributeGroup(
    235             const.AttributeTags.JOB,
    236             job_attributes)
    237 
    238         # Operation attributions
    239         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 group
    248         op_attributes_group = ipp.AttributeGroup(
    249             const.AttributeTags.OPERATION,
    250             op_attributes)
    251 
    252         # Setup the actual response dictionary
    253         response_kwargs['attribute_groups'] = [op_attributes_group,job_attribute_group]
    254         response_kwargs['operation_id'] = const.StatusCodes.OK
    255 
    256         return response_kwargs
    257 
    258179    ##### Printer Commands
    259180
Note: See TracChangeset for help on using the changeset viewer.