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

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

Clean up printer, job, and requests code

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