source: server/lib/gutenbach/server/job.py @ eee389a

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

Better threading model

  • Property mode set to 100644
File size: 7.0 KB
Line 
1from . import InvalidJobStateException, MissingDataException
2from .player import Player
3from gutenbach.ipp import JobStates as States
4import os
5import gutenbach.ipp as ipp
6import logging
7
8# initialize logger
9logger = logging.getLogger(__name__)
10
11class Job(object):
12
13    # for IPP
14    attributes = [
15        "job-id",
16        "job-name",
17        "job-originating-user-name",
18        "job-k-octets",
19        "job-state",
20        "job-printer-uri"
21    ]
22
23    def __init__(self, job_id=-1, printer=None, creator=None, name=None, size=None):
24        """Create an empty Gutenbach job.
25
26        """
27
28        self.printer = printer
29        self.player = None
30
31        self.id = job_id
32        self.creator = creator
33        self.name = name
34        self.size = size
35        self.state = States.HELD
36        self.priority = 1
37
38        self.document_name = None
39        self.document_format = None
40        self.document_natural_language = None
41        self.compression = None
42   
43    def __repr__(self):
44        return str(self)
45
46    def __str__(self):
47        return "<Job %d '%s'>" % (self.id, self.name)
48
49    def __cmp__(self, other):
50        return cmp(self.priority, other.priority)
51
52    ######################################################################
53    ###                          Properties                            ###
54    ######################################################################
55
56    @property
57    def id(self):
58        """Unique job identifier.  Should be a positive integer,
59        except when unassigned, when it defaults to -1.
60       
61        """
62        return self._id
63    @id.setter
64    def id(self, val):
65        try:
66            self._id = int(val)
67        except TypeError:
68            self._id = -1
69
70    @property
71    def creator(self):
72        """The user who created the job; analogous to the IPP
73        requesting-user-name.
74
75        """
76        return self._creator
77    @creator.setter
78    def creator(self, val):
79        if val is None:
80            self._creator = ""
81        else:
82            self._creator = str(val)
83
84    @property
85    def name(self):
86        """The job's name.
87
88        """
89        return self._name
90    @name.setter
91    def name(self, val):
92        if val is None:
93            self._name = ""
94        else:
95            self._name = str(val)
96
97    @property
98    def size(self):
99        """The size of the job in bytes.
100
101        """
102        return self._size
103    @size.setter
104    def size(self, val):
105        try:
106            self._size = int(val)
107        except TypeError:
108            self._size = 0
109
110    @property
111    def is_playing(self):
112        return self.state == States.PROCESSING
113
114    @property
115    def is_ready(self):
116        return self.state == States.PENDING
117
118    @property
119    def is_finished(self):
120        return self.state != States.PENDING and self.state != States.PROCESSING
121       
122    ######################################################################
123    ###                            Methods                             ###
124    ######################################################################
125
126    def play(self):
127        """Non-blocking play function.
128
129        """
130       
131        # make sure the job is waiting to be played and that it's
132        # valid
133        if self.state != States.PENDING:
134            raise InvalidJobStateException(self.state)
135       
136        # and set the state to processing if we're good to go
137        logger.info("playing job %s" % str(self))
138        self.state = States.PROCESSING
139        self.player.callback = self._completed
140        self.player.run()
141
142    def pause(self):
143        if self.player:
144            self.player.mplayer_pause()
145
146    def stop(self):
147        if self.player:
148            self.player.callback = self._stopped
149            self.player.mplayer_stop()
150
151    def _completed(self):
152        if self.state != States.PROCESSING:
153            raise InvalidJobStateException(self.state)
154        logger.info("completed job %s" % str(self))
155        self.state = States.COMPLETE
156        self.player = None
157
158    def _canceled(self):
159        if self.state != States.PROCESSING:
160            raise InvalidJobStateException(self.state)
161        logger.info("canceled job %s" % str(self))
162        self.state = States.CANCELLED
163        self.player = None
164
165    def _stopped(self):
166        if self.state != States.PROCESSING:
167            raise InvalidJobStateException(self.state)
168        logger.info("stopped job %s" % str(self))
169        self.state = States.STOPPED
170        self.player = None
171
172    def _aborted(self):
173        if self.state != States.PROCESSING:
174            raise InvalidJobStateException(self.state)
175        logger.info("aborted job %s" % str(self))
176        self.state = States.ABORTED
177        self.player = None
178
179    ######################################################################
180    ###                        IPP Attributes                          ###
181    ######################################################################
182
183    @property
184    def job_id(self):
185        return ipp.JobId(self.id)
186
187    @property
188    def job_name(self):
189        return ipp.JobName(self.name)
190
191    @property
192    def job_originating_user_name(self):
193        return ipp.JobOriginatingUserName(self.creator)
194
195    @property
196    def job_k_octets(self):
197        return ipp.JobKOctets(self.size)
198
199    @property
200    def job_state(self):
201        return ipp.JobState(self.state)
202
203    @property
204    def job_printer_uri(self):
205        return ipp.JobPrinterUri(self.printer.uri)
206
207
208    ######################################################################
209    ###                        IPP Operations                          ###
210    ######################################################################
211
212    def cancel_job(self):
213        pass
214
215    def send_document(self, document, document_name=None,
216                      document_format=None, document_natural_language=None,
217                      requesting_user_name=None, compression=None,
218                      last_document=None):
219
220        if self.state != States.HELD:
221            raise InvalidJobStateException(self.state)
222
223        self.player = Player(document)
224
225        if self.size == 0:
226            self.size = os.path.getsize(document.name)
227       
228        self.document_name = str(document_name)
229        self.document_format = str(document_format)
230        self.document_natural_language = str(document_natural_language)
231        self.creator = str(requesting_user_name)
232        self.compression = str(compression)
233        self.state = States.PENDING
234
235        logger.debug("document for job %d is '%s'" % (self.id, self.document_name))
236
237    def send_uri(self):
238        pass
239
240    def get_job_attributes(self, requested_attributes=None):
241        if requested_attributes is None:
242            requested = self.attributes
243        else:
244            requested = [a for a in self.attributes if a in requested_attributes]
245
246        _attributes = [attr.replace("-", "_") for attr in requested]
247        attributes = [getattr(self, attr) for attr in _attributes]
248        return attributes
249
250    def set_job_attributes(self):
251        pass
252
253    def restart_job(self):
254        pass
255
256    def promote_job(self):
257        pass
Note: See TracBrowser for help on using the repository browser.