Changeset 279640c


Ignore:
Timestamp:
Jan 21, 2012, 5:20:56 PM (12 years ago)
Author:
Daniel Cooper <danny@…>
Branches:
no-cups
Children:
7f1098c
Parents:
f70792f (diff), 57bc2dc (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:20:56)
git-committer:
Daniel Cooper <danny@…> (01/21/12 17:20:56)
Message:

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

Location:
server/lib
Files:
4 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
  • server/lib/gutenbach/server/requests.py

    rc1dc25f rf70792f  
    169169
    170170        """
     171        operation = request.attribute_groups[0]
     172        # requested printer uri
     173        if 'printer-uri' not in operation:
     174            raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
     175        printer_uri = verify_attribute(operation['printer-uri'], ipp.PrinterUri)[0]
     176        if printer_uri not in self.printer.uris:
     177            raise ipp.errors.ClientErrorAttributes(
     178                str(operation['printer-uri']), operation['printer-uri'])
     179
     180        if 'requesting-user-name' in operation:
     181            user_name = verify_attribute(
     182                operation['requesting-user-name'], ipp.RequestingUserName)[0]
     183
     184        if 'job-name' in operation:
     185            job_name = verify_attribute(
     186                operation['job-name'], ipp.JobName)[0]
     187
     188        if 'job-k-octets' in operation:
     189            job_k_octets = verify_attribute(
     190                operation['job-k-octets'], ipp.JobKOctets)[0]
     191
     192        if 'ipp-attribute-fidelity' in operation:
     193            pass # don't care
     194        if 'job-impressions' in operation:
     195            pass # don't care
     196        if 'job-media-sheets' in operation:
     197            pass # don't care
     198
     199        # get attributes from the printer and add to response
     200        job_id = self.printer.create_job(
     201            requesting_user_name=requesting_user_name,
     202            job_name=job_name,
     203            job_k_octets=job_k_octets)
     204        attrs = self.printer.get_job_attributes(job_id)
     205        response.attribute_groups.append(ipp.AttributeGroup(
     206            ipp.AttributeTags.JOB, attrs))
     207            #raise ipp.errors.ServerErrorOperationNotSupported
     208        # Get nescessary information for calling send_document
     209        # Any field being set to None here just means that we either aren't using or haven't implemented parsing it
     210        document = request.attribute_groups[2]
     211        #XXX
     212        document_format = None
     213        document_natural_language = None
     214        compression = None
     215        last_document = None
     216
     217
    171218       
    172         raise ipp.errors.ServerErrorOperationNotSupported
    173 
     219        # Actually put the document in the job
     220        self.printer.send_document(job_id,document,
     221                document_name = document_name,
     222                document_format = document_format,
     223                document_natural_language = document_natural_language,
     224                requesting_user_name = requesting_user_name,
     225                compression = compression,
     226                last_document = last_document)
     227        #fix this once jess pushes
     228        self.print_job()
    174229    @handler_for(ipp.OperationCodes.VALIDATE_JOB)
    175230    def validate_job(self, request, response):
Note: See TracChangeset for help on using the changeset viewer.