Index: server/lib/gutenbach/server/job.py
===================================================================
--- server/lib/gutenbach/server/job.py	(revision 34a4e5d730962d108163c14fafd961f93db9c5db)
+++ server/lib/gutenbach/server/job.py	(revision 33ea5054308a544bb5f939b99ad15f59fa4b6d7a)
@@ -1,30 +1,18 @@
-from . import InvalidJobStateException, MissingDataException
+from .errors import InvalidJobStateException, MissingDataException
 from .player import Player
 from gutenbach.ipp import JobStates as States
+import logging
 import os
-import gutenbach.ipp as ipp
-import logging
 
 # initialize logger
 logger = logging.getLogger(__name__)
 
-class Job(object):
+class GutenbachJob(object):
 
-    # for IPP
-    attributes = [
-        "job-id",
-        "job-name",
-        "job-originating-user-name",
-        "job-k-octets",
-        "job-state",
-        "job-printer-uri"
-    ]
-
-    def __init__(self, job_id=-1, printer=None, creator=None, name=None, size=None):
+    def __init__(self, job_id=None, creator=None, name=None):
 	"""Create an empty Gutenbach job.
 
 	"""
 
-	self.printer = printer
         self.player = None
 
@@ -32,13 +20,8 @@
         self.creator = creator
         self.name = name
-        self.size = size
 	self.state = States.HELD
         self.priority = 1
+        self.document = None
 
-        self.document_name = None
-        self.document_format = None
-        self.document_natural_language = None
-        self.compression = None
-    
     def __repr__(self):
 	return str(self)
@@ -67,13 +50,4 @@
         except TypeError:
             self._id = -1
-
-    @property
-    def uri(self):
-        return self.uris[0]
-
-    @property
-    def uris(self):
-        return ["ipp://localhost/jobs/%d" % self.id,
-                "ipp://localhost:8000/jobs/%d" % self.id]
 
     @property
@@ -109,11 +83,9 @@
 
         """
-        return self._size
-    @size.setter
-    def size(self, val):
         try:
-            self._size = int(val)
-        except TypeError:
-            self._size = 0
+            size = os.path.getsize(self.document)
+        except:
+            size = 0
+        return size
 
     @property
@@ -135,6 +107,24 @@
     ######################################################################
 
+    def spool(self, document, username=None):
+        if self.state != States.HELD:
+            raise InvalidJobStateException(self.state)
+
+        self.document = document.name
+        self.player = Player(document)
+        self.creator = username
+        self.state = States.PENDING
+
+        logger.debug("document for job %d is '%s'" % (self.id, self.document))
+
+
     def play(self):
-        """Non-blocking play function.
+        """Non-blocking play function.  Sets the job state to
+        PROCESSING.
+
+        Raises
+        ------
+        InvalidJobStateException
+            If the job is not ready to be played.
 
         """
@@ -142,122 +132,58 @@
         # make sure the job is waiting to be played and that it's
         # valid
-        if self.state != States.PENDING:
+        if not self.is_ready:
             raise InvalidJobStateException(self.state)
         
         # and set the state to processing if we're good to go
         logger.info("playing job %s" % str(self))
+
+        def _completed():
+            logger.info("completed job %s" % str(self))
+            self.state = States.COMPLETE
+            self.player = None
+
 	self.state = States.PROCESSING
-        self.player.callback = self._completed
+        self.player.callback = _completed
         self.player.start()
 
     def pause(self):
-        if self.is_playing:
-            self.player.mplayer_pause()
-            self.state = States.STOPPED
+        """Non-blocking pause function.  Sets the job state to
+        STOPPED.
+
+        """
+        
+        if not self.is_playing:
+            raise InvalidJobStateException(self.state)
+        
+        self.player.mplayer_pause()
+        self.state = States.STOPPED
 
     def cancel(self):
+        def _canceled():
+            logger.info("canceled job %s" % str(self))
+            self.state = States.CANCELLED
+            self.player = None
+
         if self.is_playing:
-            self.player.callback = self._canceled
+            self.player.callback = _canceled
             self.player.mplayer_stop()
+        elif self.is_finished:
+            raise InvalidJobStateException(self.state)
+        
         self.state = States.CANCELLED
 
     def abort(self):
+        def _aborted():
+            logger.info("aborted job %s" % str(self))
+            self.state = States.ABORTED
+            self.player = None
+
         if self.is_playing:
-            self.player.callback = self._aborted
+            self.player.callback = _aborted
             self.player.mplayer_stop()
-        self.state = states.ABORTED
-
-    def _completed(self):
-        logger.info("completed job %s" % str(self))
-	self.state = States.COMPLETE
-        self.player = None
-
-    def _canceled(self):
-        logger.info("canceled job %s" % str(self))
-        self.state = States.CANCELLED
-        self.player = None
-
-    def _aborted(self):
-        logger.info("aborted job %s" % str(self))
+        elif self.is_finished:
+            raise InvalidJobStateException(self.state)
+        
         self.state = States.ABORTED
-        self.player = None
-
-    ######################################################################
-    ###                        IPP Attributes                          ###
-    ######################################################################
-
-    @property
-    def job_id(self):
-        return ipp.JobId(self.id)
-
-    @property
-    def job_name(self):
-        return ipp.JobName(self.name)
-
-    @property
-    def job_originating_user_name(self):
-        return ipp.JobOriginatingUserName(self.creator)
-
-    @property
-    def job_k_octets(self):
-        return ipp.JobKOctets(self.size)
-
-    @property
-    def job_state(self):
-        return ipp.JobState(self.state)
-
-    @property
-    def job_printer_uri(self):
-        return ipp.JobPrinterUri(self.printer.uri)
 
 
-    ######################################################################
-    ###                        IPP Operations                          ###
-    ######################################################################
-
-    def cancel_job(self):
-        pass
-
-    def send_document(self, document, document_name=None,
-                      document_format=None, document_natural_language=None,
-                      requesting_user_name=None, compression=None,
-                      last_document=None):
-
-        if self.state != States.HELD:
-            raise InvalidJobStateException(self.state)
-
-        self.player = Player(document)
-
-        if self.size == 0:
-            self.size = os.path.getsize(document.name)
-        
-        self.document_name = str(document_name)
-        self.document_format = str(document_format)
-        self.document_natural_language = str(document_natural_language)
-        self.creator = str(requesting_user_name)
-        self.compression = str(compression)
-        self.state = States.PENDING
-
-        logger.debug("document for job %d is '%s'" % (self.id, self.document_name))
-
-    def send_uri(self):
-        pass
-
-    def get_job_attributes(self, requested_attributes=None):
-        if requested_attributes is None:
-            requested = self.attributes
-        else:
-            requested = [a for a in self.attributes if a in requested_attributes]
-
-        _attributes = [attr.replace("-", "_") for attr in requested]
-        attributes = [getattr(self, attr) for attr in _attributes]
-        return attributes
-
-    def set_job_attributes(self):
-        pass
-
-    def restart_job(self):
-        pass
-
-    def promote_job(self):
-        pass
