Changeset f70792f


Ignore:
Timestamp:
Jan 21, 2012, 5:11:09 PM (12 years ago)
Author:
Daniel Cooper <danny@…>
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)
Message:

Merge branch 'no-cups' of github.com:jhamrick/gutenbach into no-cups

Files:
8 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r01e3017 rd17381b  
    33debian/
    44*.pyc
     5*.log
     6*.log.*
     7tags
  • queue/lib/build-gutenbach-queue

    r8b676cb r374c558  
    77while true; do
    88    time=$(date)
    9     echo "This is a work in progress!  Please send bugs to jhamrick." >> /tmp/gutenbach/current_queue_temp
     9    echo "This is a work in progress!  Please send bugs to gutenbach@mit.edu." >> /tmp/gutenbach/current_queue_temp
    1010    echo "" >> /tmp/gutenbach/current_queue_temp
    1111    echo "As of $time:" >> /tmp/gutenbach/current_queue_temp
  • server/lib/TODO

    rc1cebbc r374c558  
    44
    55- finish implementing a bunch of the IPP handlers
     6     [ ] print job
    67     [ ] validate job
    78     [ ] pause printer
     
    1516
    1617- add support in printer.py for:
     18     [ ] print job
    1719     [ ] validate job
    18      [ ] pause printer
    19      [ ] resume printer
    20      [ ] set printer attributes
    21      [ ] send uri
    22      [ ] set job attributes
     20     [x] pause printer
     21     [x] resume printer
     22     [\] set printer attributes
     23     [\] send uri
     24     [\] set job attributes
    2325     [X] restart job
    2426     [\] promote job
    2527
    2628- add support in job.py for:
    27      [ ] restart job
     29     [X] restart job
     30     [x] resume job
    2831
    2932- finish test cases for printer.py
     
    5255   - local streaming
    5356   - generic streaming
     57   - zephyr control (e.g. youtube link)
    5458
    5559Tickets that should be fixed by this new version:
    56    http://gutenbach.mit.edu/ticket/21
    57    http://gutenbach.mit.edu/ticket/2
    58    http://gutenbach.mit.edu/ticket/7
    59    http://gutenbach.mit.edu/ticket/39
    60    http://gutenbach.mit.edu/ticket/47
    61    http://gutenbach.mit.edu/ticket/48
    62    http://gutenbach.mit.edu/ticket/8
    63    http://gutenbach.mit.edu/ticket/34
    64    http://gutenbach.mit.edu/ticket/38
    65    http://gutenbach.mit.edu/ticket/41
    66    http://gutenbach.mit.edu/ticket/18
     60   [ ] 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  
    33__all__ = ['errors']
    44__all__.extend(errors.__all__)
     5
     6def 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
    519
    620from job import GutenbachJob
  • server/lib/gutenbach/server/job.py

    rc1cebbc r9225351  
    322322        self.player.mplayer_pause()
    323323
     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
    324338    def cancel(self):
    325339        """Blocking cancel. The job must not have been previously
  • server/lib/gutenbach/server/player.py

    ra9eb577e rcf0d7e8  
    33import subprocess
    44import time
     5from . import sync
    56
    67# initialize logger
     
    2425
    2526    @property
     27    @sync
    2628    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
    3636
    3737    @property
     38    @sync
    3839    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
    4241
    4342    @property
     
    4948        return self._callback
    5049    @callback.setter
     50    @sync
    5151    def callback(self, val):
    52         with self.lock:
    53             self._callback = val
     52        self._callback = val
    5453
    5554    def start(self):
     
    112111
    113112    def mplayer_pause(self):
     113        # Note: Inner lock due to sleep.
    114114        with self.lock:
    115115            if self.is_playing:
     
    123123               
    124124    def mplayer_stop(self):
     125        # Note: Inner Lock due to join.
    125126        with self.lock:
    126127            if self.is_playing:
  • server/lib/gutenbach/server/printer.py

    rc1cebbc r9225351  
    99import traceback
    1010import sys
     11from . import sync
    1112
    1213
     
    100101            with self.lock:
    101102                try:
    102                     if self.current_job is None:
     103                    if not self.paused and self.current_job is None:
    103104                        self.start_job()
    104105                    elif self.current_job.is_done:
     
    124125
    125126    @property
     127    @sync
    126128    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
    137138    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)
    142142        return jobs
    143143
     
    146146    ######################################################################
    147147
     148    @sync
    148149    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
    160160                   
     161    @sync
    161162    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
    173174    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]
    179178
    180179    ######################################################################
     
    185184    def printer_uri_supported(self):
    186185        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")
    187189
    188190    @property
    189191    def uri_authentication_supported(self):
    190192        return ipp.UriAuthenticationSupported("none")
     193    @uri_authentication_supported.setter
     194    def uri_authentication_supported(self, val):
     195        raise ipp.errors.AttributesNotSettable("uri-authentication-supported")
    191196
    192197    @property
    193198    def uri_security_supported(self):
    194199        return ipp.UriSecuritySupported("none")
     200    @uri_security_supported.setter
     201    def uri_security_supported(self, val):
     202        raise ipp.errors.AttributesNotSettable("uri-security-supported")
    195203
    196204    @property
    197205    def printer_name(self):
    198206        return ipp.PrinterName(self.name)
     207    @printer_name.setter
     208    def printer_name(self, val):
     209        raise ipp.errors.AttributesNotSettable("printer-name")
    199210
    200211    @property
    201212    def printer_state(self):
    202213        return ipp.PrinterState(self.state)
     214    @printer_state.setter
     215    def printer_state(self, val):
     216        raise ipp.errors.AttributesNotSettable("printer-state")
    203217
    204218    @property
    205219    def printer_state_reasons(self):
    206220        return ipp.PrinterStateReasons("none")
     221    @printer_state_reasons.setter
     222    def printer_state_reasons(self, val):
     223        raise ipp.errors.AttributesNotSettable("printer-state-reasons")
    207224
    208225    @property
    209226    def ipp_versions_supported(self):
    210227        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")
    211231
    212232    # XXX: We should query ourself for the supported operations
     
    214234    def operations_supported(self):
    215235        return ipp.OperationsSupported(ipp.OperationCodes.GET_JOBS)
     236    @operations_supported.setter
     237    def operations_supported(self, val):
     238        raise ipp.errors.AttributesNotSettable("operations-supported")
    216239
    217240    @property
    218241    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       
    221247    @property
    222248    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")
    224253
    225254    @property
    226255    def natural_language_configured(self):
    227256        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")
    228260
    229261    @property
    230262    def generated_natural_language_supported(self):
    231263        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")
    232267
    233268    @property
    234269    def document_format_default(self):
    235270        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")
    236274
    237275    @property
    238276    def document_format_supported(self):
    239277        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")
    240281
    241282    @property
    242283    def printer_is_accepting_jobs(self):
    243284        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")
    244288
    245289    @property
    246290    def queued_job_count(self):
    247291        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")
    248295
    249296    @property
    250297    def pdl_override_supported(self):
    251298        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")
    252302
    253303    @property
    254304    def printer_up_time(self):
    255305        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")
    256309
    257310    @property
    258311    def compression_supported(self):
    259312        return ipp.CompressionSupported("none")
     313    @compression_supported.setter
     314    def compression_supported(self, val):
     315        raise ipp.errors.AttributesNotSettable("compression-supported")
    260316
    261317    @property
    262318    def multiple_operation_time_out(self):
    263319        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")
    264323
    265324    @property
    266325    def multiple_document_jobs_supported(self):
    267326        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")
    268330
    269331    ######################################################################
     
    349411        return job_id
    350412
     413    @sync
    351414    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
    354430    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
    356442
    357443    def get_printer_attributes(self, requested_attributes=None):
     
    366452        return attributes
    367453
    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
    370460
    371461    def cancel_job(self, job_id, requesting_user_name=None):
     
    385475        job.spool(document)
    386476
    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)
    389485
    390486    def get_job_attributes(self, job_id, requested_attributes=None):
     
    399495        return attributes
    400496
    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               
    404507    def restart_job(self, job_id, requesting_user_name=None):
    405508        job = self.get_job(job_id)
  • server/lib/gutenbach/server/requests.py

    r4914b47 rf70792f  
    985985            REQUIRED 'job-id' (integer(1:MAX)) and 'printer-uri' (uri)
    986986            REQUIRED 'document-uri' (uri)
    987               -or-  'job-uri' (uri)
     987            OPTIONAL 'job-uri' (uri)
    988988            OPTIONAL 'requesting-user-name' (name(MAX))
    989989            OPTIONAL 'document-name' (name(MAX))
     
    991991            OPTIONAL 'document-format' (mimeMediaType)
    992992            OPTIONAL 'document-natural-language' (naturalLanguage)
    993         Group 2: Document Content
    994993           
    995994        Response
     
    10691068            self.printer.send_uri(
    10701069                job_id,
    1071                 document_uri=document_uri,
     1070                document_uri,
    10721071                document_name=document_name,
    10731072                document_format=document_format,
Note: See TracChangeset for help on using the changeset viewer.