def check_licenses(node_licenses, allowed_licenses, forbidden_licenses): """Check licenses""" from aiida.common.exceptions import LicensingException from inspect import isfunction for pk, license_ in node_licenses: if allowed_licenses is not None: try: if isfunction(allowed_licenses): try: if not allowed_licenses(license_): raise LicensingException except Exception: raise LicensingException else: if license_ not in allowed_licenses: raise LicensingException except LicensingException: raise LicensingException('Node {} is licensed ' 'under {} license, which ' 'is not in the list of ' 'allowed licenses'.format( pk, license_)) if forbidden_licenses is not None: try: if isfunction(forbidden_licenses): try: if forbidden_licenses(license_): raise LicensingException except Exception: raise LicensingException else: if license_ in forbidden_licenses: raise LicensingException except LicensingException: raise LicensingException('Node {} is licensed ' 'under {} license, which ' 'is in the list of ' 'forbidden licenses'.format( pk, license_))
def _collect_tags( node, calc, parameters=None, dump_aiida_database=default_options['dump_aiida_database'], exclude_external_contents=default_options['exclude_external_contents'], gzip=default_options['gzip'], gzip_threshold=default_options['gzip_threshold']): """ Retrieve metadata from attached calculation and pseudopotentials and prepare it to be saved in TCOD CIF. """ from aiida.common.links import LinkType import os, json import aiida tags = { '_audit_creation_method': "AiiDA version {}".format(aiida.__version__) } # Recording the dictionaries (if any) if len(conforming_dictionaries): for postfix in ['name', 'version', 'location']: key = '_audit_conform_dict_{}'.format(postfix) if key not in tags: tags[key] = [] for dictionary in conforming_dictionaries: tags['_audit_conform_dict_name'].append(dictionary['name']) tags['_audit_conform_dict_version'].append(dictionary['version']) tags['_audit_conform_dict_location'].append(dictionary['url']) # Collecting metadata from input files: calc_data = [] if calc is not None: calc_data = _collect_calculation_data(calc) for tag in tcod_loops['_tcod_computation'] + tcod_loops['_tcod_file']: tags[tag] = [] export_files = [] sn = 1 for step in calc_data: tags['_tcod_computation_step'].append(sn) tags['_tcod_computation_command'].append('cd {}; ./{}'.format( sn, aiida_executable_name)) tags['_tcod_computation_reference_uuid'].append(step['uuid']) if 'env' in step: tags['_tcod_computation_environment'].append("\n".join( ["%s=%s" % (key, step['env'][key]) for key in step['env']])) else: tags['_tcod_computation_environment'].append('') if 'stdout' in step and step['stdout'] is not None: tags['_tcod_computation_stdout'].append(step['stdout']) else: tags['_tcod_computation_stdout'].append('') if 'stderr' in step and step['stderr'] is not None: tags['_tcod_computation_stderr'].append(step['stderr']) else: tags['_tcod_computation_stderr'].append('') export_files.append({ 'name': "{}{}".format(sn, os.sep), 'type': 'folder' }) for f in step['files']: f['name'] = os.path.join(str(sn), f['name']) export_files.extend(step['files']) sn = sn + 1 # Creating importable AiiDA database dump in CIF tags if dump_aiida_database and node.is_stored: import json from aiida.common.exceptions import LicensingException from aiida.common.folders import SandboxFolder from aiida.orm.importexport import export_tree with SandboxFolder() as folder: try: export_tree([node.dbnode], folder=folder, silent=True, allowed_licenses=['CC0']) except LicensingException as e: raise LicensingException(e.message + \ ". Only CC0 license is accepted.") files = _collect_files(folder.abspath) with open(folder.get_abs_path('data.json')) as f: data = json.loads(f.read()) md5_to_url = {} if exclude_external_contents: for pk in data['node_attributes']: n = data['node_attributes'][pk] if 'md5' in n.keys() and 'source' in n.keys() and \ 'uri' in n['source'].keys(): md5_to_url[n['md5']] = n['source']['uri'] for f in files: f['name'] = os.path.join('aiida', f['name']) if f['type'] == 'file' and f['md5'] in md5_to_url.keys(): f['uri'] = md5_to_url[f['md5']] export_files.extend(files) # Describing seen files in _tcod_file_* loop encodings = list() fn = 0 for f in export_files: # ID and name tags['_tcod_file_id'].append(fn) tags['_tcod_file_name'].append(f['name']) # Checksums md5sum = None sha1sum = None if f['type'] == 'file': md5sum = f['md5'] sha1sum = f['sha1'] else: md5sum = '.' sha1sum = '.' tags['_tcod_file_md5sum'].append(md5sum) tags['_tcod_file_sha1sum'].append(sha1sum) # Content, encoding and URI contents = '?' encoding = None if 'uri' in f.keys(): contents = '.' tags['_tcod_file_URI'].append(f['uri']) else: tags['_tcod_file_URI'].append('?') if f['type'] == 'file': contents,encoding = \ cif_encode_contents(f['contents'], gzip=gzip, gzip_threshold=gzip_threshold) else: contents = '.' if encoding is None: encoding = '.' elif encoding not in encodings: encodings.append(encoding) tags['_tcod_file_contents'].append(contents) tags['_tcod_file_content_encoding'].append(encoding) # Role role = '?' if 'role' in f.keys(): role = f['role'] tags['_tcod_file_role'].append(role) fn = fn + 1 # Describing the encodings if encodings: for tag in tcod_loops['_tcod_content_encoding']: tags[tag] = [] for encoding in encodings: layers = encoding.split('+') for i in range(0, len(layers)): tags['_tcod_content_encoding_id'].append(encoding) tags['_tcod_content_encoding_layer_id'].append(i + 1) tags['_tcod_content_encoding_layer_type'].append(layers[i]) # Describing Brillouin zone (if used) if calc is not None: from aiida.orm.data.array.kpoints import KpointsData kpoints_list = calc.get_inputs(KpointsData, link_type=LinkType.INPUT) # TODO: stop if more than one KpointsData is used? if len(kpoints_list) == 1: kpoints = kpoints_list[0] density, shift = kpoints.get_kpoints_mesh() tags['_dft_BZ_integration_grid_X'] = density[0] tags['_dft_BZ_integration_grid_Y'] = density[1] tags['_dft_BZ_integration_grid_Z'] = density[2] tags['_dft_BZ_integration_grid_shift_X'] = shift[0] tags['_dft_BZ_integration_grid_shift_Y'] = shift[1] tags['_dft_BZ_integration_grid_shift_Z'] = shift[2] from aiida.common.exceptions import MultipleObjectsError from aiida.common.pluginloader import all_plugins, get_plugin category = 'tools.dbexporters.tcod_plugins' plugins = list() if calc is not None: for entry_point in all_plugins(category): plugin = get_plugin(category, entry_point) if calc._plugin_type_string.endswith(plugin._plugin_type_string + '.'): plugins.append(plugin) if len(plugins) > 1: raise MultipleObjectsError('more than one plugin found for {}'.format( calc._plugin_type_string)) if len(plugins) == 1: plugin = plugins[0] translated_tags = translate_calculation_specific_values(calc, plugin) tags.update(translated_tags) return tags