source: server/lib/gutenbach/server/printer.py @ ffbe41d

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

Clean up core ipp code a bit

  • Property mode set to 100644
File size: 7.5 KB
RevLine 
[e58af05]1from . import InvalidJobException, InvalidPrinterStateException
2from . import Job
[b2e077a]3import gutenbach.ipp as ipp
4import logging
5import time
[d04a689]6
7# initialize logger
8logger = logging.getLogger(__name__)
[776a659]9
[b2e077a]10class GutenbachPrinter(object):
11
[1a63bf7]12    # for IPP
[b2e077a]13    attributes = [
14        "printer-uri-supported",
15        "uri-authentication-supported",
16        "uri-security-supported",
17        "printer-name",
18        "printer-state",
19        "printer-state-reasons",
20        "ipp-versions-supported",
21        "operations-supported",
22        "charset-configured",
23        "charset-supported",
24        "natural-language-configured",
25        "generated-natural-language-supported",
26        "document-format-default",
27        "document-format-supported",
28        "printer-is-accepting-jobs",
29        "queued-job-count",
30        "pdl-override-supported",
31        "printer-up-time",
[f6e2532]32        "compression-supported",
33        "multiple-operation-time-out",
34        "multiple-document-jobs-supported",
[1a63bf7]35    ]
[b2e077a]36
[f6e2532]37    operations = [
38        "print-job",
39        "complete-job",
40        "start-job",
41        "get-job",
42        "get-jobs",
43    ]
44       
45
[b2e077a]46    def __init__(self, name):
47
[1a63bf7]48        self.name = name
49        self.uri = "ipp://localhost:8000/printers/" + self.name
50        self.time_created = int(time.time())
51        self.state = "idle"
[b2e077a]52
[776a659]53        self.finished_jobs = []
54        self.active_jobs = []
55        self.jobs = {}
56
[7c143c9]57        # cups ignores jobs with id 0, so we have to start at 1
58        self._next_jobid = 1 
[776a659]59
[1a63bf7]60    def __getattr__(self, attr):
61        try:
[6effd50]62            return self.__getattribute__(attr)
[1a63bf7]63        except AttributeError:
64            pass
[6effd50]65        return self.__getattribute__(attr.replace("-", "_"))
[1a63bf7]66
67    def __hasattr__(self, attr):
[6effd50]68        try:
69            getattr(self, attr)
70            return True
71        except AttributeError:
72            return False
[1a63bf7]73
[b2e077a]74    ## Printer attributes
[1a63bf7]75
[b2e077a]76    @property
77    def printer_uri_supported(self):
[793432f]78        return ipp.PrinterUriSupported(self.uri)
[1a63bf7]79
[b2e077a]80    @property
81    def uri_authentication_supported(self):
[793432f]82        return ipp.UriAuthenticationSupported("none")
[b2e077a]83
84    @property
85    def uri_security_supported(self):
[793432f]86        return ipp.UriSecuritySupported("none")
[b2e077a]87
88    @property
89    def printer_name(self):
[793432f]90        return ipp.PrinterName(self.name)
[1a63bf7]91
[b2e077a]92    @property
93    def printer_state(self):
[793432f]94        return ipp.PrinterState(ipp.constants.PrinterStates.IDLE)
[1a63bf7]95
[b2e077a]96    @property
97    def printer_state_reasons(self):
[793432f]98        return ipp.PrinterStateReasons("none")
[b2e077a]99
100    @property
101    def ipp_versions_supported(self):
[793432f]102        return ipp.IppVersionsSupported("1.0", "1.1")
[1a63bf7]103
[f6e2532]104    # XXX: We should query ourself for the supported operations
[b2e077a]105    @property
106    def operations_supported(self):
[793432f]107        return ipp.OperationsSupported(ipp.OperationCodes.GET_JOBS)
[b2e077a]108
109    @property
110    def charset_configured(self):
[793432f]111        return ipp.CharsetConfigured("utf-8")
[b2e077a]112
113    @property
114    def charset_supported(self):
[793432f]115        return ipp.CharsetSupported("utf-8")
[b2e077a]116
117    @property
118    def natural_language_configured(self):
[793432f]119        return ipp.NaturalLanguageConfigured("en-us")
[b2e077a]120
121    @property
122    def generated_natural_language_supported(self):
[793432f]123        return ipp.GeneratedNaturalLanguageSupported("en-us")
[b2e077a]124
125    @property
126    def document_format_default(self):
[793432f]127        return ipp.DocumentFormatDefault("application/octet-stream")
[b2e077a]128
129    @property
130    def document_format_supported(self):
[793432f]131        return ipp.DocumentFormatSupported("application/octet-stream", "audio/mp3")
[b2e077a]132
133    @property
134    def printer_is_accepting_jobs(self):
[793432f]135        return ipp.PrinterIsAcceptingJobs(True)
[b2e077a]136
137    @property
138    def queued_job_count(self):
[793432f]139        return ipp.QueuedJobCount(len(self.active_jobs))
[b2e077a]140
141    @property
142    def pdl_override_supported(self):
[793432f]143        return ipp.PdlOverrideSupported("not-attempted")
[b2e077a]144
145    @property
146    def printer_up_time(self):
[793432f]147        return ipp.PrinterUpTime(int(time.time()) - self.time_created)
[b2e077a]148
149    @property
150    def compression_supported(self):
[793432f]151        return ipp.CompressionSupported("none")
[b2e077a]152
[f6e2532]153    @property
154    def multiple_operation_time_out(self):
[793432f]155        return ipp.MultipleOperationTimeOut(240)
[f6e2532]156
157    @property
158    def multiple_document_jobs_supported(self):
[793432f]159        return ipp.MultipleDocumentJobsSupported(False)
[f6e2532]160
[ee8e6d0]161    ## Printer operations
162
163    def get_printer_attributes(self, request=None):
164        if request and 'requested-attributes' in request:
165            requested = []
166            for value in request['requested-attributes'].values:
167                if value.value in self.attributes:
168                    requested.append(value.value)
169        else:
170            requested = self.attributes
171           
172        attributes = [getattr(self, attr) for attr in requested]
[b2e077a]173        return attributes
174
[ee8e6d0]175    def create_job(self, request):
176        operation = request.attribute_groups[0]
177        kwargs = {}
178       
179        # requesting username
180        if 'requesting-user-name' in operation:
181            username_attr = operation['requesting-user-name']
182            username = username_attr.values[0].value
183            if username_attr != ipp.RequestingUserName(username):
184                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
185            kwargs['creator'] = username
186
187        # job name
188        if 'job-name' in operation:
189            job_name_attr = operation['job-name']
190            job_name = job_name_attr.values[0].value
191            if job_name_attr != ipp.JobName(job_name):
192                raise ipp.errors.ClientErrorBadRequest(str(job_name_attr))
193            kwargs['name'] = job_name
194
195        # job size
196        if 'job-k-octets' in operation:
197            job_k_octets_attr = operation['job-k-octets']
198            job_k_octets = job_k_octets_attr.values[0].value
199            if job_k_octets_attr != ipp.JobKOctets(job_k_octets):
200                raise ipp.errors.ClientErrorBadRequest(str(job_k_octets_attr))
201            kwargs['size'] = job_k_octets
202
203        job_id = self._next_jobid
204        self._next_jobid += 1
205       
206        job = Job(job_id, self, **kwargs)
207        self.jobs[job_id] = job
208        self.active_jobs.append(job_id)
209        return job
[776a659]210
[e58af05]211    def send_document(self, jobid, document):
212        job = self.jobs[jobid]
213        if job.status != ipp.JobStates.HELD:
214            raise InvalidPrinterStateException(
215                "Invalid job state: %d" % job.status)
216        job.document = document
[ce2abc5]217        logger.debug("document for job %d is '%s'" % (jobid, job.document.name))
[e58af05]218        job.status = ipp.JobStates.PENDING
219
[776a659]220    def print_job(self, job):
[ee8e6d0]221        pass
[776a659]222
223    def complete_job(self, jobid):
[5d24a81]224        job = self.jobs[self.active_jobs.pop(0)]
[776a659]225        self.finished_jobs.append(job)
226        job.finish()
[e58af05]227        return job.jid
[776a659]228
229    def start_job(self, jobid):
[5d24a81]230        job = self.jobs[self.active_jobs[0]]
[e58af05]231        if job.status != ipp.JobStates.PENDING:
[776a659]232            raise InvalidPrinterStateException(
[e58af05]233                "Invalid job state: %s" % job.status)
[776a659]234        job.play()
235
[e58af05]236    @property
237    def next_job(self):
238        if len(self.active_jobs) == 0:
239            job = None
240        else:
241            job = self.active_jobs[0]
[ce2abc5]242        return job
243
244    def stop(self):
245        if len(self.active_jobs) == 0:
246            return
247        job = self.jobs[self.active_jobs[0]]
248        if job.player is not None:
249            logger.info("stopping printer %s" % self.name)
250            job.player.terminate()
[e58af05]251
[776a659]252    def get_job(self, jobid):
253        if jobid not in self.jobs:
254            raise InvalidJobException(jobid)
255        return self.jobs[jobid]
256
[b2e077a]257    def get_jobs(self):
[ee8e6d0]258        print self.active_jobs
[b2e077a]259        jobs = [self.jobs[job_id] for job_id in self.active_jobs]
[ee8e6d0]260        return jobs
[b2e077a]261
[ee8e6d0]262    # def __repr__(self):
263    #     return str(self)
[776a659]264
[ee8e6d0]265    # def __str__(self):
266    #     return "<Printer '%s'>" % self.name
Note: See TracBrowser for help on using the repository browser.