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

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

Queueing jobs (and playing them through mplayer) works

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