* This is a scrap todo file while the new IPP server based Gutenbach is * being developed. Once this branch is released and becomes master, * items in this file will be merged into the Trac. - finish implementing a bunch of the IPP handlers [X] print job [X] validate job [X] print uri [X] pause printer [X] resume printer [X] set printer attributes [X] send uri [ ] set job attributes [ ] restart job [ ] promote job [ ] cups get document - add support in printer.py for: [x] print job [x] validate job [x] pause printer [x] resume printer [\] set printer attributes [\] send uri [\] set job attributes [X] restart job [\] promote job - add support in job.py for: [X] restart job [x] resume job - server stuff [ ] write convenience client-side API [ ] setuptools entry points for notification system (e.g. zephyr) [ ] deal with queue management/reordering [ ] add support for volume management [ ] support authentication/security - client-ish stuff [ ] rewrite gbr/gbq/etc. scripts to use client API [ ] rewrite server-side queue display to use API - misc [ ] make sure all CUPS commands are compatible [ ] deal with all the code marked 'XXX' - documentation and testing test cases for printer.py [X] TestEmptyGutenbachPrinter [X] TestBadEmptyGutenbachPrinter [ ] testPrintJob [ ] testValidateJob [ ] testGetJobs [ ] testPrintUri [X] testCreateJob [X] testPausePrinter [X] testResumePrinter [ ] testGetPrinterAttributes [ ] testSetPrinterAttributes [ ] testCancelJob [ ] testSendDocument [ ] testSendUri [ ] testGetJobAttributes [ ] testSetJobAttributes [ ] testRestartJob [ ] testPromoteJob test cases for requests.py [ ] testPrintJob [ ] testValidateJob [ ] testGetJobs [ ] testPrintUri [ ] testCreateJob [ ] testPausePrinter [ ] testResumePrinter [ ] testGetPrinterAttributes [ ] testSetPrinterAttributes [ ] testCancelJob [ ] testSendDocument [ ] testSendUri [ ] testGetJobAttributes [ ] testSetJobAttributes [ ] testRestartJob [ ] testPromoteJob [ ] testCupsGetDocument [ ] testCupsGetDefault [ ] testCupsGetPrinters [ ] testCupsGetClasses [ ] write test cases for future client API [ ] all the documentation [ ] check test case coverage ( http://nedbatchelder.com/code/coverage/ ) [ ] why doesn't the bug tracker work?! relatedly, figure out a solution that makes it easier for non-MIT developers to contribute Ponies - gapless playback - display video - youtube - pandora - last.fm - local streaming - generic streaming - zephyr control (e.g. youtube link) Tickets that should be fixed by this new version: [ ] http://gutenbach.mit.edu/ticket/21 [ ] http://gutenbach.mit.edu/ticket/2 [ ] http://gutenbach.mit.edu/ticket/7 [ ] http://gutenbach.mit.edu/ticket/39 [ ] http://gutenbach.mit.edu/ticket/47 [ ] http://gutenbach.mit.edu/ticket/48 [ ] http://gutenbach.mit.edu/ticket/8 [ ] http://gutenbach.mit.edu/ticket/34 [x] http://gutenbach.mit.edu/ticket/38 [ ] http://gutenbach.mit.edu/ticket/41 [ ] http://gutenbach.mit.edu/ticket/18 === CONSIDERATIONS FOR MPD === We are considering using MPD (the Music Player Daemon) for playback, instead of mplayer. This gives us a pony (gapless playback), and makes some other things, like keeping track of the queue, much easier. There is a lot of work needed to make this work, though. THIS ADDS A DEPENDENCY: python-mpd We will have to re-implement all the functions in jobs.py, and completely re-structure player.py If we want video playback eventually (and we do), there will be some hackery involved. We will pause mpd playback, do the video playback completely separately, and then resume mpd playback. Some almost-pseudocode: startup: client = MPDClient() client.connect(**{'host':'/var/run/mpd/socket', 'port':'6600'}) adding a song to the queue: Receive job Put it into a file [gutenbach/FILENAME] Tell MPD to add it to the queue [client.addid('gutenbach/FILENAME')] Find out what the id is Store all the data [including the temporary filename] IF WE ARE SUPPOSED TO BE PLAYING, MAKE SURE WE *ARE* PLAYING In particular, if the queue was empty, start playback [gutenbach.play()] when a job completes playing: Remove the file [rm gutenbach/FILENAME] getting the queue: get playlist, parse return [client.playlistid()] removing a job: dequeue it [client.deleteid('NUMBER')] remove the file tell them what you did restart song: client.seek(0,1) [0% through song 1...]