'Set history, datasets, and jobs\' attributes and clean up archive directory.'

def cleanup_after_job(self):

    def file_in_dir(file_path, a_dir):
        '    Returns    true    if    file    is    in    directory.    '
        abs_file_path = os.path.abspath(file_path)
        return (os.path.split(abs_file_path)[0] == a_dir)
    def read_file_contents(file_path):
        '    Read    contents    of    a    file.    '
        fp = open(file_path, 'rb')
        buffsize = 1048576
        file_contents = ''
        try:
            while True:
                file_contents += fp.read(buffsize)
                if ((not file_contents) or ((len(file_contents) % buffsize) != 0)):
                    break
        except OverflowError:
            pass
        fp.close()
        return file_contents
    def get_tag_str(tag, value):
        '    Builds    a    tag    string    for    a    tag,    value    pair.    '
        if (not value):
            return tag
        else:
            return ((tag + ':') + value)
    jiha = self.sa_session.query(model.JobImportHistoryArchive).filter_by(job_id=self.job_id).first()
    if jiha:
        try:
            archive_dir = jiha.archive_dir
            user = jiha.job.user
            if (not os.path.exists(os.path.join(archive_dir, 'history_attrs.txt'))):
                for d in os.listdir(archive_dir):
                    if os.path.isdir(os.path.join(archive_dir, d)):
                        archive_dir = os.path.join(archive_dir, d)
                        break
            history_attr_file_name = os.path.join(archive_dir, 'history_attrs.txt')
            history_attr_str = read_file_contents(history_attr_file_name)
            history_attrs = loads(history_attr_str)
            new_history = model.History(name=('imported    from    archive:    %s' % history_attrs['name'].encode('utf-8')), user=user)
            new_history.importing = True
            new_history.hid_counter = history_attrs['hid_counter']
            new_history.genome_build = history_attrs['genome_build']
            self.sa_session.add(new_history)
            jiha.history = new_history
            self.sa_session.flush()
            if user:
                self.add_item_annotation(self.sa_session, user, new_history, history_attrs['annotation'])
                "\n                                                                                TODO:    figure    out    to    how    add    tags    to    item.\n                                                                                for    tag,    value    in    history_attrs[    'tags'    ].items():\n                                                                                                trans.app.tag_handler.apply_item_tags(    trans,    trans.user,    new_history,    get_tag_str(    tag,    value    )    )\n                                                                                "
            datasets_attrs_file_name = os.path.join(archive_dir, 'datasets_attrs.txt')
            datasets_attr_str = read_file_contents(datasets_attrs_file_name)
            datasets_attrs = loads(datasets_attr_str)
            if os.path.exists((datasets_attrs_file_name + '.provenance')):
                provenance_attr_str = read_file_contents((datasets_attrs_file_name + '.provenance'))
                provenance_attrs = loads(provenance_attr_str)
                datasets_attrs += provenance_attrs
            datasets_usage_counts = {}
            for dataset_attrs in datasets_attrs:
                temp_dataset_file_name = os.path.abspath(os.path.join(archive_dir, dataset_attrs['file_name']))
                if (temp_dataset_file_name not in datasets_usage_counts):
                    datasets_usage_counts[temp_dataset_file_name] = 0
                datasets_usage_counts[temp_dataset_file_name] += 1
            for dataset_attrs in datasets_attrs:
                metadata = dataset_attrs['metadata']
                hda = model.HistoryDatasetAssociation(name=dataset_attrs['name'].encode('utf-8'), extension=dataset_attrs['extension'], info=dataset_attrs['info'].encode('utf-8'), blurb=dataset_attrs['blurb'], peek=dataset_attrs['peek'], designation=dataset_attrs['designation'], visible=dataset_attrs['visible'], dbkey=metadata['dbkey'], metadata=metadata, history=new_history, create_dataset=True, sa_session=self.sa_session)
                if ('uuid' in dataset_attrs):
                    hda.dataset.uuid = dataset_attrs['uuid']
                if (dataset_attrs.get('exported', True) is False):
                    hda.state = hda.states.DISCARDED
                    hda.deleted = True
                    hda.purged = True
                else:
                    hda.state = hda.states.OK
                self.sa_session.add(hda)
                self.sa_session.flush()
                new_history.add_dataset(hda, genome_build=None)
                hda.hid = dataset_attrs['hid']
                self.sa_session.flush()
                if (dataset_attrs.get('exported', True) is True):
                    temp_dataset_file_name = os.path.realpath(os.path.abspath(os.path.join(archive_dir, dataset_attrs['file_name'])))
                    if (not file_in_dir(temp_dataset_file_name, os.path.join(archive_dir, 'datasets'))):
                        raise MalformedContents(('Invalid    dataset    path:    %s' % temp_dataset_file_name))
                    if (datasets_usage_counts[temp_dataset_file_name] == 1):
                        self.app.object_store.update_from_file(hda.dataset, file_name=temp_dataset_file_name, create=True)
                        dataset_extra_files_path = dataset_attrs.get('extra_files_path', None)
                        if dataset_extra_files_path:
                            try:
                                file_list = os.listdir(os.path.join(archive_dir, dataset_extra_files_path))
                            except OSError:
                                file_list = []
                            if file_list:
                                for extra_file in file_list:
                                    self.app.object_store.update_from_file(hda.dataset, extra_dir=('dataset_%s_files' % hda.dataset.id), alt_name=extra_file, file_name=os.path.join(archive_dir, dataset_extra_files_path, extra_file), create=True)
                    else:
                        datasets_usage_counts[temp_dataset_file_name] -= 1
                        shutil.copyfile(temp_dataset_file_name, hda.file_name)
                    hda.dataset.set_total_size()
                if user:
                    self.add_item_annotation(self.sa_session, user, hda, dataset_attrs['annotation'])
                    "\n                                                                                                for    tag,    value    in    dataset_attrs[    'tags'    ].items():\n                                                                                                                trans.app.tag_handler.apply_item_tags(    trans,    trans.user,    hda,    get_tag_str(    tag,    value    )    )\n                                                                                                                self.sa_session.flush()\n                                                                                                "
                if (hda.extension == 'bam'):
                    self.app.datatypes_registry.set_external_metadata_tool.tool_action.execute_via_app(self.app.datatypes_registry.set_external_metadata_tool, self.app, jiha.job.session_id, new_history.id, jiha.job.user, incoming={'input1': hda}, overwrite=False)
            jobs_attr_file_name = os.path.join(archive_dir, 'jobs_attrs.txt')
            jobs_attr_str = read_file_contents(jobs_attr_file_name)
            def as_hda(obj_dct):
                "    Hook    to    'decode'    an    HDA;    method    uses    history    and    HID    to    get    the    HDA    represented    by\n                                                                                                the    encoded    object.    This    only    works    because    HDAs    are    created    above.    "
                if obj_dct.get('__HistoryDatasetAssociation__', False):
                    return self.sa_session.query(model.HistoryDatasetAssociation).filter_by(history=new_history, hid=obj_dct['hid']).first()
                return obj_dct
            jobs_attrs = loads(jobs_attr_str, object_hook=as_hda)
            for job_attrs in jobs_attrs:
                imported_job = model.Job()
                imported_job.user = user
                imported_job.history = new_history
                imported_job.imported = True
                imported_job.tool_id = job_attrs['tool_id']
                imported_job.tool_version = job_attrs['tool_version']
                imported_job.set_state(job_attrs['state'])
                imported_job.info = job_attrs.get('info', None)
                imported_job.exit_code = job_attrs.get('exit_code', None)
                imported_job.traceback = job_attrs.get('traceback', None)
                imported_job.stdout = job_attrs.get('stdout', None)
                imported_job.stderr = job_attrs.get('stderr', None)
                imported_job.command_line = job_attrs.get('command_line', None)
                try:
                    imported_job.create_time = datetime.datetime.strptime(job_attrs['create_time'], '%Y-%m-%dT%H:%M:%S.%f')
                    imported_job.update_time = datetime.datetime.strptime(job_attrs['update_time'], '%Y-%m-%dT%H:%M:%S.%f')
                except:
                    pass
                self.sa_session.add(imported_job)
                self.sa_session.flush()
                class HistoryDatasetAssociationIDEncoder(json.JSONEncoder, ):
                    '    Custom    JSONEncoder    for    a    HistoryDatasetAssociation    that    encodes    an    HDA    as    its    ID.    '
                    def default(self, obj):
                        '    Encode    an    HDA,    default    encoding    for    everything    else.    '
                        if isinstance(obj, model.HistoryDatasetAssociation):
                            return obj.id
                        return json.JSONEncoder.default(self, obj)
                for (name, value) in job_attrs['params'].items():
                    if isinstance(value, model.HistoryDatasetAssociation):
                        input_hda = self.sa_session.query(model.HistoryDatasetAssociation).filter_by(history=new_history, hid=value.hid).first()
                        value = input_hda.id
                    imported_job.add_parameter(name, dumps(value, cls=HistoryDatasetAssociationIDEncoder))
                for output_hid in job_attrs['output_datasets']:
                    output_hda = self.sa_session.query(model.HistoryDatasetAssociation).filter_by(history=new_history, hid=output_hid).first()
                    if output_hda:
                        imported_job.add_output_dataset(output_hda.name, output_hda)
                if ('input_mapping' in job_attrs):
                    for (input_name, input_hid) in job_attrs['input_mapping'].items():
                        input_hda = self.sa_session.query(model.HistoryDatasetAssociation).filter_by(history=new_history, hid=input_hid).first()
                        if input_hda:
                            imported_job.add_input_dataset(input_name, input_hda)
                self.sa_session.flush()
            new_history.importing = False
            self.sa_session.flush()
            if os.path.exists(archive_dir):
                shutil.rmtree(archive_dir)
        except Exception as e:
            jiha.job.stderr += ('Error    cleaning    up    history    import    job:    %s' % e)
            self.sa_session.flush()
            raise
