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
RevLine 
[b2e077a]1#import alsaaudio as aa
[d04a689]2from .exceptions import InvalidJobException, InvalidPrinterStateException
[ee8e6d0]3from .job import Job
[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       
46
[b2e077a]47    #def __init__(self, name, card, mixer):
48    def __init__(self, name):
49
[1a63bf7]50        self.name = name
51        self.uri = "ipp://localhost:8000/printers/" + self.name
52        self.time_created = int(time.time())
53        self.state = "idle"
[b2e077a]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)
[776a659]61       
[b2e077a]62        # self.card = card
63        # self.mixer = mixer
[776a659]64
65        self.finished_jobs = []
66        self.active_jobs = []
67        self.jobs = {}
68
[5d24a81]69        self._next_jobid = 0
[776a659]70
[1a63bf7]71    def __getattr__(self, attr):
72        try:
[6effd50]73            return self.__getattribute__(attr)
[1a63bf7]74        except AttributeError:
75            pass
[6effd50]76        return self.__getattribute__(attr.replace("-", "_"))
[1a63bf7]77
78    def __hasattr__(self, attr):
[6effd50]79        try:
80            getattr(self, attr)
81            return True
82        except AttributeError:
83            return False
[1a63bf7]84
[b2e077a]85    ## Printer attributes
[1a63bf7]86
[b2e077a]87    @property
88    def printer_uri_supported(self):
[793432f]89        return ipp.PrinterUriSupported(self.uri)
[1a63bf7]90
[b2e077a]91    @property
92    def uri_authentication_supported(self):
[793432f]93        return ipp.UriAuthenticationSupported("none")
[b2e077a]94
95    @property
96    def uri_security_supported(self):
[793432f]97        return ipp.UriSecuritySupported("none")
[b2e077a]98
99    @property
100    def printer_name(self):
[793432f]101        return ipp.PrinterName(self.name)
[1a63bf7]102
[b2e077a]103    @property
104    def printer_state(self):
[793432f]105        return ipp.PrinterState(ipp.constants.PrinterStates.IDLE)
[1a63bf7]106
[b2e077a]107    @property
108    def printer_state_reasons(self):
[793432f]109        return ipp.PrinterStateReasons("none")
[b2e077a]110
111    @property
112    def ipp_versions_supported(self):
[793432f]113        return ipp.IppVersionsSupported("1.0", "1.1")
[1a63bf7]114
[f6e2532]115    # XXX: We should query ourself for the supported operations
[b2e077a]116    @property
117    def operations_supported(self):
[793432f]118        return ipp.OperationsSupported(ipp.OperationCodes.GET_JOBS)
[b2e077a]119
120    @property
121    def charset_configured(self):
[793432f]122        return ipp.CharsetConfigured("utf-8")
[b2e077a]123
124    @property
125    def charset_supported(self):
[793432f]126        return ipp.CharsetSupported("utf-8")
[b2e077a]127
128    @property
129    def natural_language_configured(self):
[793432f]130        return ipp.NaturalLanguageConfigured("en-us")
[b2e077a]131
132    @property
133    def generated_natural_language_supported(self):
[793432f]134        return ipp.GeneratedNaturalLanguageSupported("en-us")
[b2e077a]135
136    @property
137    def document_format_default(self):
[793432f]138        return ipp.DocumentFormatDefault("application/octet-stream")
[b2e077a]139
140    @property
141    def document_format_supported(self):
[793432f]142        return ipp.DocumentFormatSupported("application/octet-stream", "audio/mp3")
[b2e077a]143
144    @property
145    def printer_is_accepting_jobs(self):
[793432f]146        return ipp.PrinterIsAcceptingJobs(True)
[b2e077a]147
148    @property
149    def queued_job_count(self):
[793432f]150        return ipp.QueuedJobCount(len(self.active_jobs))
[b2e077a]151
152    @property
153    def pdl_override_supported(self):
[793432f]154        return ipp.PdlOverrideSupported("not-attempted")
[b2e077a]155
156    @property
157    def printer_up_time(self):
[793432f]158        return ipp.PrinterUpTime(int(time.time()) - self.time_created)
[b2e077a]159
160    @property
161    def compression_supported(self):
[793432f]162        return ipp.CompressionSupported("none")
[b2e077a]163
[f6e2532]164    @property
165    def multiple_operation_time_out(self):
[793432f]166        return ipp.MultipleOperationTimeOut(240)
[f6e2532]167
168    @property
169    def multiple_document_jobs_supported(self):
[793432f]170        return ipp.MultipleDocumentJobsSupported(False)
[f6e2532]171
[ee8e6d0]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]
[b2e077a]184        return attributes
185
[ee8e6d0]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
[776a659]222
223    def print_job(self, job):
[ee8e6d0]224        pass
[776a659]225
226    def complete_job(self, jobid):
[5d24a81]227        job = self.jobs[self.active_jobs.pop(0)]
[776a659]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):
[5d24a81]238        job = self.jobs[self.active_jobs[0]]
[776a659]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
[b2e077a]256    def get_jobs(self):
[ee8e6d0]257        print self.active_jobs
[b2e077a]258        jobs = [self.jobs[job_id] for job_id in self.active_jobs]
[ee8e6d0]259        return jobs
[b2e077a]260
[ee8e6d0]261    # def __repr__(self):
262    #     return str(self)
[776a659]263
[ee8e6d0]264    # def __str__(self):
265    #     return "<Printer '%s'>" % self.name
Note: See TracBrowser for help on using the repository browser.