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, )
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)