Changes in / [f70792f:279640c]


Ignore:
Location:
server/lib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • server/lib/TODO

    r374c558 rf0807b8  
    6969   [ ] http://gutenbach.mit.edu/ticket/41
    7070   [ ] http://gutenbach.mit.edu/ticket/18
     71
     72 === CONSIDERATIONS FOR MPD ===
     73
     74We are considering using MPD (the Music Player Daemon) for playback, instead
     75of mplayer.  This gives us a pony (gapless playback), and makes some other
     76things, like keeping track of the queue, much easier.  There is a lot of work
     77needed to make this work, though.
     78
     79THIS ADDS A DEPENDENCY:  python-mpd
     80
     81We will have to re-implement all the functions in jobs.py, and completely
     82re-structure player.py
     83
     84If we want video playback eventually (and we do), there will be some hackery
     85involved.  We will pause mpd playback, do the video playback completely
     86separately, and then resume mpd playback.
     87
     88Some almost-pseudocode:
     89
     90startup:
     91  client = MPDClient()
     92  client.connect(**{'host':'/var/run/mpd/socket', 'port':'6600'})
     93
     94adding a song to the queue:
     95  Receive job
     96  Put it into a file                    [gutenbach/FILENAME]
     97  Tell MPD to add it to the queue       [client.addid('gutenbach/FILENAME')]
     98  Find out what the id is
     99  Store all the data [including the temporary filename]
     100  IF WE ARE SUPPOSED TO BE PLAYING, MAKE SURE WE *ARE* PLAYING
     101    In particular, if the queue was empty, start playback   [gutenbach.play()]
     102
     103when a job completes playing:
     104  Remove the file                       [rm gutenbach/FILENAME]
     105
     106getting the queue:
     107  get playlist, parse return            [client.playlistid()]
     108
     109removing a job:
     110  dequeue it                  [client.deleteid('NUMBER')]
     111  remove the file
     112  tell them what you did
     113
     114restart song:
     115  client.seek(0,1)   [0% through song 1...]
     116
  • server/lib/gutenbach/server/job.py

    r9225351 r57bc2dc  
    5353        """
    5454        return cmp(self.priority, other.priority)
     55
     56    def __del__(self):
     57        if self.player:
     58            self.player.mplayer_stop()
     59            self.player = None
     60        if self.document and not self.document.closed:
     61            self.document.close()
     62            self.document = None
     63
     64        self.id = None
     65        self.creator = None
     66        self.name = None
     67        self.priority = None
     68        self._why_done = None
    5569
    5670    ######################################################################
     
    259273        if not hasattr(document, "close"):
    260274            raise errors.InvalidDocument, "no close attribute"
     275        if not hasattr(document, "closed"):
     276            raise errors.InvalidDocument, "no closed attribute"
    261277
    262278    def spool(self, document=None):
  • server/lib/gutenbach/server/printer.py

    r9225351 r57bc2dc  
    99import traceback
    1010import sys
     11import tempfile
    1112from . import sync
    1213
     
    361362    ######################################################################
    362363
    363     def print_job(self):
    364         pass
    365 
    366     def validate_job(self):
    367         pass
     364    def print_job(self, document, document_name=None, document_format=None,
     365                  document_natural_language=None, requesting_user_name=None,
     366                  compression=None, job_name=None, job_k_octets=None):
     367
     368        # create the job
     369        job_id = self.create_job(
     370            requesting_user_name=requesting_user_name,
     371            job_name=job_name,
     372            job_k_octets=job_k_octets)
     373       
     374        # send the document
     375        self.send_document(
     376            job_id,
     377            document,
     378            document_name=document_name,
     379            document_format=document_format,
     380            document_natural_language=document_natural_language,
     381            requesting_user_name=requesting_user_name,
     382            compression=compression,
     383            last_document=False)
     384
     385        return job_id
     386
     387    def verify_job(self, document_name=None, document_format=None,
     388                  document_natural_language=None, requesting_user_name=None,
     389                  compression=None, job_name=None, job_k_octets=None):
     390
     391        job_id = self._next_job_id
     392        job = GutenbachJob(
     393            job_id,
     394            creator=requesting_user_name,
     395            name=job_name)
     396        job.spool(tempfile.TemporaryFile())
     397        job.abort()
     398        del job
    368399
    369400    def get_jobs(self, requesting_user_name=None, which_jobs=None,
     
    397428        pass
    398429
    399     def create_job(self, requesting_user_name=None, job_name=None, job_k_octets=None):
     430    def create_job(self, requesting_user_name=None, job_name=None,
     431                   job_k_octets=None):
     432
    400433        job_id = self._next_job_id
    401434        self._next_job_id += 1
     
    405438            creator=requesting_user_name,
    406439            name=job_name)
    407        
     440
    408441        self.jobs[job_id] = job
    409442        self.pending_jobs.append(job_id)
     
    425458        self.paused = True
    426459
    427 
    428 
    429460    @sync
    430461    def resume_printer(self):
     
    441472        self.paused = False
    442473
     474    @sync
    443475    def get_printer_attributes(self, requested_attributes=None):
    444476        if requested_attributes is None:
     
    452484        return attributes
    453485
     486    @sync
    454487    def set_printer_attributes(self, job_id, attributes):
    455488        for attr in attributes:
     
    459492                raise ipp.errors.ClientErrorAttributes
    460493
     494    @sync
    461495    def cancel_job(self, job_id, requesting_user_name=None):
    462496        job = self.get_job(job_id)
     
    467501            raise
    468502
     503    @sync
    469504    def send_document(self, job_id, document, document_name=None,
    470505                      document_format=None, document_natural_language=None,
     
    475510        job.spool(document)
    476511
     512    @sync
    477513    def send_uri(self, job_id, document_uri, document_name=None,
    478514                 document_format=None, document_natural_language=None,
     
    484520        #job.spool_uri(document_uri)
    485521
     522    @sync
    486523    def get_job_attributes(self, job_id, requested_attributes=None):
    487524        if requested_attributes is None:
     
    495532        return attributes
    496533
     534    @sync
    497535    def set_job_attributes(self, job_id, attributes):
    498536        job = self.get_job(job_id)
     
    504542            elif attr == "job-originating-user-name":
    505543                job.creator = attributes[attr] # XXX: do we want this?
    506                
     544
     545    @sync
    507546    def restart_job(self, job_id, requesting_user_name=None):
    508547        job = self.get_job(job_id)
     
    513552            raise ipp.errors.ClientErrorNotPossible
    514553
    515         with self.lock:
    516             self.finished_jobs.remove(job_id)
    517             self.pending_jobs.append(job_id)
    518 
     554        self.finished_jobs.remove(job_id)
     555        self.pending_jobs.append(job_id)
     556
     557    @sync
    519558    def promote_job(self, job_id, requesting_user_name=None):
    520559        # According to RFC 3998, we need to put the job at the front
Note: See TracChangeset for help on using the changeset viewer.