Exemplo n.º 1
0
def migrate(file_input, file_output, force, silent, archive_format):
    """
    An entry point to migrate existing AiiDA export archives between version numbers
    """
    import os, json, sys
    import tarfile, zipfile
    from aiida.common.folders import SandboxFolder
    from aiida.common.archive import extract_zip, extract_tar

    if os.path.exists(file_output) and not force:
        print >> sys.stderr, 'Error: the output file already exists'
        sys.exit(2)

    with SandboxFolder(sandbox_in_repo=False) as folder:

        if zipfile.is_zipfile(file_input):
            extract_zip(file_input, folder, silent=silent)
        elif tarfile.is_tarfile(file_input):
            extract_tar(file_input, folder, silent=silent)
        else:
            print >> sys.stderr, 'Error: invalid file format, expected either a zip archive or gzipped tarball'
            sys.exit(2)

        try:
            with open(folder.get_abs_path('data.json')) as f:
                data = json.load(f)
            with open(folder.get_abs_path('metadata.json')) as f:
                metadata = json.load(f)
        except IOError as e:
            raise ValueError(
                'export archive does not contain the required file {}'.format(
                    e.filename))

        old_version = verify_metadata_version(metadata)

        try:
            if old_version == '0.1':
                migrate_v1_to_v2(metadata, data)
            elif old_version == '0.2':
                try:
                    migrate_v2_to_v3(metadata, data)
                except DanglingLinkError as e:
                    print "An exception occured!"
                    print e
                    raise RuntimeError(
                        "You're export file is broken because it contains dangling links"
                    )
            else:
                raise ValueError(
                    'cannot migrate from version {}'.format(old_version))
        except ValueError as exception:
            print >> sys.stderr, 'Error:', exception
            sys.exit(2)

        new_version = verify_metadata_version(metadata)

        with open(folder.get_abs_path('data.json'), 'w') as f:
            json.dump(data, f)

        with open(folder.get_abs_path('metadata.json'), 'w') as f:
            json.dump(metadata, f)

        if archive_format == 'zip' or archive_format == 'zip-uncompressed':
            compression = zipfile.ZIP_DEFLATED if archive_format == 'zip' else zipfile.ZIP_STORED
            with zipfile.ZipFile(file_output,
                                 mode='w',
                                 compression=compression,
                                 allowZip64=True) as archive:
                src = folder.abspath
                for dirpath, dirnames, filenames in os.walk(src):
                    relpath = os.path.relpath(dirpath, src)
                    for fn in dirnames + filenames:
                        real_src = os.path.join(dirpath, fn)
                        real_dest = os.path.join(relpath, fn)
                        archive.write(real_src, real_dest)
        elif archive_format == 'tar.gz':
            with tarfile.open(file_output,
                              'w:gz',
                              format=tarfile.PAX_FORMAT,
                              dereference=True) as archive:
                archive.add(folder.abspath, arcname='')

        if not silent:
            print 'Successfully migrated the archive from version {} to {}'.format(
                old_version, new_version)
Exemplo n.º 2
0
def migrate(input_file, output_file, force, silent, archive_format):
    # pylint: disable=too-many-locals,too-many-statements,too-many-branches
    """
    Migrate an existing export archive file to the most recent version of the export format
    """
    import os
    import json
    import tarfile
    import zipfile
    from aiida.common.folders import SandboxFolder
    from aiida.common.archive import extract_zip, extract_tar

    if os.path.exists(output_file) and not force:
        echo.echo_critical('the output file already exists')

    with SandboxFolder(sandbox_in_repo=False) as folder:

        if zipfile.is_zipfile(input_file):
            extract_zip(input_file, folder, silent=silent)
        elif tarfile.is_tarfile(input_file):
            extract_tar(input_file, folder, silent=silent)
        else:
            echo.echo_critical('invalid file format, expected either a zip archive or gzipped tarball')

        try:
            with open(folder.get_abs_path('data.json')) as handle:
                data = json.load(handle)
            with open(folder.get_abs_path('metadata.json')) as handle:
                metadata = json.load(handle)
        except IOError:
            echo.echo_critical('export archive does not contain the required file {}'.format(handle.filename))

        old_version = verify_metadata_version(metadata)

        try:
            if old_version == '0.1':
                migrate_v1_to_v2(metadata, data)
            elif old_version == '0.2':
                try:
                    migrate_v2_to_v3(metadata, data)
                except DanglingLinkError:
                    echo.echo_critical('export file is invalid because it contains dangling links')
            else:
                echo.echo_critical('cannot migrate from version {}'.format(old_version))
        except ValueError as exception:
            echo.echo_critical(exception)

        new_version = verify_metadata_version(metadata)

        with open(folder.get_abs_path('data.json'), 'w') as handle:
            json.dump(data, handle)

        with open(folder.get_abs_path('metadata.json'), 'w') as handle:
            json.dump(metadata, handle)

        if archive_format == 'zip' or archive_format == 'zip-uncompressed':
            compression = zipfile.ZIP_DEFLATED if archive_format == 'zip' else zipfile.ZIP_STORED
            with zipfile.ZipFile(output_file, mode='w', compression=compression, allowZip64=True) as archive:
                src = folder.abspath
                for dirpath, dirnames, filenames in os.walk(src):
                    relpath = os.path.relpath(dirpath, src)
                    for filename in dirnames + filenames:
                        real_src = os.path.join(dirpath, filename)
                        real_dest = os.path.join(relpath, filename)
                        archive.write(real_src, real_dest)
        elif archive_format == 'tar.gz':
            with tarfile.open(output_file, 'w:gz', format=tarfile.PAX_FORMAT, dereference=True) as archive:
                archive.add(folder.abspath, arcname='')

        if not silent:
            echo.echo_success('migrated the archive from version {} to {}'.format(old_version, new_version))