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

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

Fix error with HTTP server recreating printer objects

  • Property mode set to 100644
File size: 7.3 KB
Line 
1#import alsaaudio as aa
2from .exceptions import InvalidJobException, InvalidPrinterStateException
3from .job 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        self._next_jobid = 0
70
71    def __getattr__(self, attr):
72        try:
73            return self.__getattribute__(attr)
74        except AttributeError:
75            pass
76        return self.__getattribute__(attr.replace("-", "_"))
77
78    def __hasattr__(self, attr):
79        try:
80            getattr(self, attr)
81            return True
82        except AttributeError:
83            return False
84
85    ## Printer attributes
86
87    @property
88    def printer_uri_supported(self):
89        return ipp.PrinterUriSupported(self.uri)
90
91    @property
92    def uri_authentication_supported(self):
93        return ipp.UriAuthenticationSupported("none")
94
95    @property
96    def uri_security_supported(self):
97        return ipp.UriSecuritySupported("none")
98
99    @property
100    def printer_name(self):
101        return ipp.PrinterName(self.name)
102
103    @property
104    def printer_state(self):
105        return ipp.PrinterState(ipp.constants.PrinterStates.IDLE)
106
107    @property
108    def printer_state_reasons(self):
109        return ipp.PrinterStateReasons("none")
110
111    @property
112    def ipp_versions_supported(self):
113        return ipp.IppVersionsSupported("1.0", "1.1")
114
115    # XXX: We should query ourself for the supported operations
116    @property
117    def operations_supported(self):
118        return ipp.OperationsSupported(ipp.OperationCodes.GET_JOBS)
119
120    @property
121    def charset_configured(self):
122        return ipp.CharsetConfigured("utf-8")
123
124    @property
125    def charset_supported(self):
126        return ipp.CharsetSupported("utf-8")
127
128    @property
129    def natural_language_configured(self):
130        return ipp.NaturalLanguageConfigured("en-us")
131
132    @property
133    def generated_natural_language_supported(self):
134        return ipp.GeneratedNaturalLanguageSupported("en-us")
135
136    @property
137    def document_format_default(self):
138        return ipp.DocumentFormatDefault("application/octet-stream")
139
140    @property
141    def document_format_supported(self):
142        return ipp.DocumentFormatSupported("application/octet-stream", "audio/mp3")
143
144    @property
145    def printer_is_accepting_jobs(self):
146        return ipp.PrinterIsAcceptingJobs(True)
147
148    @property
149    def queued_job_count(self):
150        return ipp.QueuedJobCount(len(self.active_jobs))
151
152    @property
153    def pdl_override_supported(self):
154        return ipp.PdlOverrideSupported("not-attempted")
155
156    @property
157    def printer_up_time(self):
158        return ipp.PrinterUpTime(int(time.time()) - self.time_created)
159
160    @property
161    def compression_supported(self):
162        return ipp.CompressionSupported("none")
163
164    @property
165    def multiple_operation_time_out(self):
166        return ipp.MultipleOperationTimeOut(240)
167
168    @property
169    def multiple_document_jobs_supported(self):
170        return ipp.MultipleDocumentJobsSupported(False)
171
172    ## Printer operations
173
174    def get_printer_attributes(self, request=None):
175        if request and 'requested-attributes' in request:
176            requested = []
177            for value in request['requested-attributes'].values:
178                if value.value in self.attributes:
179                    requested.append(value.value)
180        else:
181            requested = self.attributes
182           
183        attributes = [getattr(self, attr) for attr in requested]
184        return attributes
185
186    def create_job(self, request):
187        operation = request.attribute_groups[0]
188        kwargs = {}
189       
190        # requesting username
191        if 'requesting-user-name' in operation:
192            username_attr = operation['requesting-user-name']
193            username = username_attr.values[0].value
194            if username_attr != ipp.RequestingUserName(username):
195                raise ipp.errors.ClientErrorBadRequest(str(username_attr))
196            kwargs['creator'] = username
197
198        # job name
199        if 'job-name' in operation:
200            job_name_attr = operation['job-name']
201            job_name = job_name_attr.values[0].value
202            if job_name_attr != ipp.JobName(job_name):
203                raise ipp.errors.ClientErrorBadRequest(str(job_name_attr))
204            kwargs['name'] = job_name
205
206        # job size
207        if 'job-k-octets' in operation:
208            job_k_octets_attr = operation['job-k-octets']
209            job_k_octets = job_k_octets_attr.values[0].value
210            if job_k_octets_attr != ipp.JobKOctets(job_k_octets):
211                raise ipp.errors.ClientErrorBadRequest(str(job_k_octets_attr))
212            kwargs['size'] = job_k_octets
213
214        job_id = self._next_jobid
215        self._next_jobid += 1
216       
217        job = Job(job_id, self, **kwargs)
218        self.jobs[job_id] = job
219        self.active_jobs.append(job_id)
220        print self.active_jobs
221        return job
222
223    def print_job(self, job):
224        pass
225
226    def complete_job(self, jobid):
227        job = self.jobs[self.active_jobs.pop(0)]
228        if job.jobid != jobid:
229            raise InvalidJobException(
230                "Completed job %d has unexpected job id %d!" % \
231                (job.jobid, jobid))
232       
233        self.finished_jobs.append(job)
234        job.finish()
235        return job.jobid
236
237    def start_job(self, jobid):
238        job = self.jobs[self.active_jobs[0]]
239        if job.jobid != jobid:
240            raise InvalidJobException(
241                "Completed job %d has unexpected job id %d!" % \
242                (job.jobid, jobid))
243
244        if job.status == 'playing':
245            raise InvalidPrinterStateException(
246                "Next job in queue (id %d) is " + \
247                "already playing!" % jobid)
248
249        job.play()
250
251    def get_job(self, jobid):
252        if jobid not in self.jobs:
253            raise InvalidJobException(jobid)
254        return self.jobs[jobid]
255
256    def get_jobs(self):
257        print self.active_jobs
258        jobs = [self.jobs[job_id] for job_id in self.active_jobs]
259        return jobs
260
261    # def __repr__(self):
262    #     return str(self)
263
264    # def __str__(self):
265    #     return "<Printer '%s'>" % self.name
Note: See TracBrowser for help on using the repository browser.