예제 #1
0
def migrate_version(idx, node_file, node_settings, node=None, dry_run=True):
    """Migrate a legacy file version to OSF Storage. If `node` is provided, use
    instead of the `Node` attached to `node_settings`; used when the git repo
    for the current node is missing or corrupt.

    :param int idx: Version index (zero-based)
    :param NodeFile node_file: Legacy file record
    :param OsfStorageNodeSettings node_settings: Node settings
    :param Node node: Optional source node
    """
    node = node or node_settings.owner
    logger.info('Migrating version {0} from NodeFile {1} on node {2}'.format(
        idx,
        node_file._id,
        node._id,
    ))
    if not dry_run:
        record = model.OsfStorageFileRecord.get_or_create(
            node_file.path, node_settings)
        if len(record.versions) > idx:
            return
    content = scripts_settings.SPECIAL_CASES.get((node._id, node_file._id))
    if content is None:
        content, _ = node.read_file_object(node_file)
    logger.info('Loaded content with length {0}: {1}...'.format(
        len(content), content[:10]))
    if dry_run:
        return
    md5 = hashlib.md5(content).hexdigest()
    file_pointer = StringIO(content)
    hash_str = scripts_settings.UPLOAD_PRIMARY_HASH(content).hexdigest()
    obj = container.get_or_upload_file(file_pointer, hash_str)
    if obj.size != len(content):
        raise SizeMismatchError
    if obj.md5 != md5:
        raise HashMismatchError
    metadata = {
        'size': obj.size,
        'content_type': obj.content_type,
        'date_modified': obj.date_modified.isoformat(),
        'md5': md5,
    }
    try:
        record.create_pending_version(node_file.uploader,
                                      '{}-{}'.format(hash_str, idx))
    except errors.OsfStorageError:
        latest_version = record.get_version(required=True)
        record.remove_version(latest_version)
        record = OsfStorageFileRecord.get_or_create(node_file.path,
                                                    node_settings)
        record.create_pending_version(node_file.uploader,
                                      '{}-{}'.format(hash_str, idx))
    record.resolve_pending_version(
        '{}-{}'.format(hash_str, idx),
        obj.location,
        metadata,
        log=False,
    )
예제 #2
0
 def test_migrate_incomplete(self):
     node_settings = self.project.get_or_add_addon('osfstorage', auth=None, log=False)
     record = model.OsfStorageFileRecord.get_or_create('pizza.md', node_settings)
     node_file = NodeFile.load(self.project.files_versions['pizza_md'][0])
     content, _ = self.project.read_file_object(node_file)
     file_pointer = StringIO(content)
     hash_str = scripts_settings.UPLOAD_PRIMARY_HASH(content).hexdigest()
     record.create_pending_version(node_file.uploader, hash_str)
     main(dry_run=False)