def run(self):
        '''Main body of the code.'''
        
        logging.debug('ProcessDVD called with argument ' + self.path)
        (base_dir,file_name)=os.path.split(self.path)
        (root,ext)=os.path.splitext(file_name)
        logging.debug('Changing directory to ' + base_dir)
        os.chdir(base_dir)
        if ext == '.ISO' or ext == '.iso':
            logging.debug('ISO file detected, proceding to mount')
            logging.debug('Making directory ' + root)
            try:
                os.mkdir(root)
            except OSError:
                logging.debug('Directory exists, using existing')
                if len(os.listdir(root)) != 0:
                    logging.debug('It appears something is mounted at '+root)
                    logging.debug('Attempting unmount')
                    try:
                        subprocess.check_call(['sudo','umount',root])
                    except:
                        logging.debug('Unmount failed')
                        sys.exit('Mountpoint exists and has contents')
                
            logging.debug('Mounting iso '+file_name+' to '+root)
            try:
                subprocess.check_call(['sudo','mount','-o','loop',file_name,root])
            except:
                sys.exit('An unhandled exception occurred while executing a mount command. \
                Check that you have passwordless sudo mount enabled')
            self.cur_disk_path=os.path.join(base_dir,root)         
        elif ext == '.mp4' or ext == '.MP4' or ext == '.mkv' or ext == '.MKV' \
        or ext == '.avi' or ext == '.AVI' or ext == '.mts' or ext == '.MTS':
            logging.debug('Non-ISO video file detected')
            self.cur_disk_path=self.path
        else:
            logging.error('Only ISOs, MP4s, MKVs, MTSs, and AVIs are handled')
            sys.exit('Only ISOs, MP4s, MKVs, MTSs, and AVIs are handled')
            
        logging.debug('Scanning video')
        parsed_DVD=parseDVD(self.cur_disk_path)
        logging.debug('Generating encoding commands')
        logging.debug('self.compression_type is ' + str(self.compression_type))
        f=globals()[str(self.compression_type)]
        commands=jobGenerator(parsed_DVD,f())

        if ext == '.ISO' or ext == '.iso':
            logging.debug('Unmounting ISO')
            try:
                subprocess.check_call(['sudo','umount',root])
            except:
                logging.error('Unmounting failed.  Ensure that passworless sudo umount\
                is enabled')  
            logging.debug('Removing temporary mount directory')
            try:
                os.rmdir(root)
            except:
                logging.error('Unable to remove temporary mount directory '+root)
                
        logging.debug('Establishing connection with message server')
        writer=MessageWriter(server=MESSAGE_SERVER, vhost=VHOST, \
                         userid=MESSAGE_USERID, password=MESSAGE_PWD, \
                         exchange=EXCHANGE, exchange_durable=True, \
                         exchange_auto_delete=False, exchange_type='direct',\
                         routing_key=JOB_QUEUE, queue_durable=True,\
                         queue_auto_delete=False)
        
        for i,command in enumerate(commands):
            job_mountpoint=''
            if ext == '.ISO' or ext == '.iso':
                #Must mount an ISO, will leave mounted until job complete message
                job_mountpoint=root+'_job_'+str(i)
                logging.debug('Making job subdirectory ' + job_mountpoint)
                try:
                    os.mkdir(job_mountpoint)
                except OSError:
                    logging.debug('Directory already exists, assuming previous mount')
                    if len(os.listdir(job_mountpoint)) != 0:
                        try:
                            subprocess.check_call(['sudo','umount',job_mountpoint])
                        except:
                            logging.error('Unable to unmount ' + job_mountpoint +'. Skipping')
                            continue
                logging.debug('Mounting ISO at ' + job_mountpoint)
                try:
                    subprocess.check_call(['sudo','mount','-o','loop',file_name,job_mountpoint])
                except:
                    logging.error('Unhandled exception while mounting ISO for job.\
                     Check that passworless sudo mount is available.')
                    logging.error('Skipping')
                    continue
            else:
                job_mountpoint=file_name
            logging.debug('Appending output file to command')
            command.append('-i')
            command.append(job_mountpoint)
            logging.debug('Sending complete command to message server')
            myip=socket.gethostbyname(socket.getfqdn())
            ftp_location='ftp://' + str(myip)+ ':' + str(FTP_PORT) + '/jobs/' + job_mountpoint
            writer.send_message(pickle.dumps([job_mountpoint,ftp_location,command]))
            logging.debug([job_mountpoint,ftp_location,command])
            
        writer.close()            
    def run(self):
        '''Creates required directories, base_dir at ~/cluster_programs/project_name
        copies source and encoder to temporary job directory, encodes the source
        uploads the resulting files to the file server, and deletes all temporary
        files.
        
        Sends status updates on encode to the message server every second'''
        
        homedir = os.path.expanduser('~')
        projectdir = os.path.join(homedir, 'cluster_programs', self._project_name)
        jobdir=os.path.join(homedir, 'cluster_programs', self._project_name, self._job_name)
        sourcedir=os.path.join('\\\\', self._server_ip,self._source_path)
        outputdir=os.path.join('\\\\', self._server_ip, self._destination_path)
        
        os.chdir(projectdir)
        try:
            os.mkdir(self._job_name)
        except OSError:
            logging.debug('Directory' + self._job_name +' exists, continuing using existing dir')
        
        shutil.copy(self._exe_name, self._job_name)
        os.chdir(jobdir)


        logging.debug('Connecting with message server')
        status_updates=MessageWriter(server=self._message_server, vhost=self._vhost, userid=self._userid, password=self._password, exchange='direct_transfer', exchange_durable=True, \
                              exchange_auto_delete=False, exchange_type='direct', routing_key=self._server_hostname, queue_durable=False, queue_auto_delete=True)
        logging.debug('Connection with message server established')
        
        logging.debug('Copying Source')                      
        status_updates.send_message(self._encode_message('Copying Source'))
        if os.path.exists('source'):
            shutil.rmtree('source')
        shutil.copytree(sourcedir, 'source')
        status_updates.send_message(self._encode_message('Finished Copying Source'))
        logging.debug('Finished Copying Source')
        
        logging.debug('Starting encode process '+self._exe_name)
        status_updates.send_message(self._encode_message('Starting Process '+self._exe_name))
        proc = subprocess.Popen(self._command, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
        
        loglock=threading.Lock()
        logfile='encodinglog.txt'

        t = ProcessMonitor(proc, logfile, loglock)
        t.start()
        
        while proc.poll() is None:
            time.sleep(30)
            loglock.acquire()
            log=open(logfile, 'rU')
            current_progress=tail(log, 1)
            log.close()
            loglock.release()
            logging.debug(current_progress)
            status_updates.send_message(self._encode_message(current_progress))
            
        logging.debug('Finished Encoding')
        status_updates.send_message(self._encode_message('Finished Encoding'))
        
        logging.debug('Copying Output to Server')
        status_updates.send_message(self._encode_message('Copying Output to Server'))
        shutil.copy(self._output_file, outputdir)
        logging.debug('Finished Copying Output to Server')
        status_updates.send_message(self._encode_message('Finished Copying Output to Server'))
        
        os.chdir(homedir)
        logging.debug('Deleting temporary files and directories')
        shutil.rmtree(path=jobdir, ignore_errors=True)
        logging.debug('Closing connection with message server')
        status_updates.close()