Changeset f70792f
- Timestamp:
- Jan 21, 2012, 5:11:09 PM (13 years ago)
- Branches:
- no-cups
- Children:
- 279640c
- Parents:
- 4914b47 (diff), 374c558 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - git-author:
- Daniel Cooper <danny@…> (01/21/12 17:11:09)
- git-committer:
- Daniel Cooper <danny@…> (01/21/12 17:11:09)
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r01e3017 rd17381b 3 3 debian/ 4 4 *.pyc 5 *.log 6 *.log.* 7 tags -
queue/lib/build-gutenbach-queue
r8b676cb r374c558 7 7 while true; do 8 8 time=$(date) 9 echo "This is a work in progress! Please send bugs to jhamrick." >> /tmp/gutenbach/current_queue_temp9 echo "This is a work in progress! Please send bugs to gutenbach@mit.edu." >> /tmp/gutenbach/current_queue_temp 10 10 echo "" >> /tmp/gutenbach/current_queue_temp 11 11 echo "As of $time:" >> /tmp/gutenbach/current_queue_temp -
server/lib/TODO
rc1cebbc r374c558 4 4 5 5 - finish implementing a bunch of the IPP handlers 6 [ ] print job 6 7 [ ] validate job 7 8 [ ] pause printer … … 15 16 16 17 - add support in printer.py for: 18 [ ] print job 17 19 [ ] validate job 18 [ 19 [ 20 [ 21 [ 22 [ 20 [x] pause printer 21 [x] resume printer 22 [\] set printer attributes 23 [\] send uri 24 [\] set job attributes 23 25 [X] restart job 24 26 [\] promote job 25 27 26 28 - add support in job.py for: 27 [ ] restart job 29 [X] restart job 30 [x] resume job 28 31 29 32 - finish test cases for printer.py … … 52 55 - local streaming 53 56 - generic streaming 57 - zephyr control (e.g. youtube link) 54 58 55 59 Tickets that should be fixed by this new version: 56 http://gutenbach.mit.edu/ticket/2157 http://gutenbach.mit.edu/ticket/258 http://gutenbach.mit.edu/ticket/759 http://gutenbach.mit.edu/ticket/3960 http://gutenbach.mit.edu/ticket/4761 http://gutenbach.mit.edu/ticket/4862 http://gutenbach.mit.edu/ticket/863 http://gutenbach.mit.edu/ticket/3464 http://gutenbach.mit.edu/ticket/3865 http://gutenbach.mit.edu/ticket/4166 http://gutenbach.mit.edu/ticket/1860 [ ] http://gutenbach.mit.edu/ticket/21 61 [ ] http://gutenbach.mit.edu/ticket/2 62 [ ] http://gutenbach.mit.edu/ticket/7 63 [ ] http://gutenbach.mit.edu/ticket/39 64 [ ] http://gutenbach.mit.edu/ticket/47 65 [ ] http://gutenbach.mit.edu/ticket/48 66 [ ] http://gutenbach.mit.edu/ticket/8 67 [ ] http://gutenbach.mit.edu/ticket/34 68 [x] http://gutenbach.mit.edu/ticket/38 69 [ ] http://gutenbach.mit.edu/ticket/41 70 [ ] http://gutenbach.mit.edu/ticket/18 -
server/lib/gutenbach/server/__init__.py
ra9eb577e rcf0d7e8 3 3 __all__ = ['errors'] 4 4 __all__.extend(errors.__all__) 5 6 def sync(func): 7 """Lock decorator 8 9 Holds a lock (self.lock) for the durration of a method call. 10 """ 11 12 def do(self, *args, **kwargs): 13 with self.lock: 14 return func(self, *args, **kwargs) 15 16 return do 17 __all__.append('sync') 18 5 19 6 20 from job import GutenbachJob -
server/lib/gutenbach/server/job.py
rc1cebbc r9225351 322 322 self.player.mplayer_pause() 323 323 324 def resume(self): 325 """Non-blocking resume. Job must be paused (see 326 'GutenbachJob.is_paused'). 327 328 Raises 329 ------ 330 InvalidJobStateException 331 If the job is not paused. 332 333 """ 334 if not self.is_paused: 335 raise errors.InvalidJobStateException(self.state) 336 self.player.mplayer_pause() 337 324 338 def cancel(self): 325 339 """Blocking cancel. The job must not have been previously -
server/lib/gutenbach/server/player.py
ra9eb577e rcf0d7e8 3 3 import subprocess 4 4 import time 5 from . import sync 5 6 6 7 # initialize logger … … 24 25 25 26 @property 27 @sync 26 28 def is_playing(self): 27 with self.lock: 28 if self._dryrun: 29 playing = self.isAlive() and not self.is_done 30 else: 31 playing = self.isAlive() and \ 32 not self.is_done and \ 33 self.player is not None and \ 34 self.player.poll() is None 35 return playing 29 if self._dryrun: 30 return self.isAlive() and not self.is_done 31 else: 32 return self.isAlive() and \ 33 not self.is_done and \ 34 self.player is not None and \ 35 self.player.poll() is None 36 36 37 37 @property 38 @sync 38 39 def is_paused(self): 39 with self.lock: 40 paused = self.is_playing and self._paused 41 return paused 40 return self.is_playing and self._paused 42 41 43 42 @property … … 49 48 return self._callback 50 49 @callback.setter 50 @sync 51 51 def callback(self, val): 52 with self.lock: 53 self._callback = val 52 self._callback = val 54 53 55 54 def start(self): … … 112 111 113 112 def mplayer_pause(self): 113 # Note: Inner lock due to sleep. 114 114 with self.lock: 115 115 if self.is_playing: … … 123 123 124 124 def mplayer_stop(self): 125 # Note: Inner Lock due to join. 125 126 with self.lock: 126 127 if self.is_playing: -
server/lib/gutenbach/server/printer.py
rc1cebbc r9225351 9 9 import traceback 10 10 import sys 11 from . import sync 11 12 12 13 … … 100 101 with self.lock: 101 102 try: 102 if self.current_job is None:103 if not self.paused and self.current_job is None: 103 104 self.start_job() 104 105 elif self.current_job.is_done: … … 124 125 125 126 @property 127 @sync 126 128 def state(self): 127 with self.lock: 128 if self.current_job is not None: 129 val = States.PROCESSING 130 elif len(self.pending_jobs) == 0: 131 val = States.IDLE 132 else: 133 val = States.STOPPED 134 return val 135 136 @property 129 if self.current_job is not None: 130 return States.PROCESSING 131 elif len(self.pending_jobs) == 0: 132 return States.IDLE 133 else: 134 return States.STOPPED 135 136 @property 137 @sync 137 138 def active_jobs(self): 138 with self.lock: 139 jobs = self.pending_jobs[:] 140 if self.current_job is not None: 141 jobs.insert(0, self.current_job.id) 139 jobs = self.pending_jobs[:] 140 if self.current_job is not None: 141 jobs.insert(0, self.current_job.id) 142 142 return jobs 143 143 … … 146 146 ###################################################################### 147 147 148 @sync 148 149 def start_job(self): 149 with self.lock: 150 if self.current_job is None: 151 try: 152 job_id = heapq.heappop(self.pending_jobs) 153 self.current_job = self.get_job(job_id) 154 self.current_job.play() 155 except IndexError: 156 self.current_job = None 157 except InvalidJobStateException: 158 heapq.heappush(self.pending_jobs, self.current_job.id) 159 self.current_job = None 150 if self.current_job is None: 151 try: 152 job_id = heapq.heappop(self.pending_jobs) 153 self.current_job = self.get_job(job_id) 154 self.current_job.play() 155 except IndexError: 156 self.current_job = None 157 except InvalidJobStateException: 158 heapq.heappush(self.pending_jobs, self.current_job.id) 159 self.current_job = None 160 160 161 @sync 161 162 def complete_job(self): 162 with self.lock:163 if self.current_job is None:164 return 165 166 try:167 if not self.current_job.is_done:168 self.current_job.stop()169 finally:170 self.finished_jobs.append(self.current_job.id)171 self.current_job = None 172 163 if self.current_job is None: 164 return 165 166 try: 167 if not self.current_job.is_done: 168 self.current_job.stop() 169 finally: 170 self.finished_jobs.append(self.current_job.id) 171 self.current_job = None 172 173 @sync 173 174 def get_job(self, job_id): 174 with self.lock: 175 if job_id not in self.jobs: 176 raise InvalidJobException(job_id) 177 job = self.jobs[job_id] 178 return job 175 if job_id not in self.jobs: 176 raise InvalidJobException(job_id) 177 return self.jobs[job_id] 179 178 180 179 ###################################################################### … … 185 184 def printer_uri_supported(self): 186 185 return ipp.PrinterUriSupported(self.uri) 186 @printer_uri_supported.setter 187 def printer_uri_supported(self, val): 188 raise ipp.errors.AttributesNotSettable("printer-uri-supported") 187 189 188 190 @property 189 191 def uri_authentication_supported(self): 190 192 return ipp.UriAuthenticationSupported("none") 193 @uri_authentication_supported.setter 194 def uri_authentication_supported(self, val): 195 raise ipp.errors.AttributesNotSettable("uri-authentication-supported") 191 196 192 197 @property 193 198 def uri_security_supported(self): 194 199 return ipp.UriSecuritySupported("none") 200 @uri_security_supported.setter 201 def uri_security_supported(self, val): 202 raise ipp.errors.AttributesNotSettable("uri-security-supported") 195 203 196 204 @property 197 205 def printer_name(self): 198 206 return ipp.PrinterName(self.name) 207 @printer_name.setter 208 def printer_name(self, val): 209 raise ipp.errors.AttributesNotSettable("printer-name") 199 210 200 211 @property 201 212 def printer_state(self): 202 213 return ipp.PrinterState(self.state) 214 @printer_state.setter 215 def printer_state(self, val): 216 raise ipp.errors.AttributesNotSettable("printer-state") 203 217 204 218 @property 205 219 def printer_state_reasons(self): 206 220 return ipp.PrinterStateReasons("none") 221 @printer_state_reasons.setter 222 def printer_state_reasons(self, val): 223 raise ipp.errors.AttributesNotSettable("printer-state-reasons") 207 224 208 225 @property 209 226 def ipp_versions_supported(self): 210 227 return ipp.IppVersionsSupported(*self.config['ipp-versions']) 228 @ipp_versions_supported.setter 229 def ipp_versions_supported(self, val): 230 raise ipp.errors.AttributesNotSettable("ipp-versions-supported") 211 231 212 232 # XXX: We should query ourself for the supported operations … … 214 234 def operations_supported(self): 215 235 return ipp.OperationsSupported(ipp.OperationCodes.GET_JOBS) 236 @operations_supported.setter 237 def operations_supported(self, val): 238 raise ipp.errors.AttributesNotSettable("operations-supported") 216 239 217 240 @property 218 241 def charset_configured(self): 219 return ipp.CharsetConfigured("utf-8") 220 242 return ipp.CharsetConfigured("utf-8") # XXX 243 @charset_configured.setter 244 def charset_configured(self, val): 245 raise ipp.errors.AttributesNotSettable("charset-configured") 246 221 247 @property 222 248 def charset_supported(self): 223 return ipp.CharsetSupported("utf-8") 249 return ipp.CharsetSupported("utf-8") # XXX 250 @charset_supported.setter 251 def charset_supported(self, val): 252 raise ipp.errors.AttributesNotSettable("charset-supported") 224 253 225 254 @property 226 255 def natural_language_configured(self): 227 256 return ipp.NaturalLanguageConfigured("en-us") 257 @natural_language_configured.setter 258 def natural_language_configured(self, val): 259 raise ipp.errors.AttributesNotSettable("natural-language-configured") 228 260 229 261 @property 230 262 def generated_natural_language_supported(self): 231 263 return ipp.GeneratedNaturalLanguageSupported("en-us") 264 @generated_natural_language_supported.setter 265 def generated_natural_language_supported(self, val): 266 raise ipp.errors.AttributesNotSettable("generated-natural-language-supported") 232 267 233 268 @property 234 269 def document_format_default(self): 235 270 return ipp.DocumentFormatDefault("application/octet-stream") 271 @document_format_default.setter 272 def document_format_default(self, val): 273 raise ipp.errors.AttributesNotSettable("document-format-default") 236 274 237 275 @property 238 276 def document_format_supported(self): 239 277 return ipp.DocumentFormatSupported("application/octet-stream", "audio/mp3") 278 @document_format_supported.setter 279 def document_format_supported(self, val): 280 raise ipp.errors.AttributesNotSettable("document-format-supported") 240 281 241 282 @property 242 283 def printer_is_accepting_jobs(self): 243 284 return ipp.PrinterIsAcceptingJobs(True) 285 @printer_is_accepting_jobs.setter 286 def printer_is_accepting_jobs(self, val): 287 raise ipp.errors.AttributesNotSettable("printer-is-accepting-jobs") 244 288 245 289 @property 246 290 def queued_job_count(self): 247 291 return ipp.QueuedJobCount(len(self.active_jobs)) 292 @queued_job_count.setter 293 def queued_job_count(self, val): 294 raise ipp.errors.AttributesNotSettable("queued-job-count") 248 295 249 296 @property 250 297 def pdl_override_supported(self): 251 298 return ipp.PdlOverrideSupported("not-attempted") 299 @pdl_override_supported.setter 300 def pdl_override_supported(self, val): 301 raise ipp.errors.AttributesNotSettable("pdl-override-supported") 252 302 253 303 @property 254 304 def printer_up_time(self): 255 305 return ipp.PrinterUpTime(int(time.time()) - self.time_created) 306 @printer_up_time.setter 307 def printer_up_time(self, val): 308 raise ipp.errors.AttributesNotSettable("printer-up-time") 256 309 257 310 @property 258 311 def compression_supported(self): 259 312 return ipp.CompressionSupported("none") 313 @compression_supported.setter 314 def compression_supported(self, val): 315 raise ipp.errors.AttributesNotSettable("compression-supported") 260 316 261 317 @property 262 318 def multiple_operation_time_out(self): 263 319 return ipp.MultipleOperationTimeOut(240) 320 @multiple_operation_time_out.setter 321 def multiple_operation_time_out(self, val): 322 raise ipp.errors.AttributesNotSettable("multiple-operation-time-out") 264 323 265 324 @property 266 325 def multiple_document_jobs_supported(self): 267 326 return ipp.MultipleDocumentJobsSupported(False) 327 @multiple_document_jobs_supported.setter 328 def multiple_document_jobs_supported(self, val): 329 raise ipp.errors.AttributesNotSettable("multiple-document-jobs-supported") 268 330 269 331 ###################################################################### … … 349 411 return job_id 350 412 413 @sync 351 414 def pause_printer(self): 352 pass 353 415 """Pause the printer. 416 417 Does nothing if the printer is already paused. 418 """ 419 if self.paused: 420 return 421 422 if self.current_job is not None and self.current_job.is_playing: 423 self.current_job.pause() 424 425 self.paused = True 426 427 428 429 @sync 354 430 def resume_printer(self): 355 pass 431 """Resume the printer. 432 433 Does nothing if the printer is not paused. 434 """ 435 if not self.paused: 436 return 437 438 if self.current_job is not None: 439 self.current_job.resume() 440 441 self.paused = False 356 442 357 443 def get_printer_attributes(self, requested_attributes=None): … … 366 452 return attributes 367 453 368 def set_printer_attributes(self): 369 pass 454 def set_printer_attributes(self, job_id, attributes): 455 for attr in attributes: 456 try: 457 setattr(self, attr, attributes[attr]) 458 except AttributeError: 459 raise ipp.errors.ClientErrorAttributes 370 460 371 461 def cancel_job(self, job_id, requesting_user_name=None): … … 385 475 job.spool(document) 386 476 387 def send_uri(self): 388 pass 477 def send_uri(self, job_id, document_uri, document_name=None, 478 document_format=None, document_natural_language=None, 479 requesting_user_name=None, compression=None, 480 last_document=None): 481 job = self.get_job(job_id) 482 # XXX: need to validate URI 483 # XXX: need to deal with the URI stream? 484 #job.spool_uri(document_uri) 389 485 390 486 def get_job_attributes(self, job_id, requested_attributes=None): … … 399 495 return attributes 400 496 401 def set_job_attributes(self): 402 pass 403 497 def set_job_attributes(self, job_id, attributes): 498 job = self.get_job(job_id) 499 for attr in attributes: 500 if attr in ("job-id", "job-k-octets", "job-state", "job-printer-uri"): 501 raise ipp.errors.ClientErrorAttributesNotSettable(attr) 502 elif attr == "job-name": 503 job.name = attributes[attr] 504 elif attr == "job-originating-user-name": 505 job.creator = attributes[attr] # XXX: do we want this? 506 404 507 def restart_job(self, job_id, requesting_user_name=None): 405 508 job = self.get_job(job_id) -
server/lib/gutenbach/server/requests.py
r4914b47 rf70792f 985 985 REQUIRED 'job-id' (integer(1:MAX)) and 'printer-uri' (uri) 986 986 REQUIRED 'document-uri' (uri) 987 -or-'job-uri' (uri)987 OPTIONAL 'job-uri' (uri) 988 988 OPTIONAL 'requesting-user-name' (name(MAX)) 989 989 OPTIONAL 'document-name' (name(MAX)) … … 991 991 OPTIONAL 'document-format' (mimeMediaType) 992 992 OPTIONAL 'document-natural-language' (naturalLanguage) 993 Group 2: Document Content994 993 995 994 Response … … 1069 1068 self.printer.send_uri( 1070 1069 job_id, 1071 document_uri =document_uri,1070 document_uri, 1072 1071 document_name=document_name, 1073 1072 document_format=document_format,
Note: See TracChangeset
for help on using the changeset viewer.