예제 #1
0
def create_new_file(obj, source, destination, destination_node):
    # TODO: Remove when materialized paths are fixed in the payload returned from waterbutler
    if not source['materialized'].startswith('/'):
        source['materialized'] = '/' + source['materialized']
    if not destination['materialized'].startswith('/'):
        destination['materialized'] = '/' + destination['materialized']

    if not source['path'].endswith('/'):
        data = dict(destination)
        new_file = FileNode.resolve_class(destination['provider'],
                                          FileNode.FILE).get_or_create(
                                              destination_node,
                                              destination['path'])
        if destination['provider'] != 'osfstorage':
            new_file.update(revision=None, data=data)
    else:
        new_file = find_and_create_file_from_metadata(
            destination.get('children', []), source, destination,
            destination_node, obj)
        if not new_file:
            if source['provider'] == 'box':
                new_path = obj.referent.path
            else:
                new_path = obj.referent.materialized_path.replace(
                    source['materialized'], destination['materialized'])
            new_file = FileNode.resolve_class(destination['provider'],
                                              FileNode.FILE).get_or_create(
                                                  destination_node, new_path)
            new_file.name = new_path.split('/')[-1]
            new_file.materialized_path = new_path
            new_file.save()
    return new_file
예제 #2
0
파일: views.py 프로젝트: lambroisie/osf.io
def addon_delete_file_node(self, node, user, event_type, payload):
    """ Get addon StoredFileNode(s), move it into the TrashedFileNode collection
    and remove it from StoredFileNode.

    Required so that the guids of deleted addon files are not re-pointed when an
    addon file or folder is moved or renamed.
    """
    if event_type == 'file_removed' and payload.get('provider',
                                                    None) != 'osfstorage':
        provider = payload['provider']
        path = payload['metadata']['path']
        materialized_path = payload['metadata']['materialized']
        if path.endswith('/'):
            folder_children = FileNode.resolve_class(
                provider, FileNode.ANY).find(
                    Q('provider', 'eq', provider) & Q('node', 'eq', node)
                    & Q('materialized_path', 'startswith', materialized_path))
            for item in folder_children:
                if item.kind == 'file' and not TrashedFileNode.load(item._id):
                    item.delete(user=user)
                elif item.kind == 'folder':
                    StoredFileNode.remove_one(item.stored_object)
        else:
            try:
                file_node = FileNode.resolve_class(
                    provider, FileNode.FILE).find_one(
                        Q('node', 'eq', node)
                        & Q('materialized_path', 'eq', materialized_path))
            except NoResultsFound:
                file_node = None

            if file_node and not TrashedFileNode.load(file_node._id):
                file_node.delete(user=user)
예제 #3
0
파일: views.py 프로젝트: baylee-d/osf.io
def addon_delete_file_node(self, node, user, event_type, payload):
    """ Get addon StoredFileNode(s), move it into the TrashedFileNode collection
    and remove it from StoredFileNode.

    Required so that the guids of deleted addon files are not re-pointed when an
    addon file or folder is moved or renamed.
    """
    if event_type == 'file_removed' and payload.get('provider', None) != 'osfstorage':
        provider = payload['provider']
        path = payload['metadata']['path']
        materialized_path = payload['metadata']['materialized']
        if path.endswith('/'):
            folder_children = FileNode.resolve_class(provider, FileNode.ANY).find(
                Q('provider', 'eq', provider) &
                Q('node', 'eq', node) &
                Q('materialized_path', 'startswith', materialized_path)
            )
            for item in folder_children:
                if item.kind == 'file' and not TrashedFileNode.load(item._id):
                    item.delete(user=user)
                elif item.kind == 'folder':
                    StoredFileNode.remove_one(item.stored_object)
        else:
            try:
                file_node = FileNode.resolve_class(provider, FileNode.FILE).find_one(
                    Q('node', 'eq', node) &
                    Q('materialized_path', 'eq', materialized_path)
                )
            except NoResultsFound:
                file_node = None

            if file_node and not TrashedFileNode.load(file_node._id):
                file_node.delete(user=user)
예제 #4
0
def get_metadata_files(draft):
    data = draft.registration_metadata
    for q, question in get_file_questions('prereg-prize.json'):
        if not isinstance(data[q]['value'], dict):
            for i, file_info in enumerate(data[q]['extra']):
                provider = file_info['data']['provider']
                if provider != 'osfstorage':
                    raise Http404(
                        'File does not exist in OSFStorage ({}: {})'.format(
                            q, question))
                file_guid = file_info.get('fileId')
                if not file_guid:
                    node = Node.load(file_info.get('nodeId'))
                    path = file_info['data'].get('path')
                    item = FileNode.resolve_class(provider,
                                                  FileNode.FILE).get_or_create(
                                                      node, path)
                    file_guid = item.get_guid(create=True)._id
                    data[q]['extra'][i]['fileId'] = file_guid
                    draft.update_metadata(data)
                    draft.save()
                else:
                    guid = Guid.load(file_guid)
                    item = guid.referent
                if item is None:
                    raise Http404(
                        'File with guid "{}" in "{}" does not exist'.format(
                            file_guid, question))
                yield item
            continue
        for i, file_info in enumerate(data[q]['value']['uploader']['extra']):
            provider = file_info['data']['provider']
            if provider != 'osfstorage':
                raise Http404(
                    'File does not exist in OSFStorage ({}: {})'.format(
                        q, question))
            file_guid = file_info.get('fileId')
            if not file_guid:
                node = Node.load(file_info.get('nodeId'))
                path = file_info['data'].get('path')
                item = FileNode.resolve_class(provider,
                                              FileNode.FILE).get_or_create(
                                                  node, path)
                file_guid = item.get_guid(create=True)._id
                data[q]['value']['uploader']['extra'][i]['fileId'] = file_guid
                draft.update_metadata(data)
                draft.save()
            else:
                guid = Guid.load(file_guid)
                item = guid.referent
            if item is None:
                raise Http404(
                    'File with guid "{}" in "{}" does not exist'.format(
                        file_guid, question))
            yield item
예제 #5
0
    def test_comments_move_when_folder_moved_to_different_provider(self, destination_provider, destination_path):
        if self.provider == destination_provider:
            return True

        self.project.add_addon(destination_provider, auth=Auth(self.user))
        self.project.save()
        self.addon_settings = self.project.get_addon(destination_provider)
        self.addon_settings.folder = '/AddonFolder'
        self.addon_settings.save()

        source = {
            'path': '/subfolder/',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': '/subfolder/',
            'node': self.project,
            'provider': destination_provider,
            'children': [{
                    'path': '/subfolder/file.txt',
                    'node': self.project,
                    'provider': destination_provider
            }]
        }
        file_name = 'file.txt'
        self._create_file_with_comment(node=source['node'], path='{}{}'.format(source['path'], file_name))
        payload = self._create_payload('move', self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(destination_provider, FileNode.FILE).get_or_create(destination['node'], destination_path)
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #6
0
def update_file_guid_referent(self, node, event_type, payload, user=None):
    if event_type == 'addon_file_moved' or event_type == 'addon_file_renamed':
        source = payload['source']
        destination = payload['destination']
        source_node = Node.load(source['node']['_id'])
        destination_node = node
        file_guids = FileNode.resolve_class(source['provider'], FileNode.ANY).get_file_guids(
            materialized_path=source['materialized'] if source['provider'] != 'osfstorage' else source['path'],
            provider=source['provider'],
            node=source_node)

        if event_type == 'addon_file_renamed' and source['provider'] in settings.ADDONS_BASED_ON_IDS:
            return
        if event_type == 'addon_file_moved' and (source['provider'] == destination['provider'] and
                                                 source['provider'] in settings.ADDONS_BASED_ON_IDS) and source_node == destination_node:
            return

        for guid in file_guids:
            obj = Guid.load(guid)
            if source_node != destination_node and Comment.find(Q('root_target', 'eq', guid)).count() != 0:
                update_comment_node(guid, source_node, destination_node)

            if source['provider'] != destination['provider'] or source['provider'] != 'osfstorage':
                old_file = FileNode.load(obj.referent._id)
                obj.referent = create_new_file(obj, source, destination, destination_node)
                obj.save()
                if old_file and not TrashedFileNode.load(old_file._id):
                    old_file.delete()
예제 #7
0
    def test_comments_move_when_folder_moved_to_different_provider(self, destination_provider, destination_path):
        if self.provider == destination_provider:
            return True

        self.project.add_addon(destination_provider, auth=Auth(self.user))
        self.project.save()
        self.addon_settings = self.project.get_addon(destination_provider)
        self.addon_settings.folder = '/AddonFolder'
        self.addon_settings.save()

        source = {
            'path': '/subfolder/',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': '/subfolder/',
            'node': self.project,
            'provider': destination_provider,
            'children': [{
                    'path': '/subfolder/file.txt',
                    'node': self.project,
                    'provider': destination_provider
            }]
        }
        file_name = 'file.txt'
        self._create_file_with_comment(node=source['node'], path='{}{}'.format(source['path'], file_name))
        payload = self._create_payload('move', self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(destination_provider, FileNode.FILE).get_or_create(destination['node'], destination_path)
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #8
0
    def test_comments_move_when_file_moved_to_osfstorage(self):
        osfstorage = self.project.get_addon('osfstorage')
        root_node = osfstorage.get_root()
        osf_file = root_node.append_file('file.txt')
        osf_file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png',
            'etag': 'abcdefghijklmnop'
        }).save()

        source = {
            'path': '/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': osf_file.path,
            'node': self.project,
            'provider': 'osfstorage'
        }
        self._create_file_with_comment(node=source['node'], path=source['path'])
        payload = self._create_payload('move', self.user, source, destination, self.file._id, destination_file_id=destination['path'].strip('/'))
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class('osfstorage', FileNode.FILE).get_or_create(destination['node'], destination['path'])
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #9
0
    def test_comments_move_when_folder_moved_to_different_provider(self, destination_provider, destination_path):
        if self.provider == destination_provider:
            return True

        self.project.add_addon(destination_provider, auth=Auth(self.user))
        self.project.save()
        self.addon_settings = self.project.get_addon(destination_provider)
        self.addon_settings.folder = "/AddonFolder"
        self.addon_settings.save()

        source = {"path": "/subfolder/", "node": self.project, "provider": self.provider}
        destination = {
            "path": "/subfolder/",
            "node": self.project,
            "provider": destination_provider,
            "children": [{"path": "/subfolder/file.txt", "node": self.project, "provider": destination_provider}],
        }
        file_name = "file.txt"
        self._create_file_with_comment(node=source["node"], path="{}{}".format(source["path"], file_name))
        payload = self._create_payload("move", self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination["node"], event_type="addon_file_moved", payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(destination_provider, FileNode.FILE).get_or_create(
            destination["node"], destination_path
        )
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q("root_target", "eq", self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #10
0
    def test_comments_move_when_folder_moved_to_osfstorage(self):
        osfstorage = self.project.get_addon("osfstorage")
        root_node = osfstorage.get_root()
        osf_folder = root_node.append_folder("subfolder")
        osf_file = osf_folder.append_file("file.txt")
        osf_file.create_version(
            self.user,
            {"object": "06d80e", "service": "cloud", osfstorage_settings.WATERBUTLER_RESOURCE: "osf"},
            {"size": 1337, "contentType": "img/png", "etag": "1234567890abcde"},
        ).save()

        source = {"path": "/subfolder/", "node": self.project, "provider": self.provider}
        destination = {
            "path": "/subfolder/",
            "node": self.project,
            "provider": "osfstorage",
            "children": [{"path": "/subfolder/file.txt", "node": self.project, "provider": "osfstorage"}],
        }
        file_name = "file.txt"
        self._create_file_with_comment(node=source["node"], path="{}{}".format(source["path"], file_name))
        payload = self._create_payload(
            "move", self.user, source, destination, self.file._id, destination_file_id=osf_file._id
        )
        update_file_guid_referent(self=None, node=destination["node"], event_type="addon_file_moved", payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class("osfstorage", FileNode.FILE).get_or_create(destination["node"], osf_file._id)
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q("root_target", "eq", self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #11
0
def find_and_create_file_from_metadata(children, source, destination,
                                       destination_node, obj):
    """ Given a Guid obj, recursively search for the metadata of its referent (a file obj)
    in the waterbutler response. If found, create a new addon FileNode with that metadata
    and return the new file.
    """
    for item in children:
        # TODO: Remove when materialized paths are fixed in the payload returned from waterbutler
        if not item['materialized'].startswith('/'):
            item['materialized'] = '/' + item['materialized']

        if item['kind'] == 'folder':
            return find_and_create_file_from_metadata(item.get('children', []),
                                                      source, destination,
                                                      destination_node, obj)
        elif item['kind'] == 'file' and item['materialized'].replace(
                destination['materialized'],
                source['materialized']) == obj.referent.materialized_path:
            data = dict(item)
            new_file = FileNode.resolve_class(destination['provider'],
                                              FileNode.FILE).get_or_create(
                                                  destination_node,
                                                  item['path'])
            if destination['provider'] != 'osfstorage':
                new_file.update(revision=None, data=data)
            return new_file
예제 #12
0
    def test_comments_move_when_file_moved_to_osfstorage(self):
        osfstorage = self.project.get_addon('osfstorage')
        root_node = osfstorage.get_root()
        osf_file = root_node.append_file('file.txt')
        osf_file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png',
            'etag': 'abcdefghijklmnop'
        }).save()

        source = {
            'path': '/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': osf_file.path,
            'node': self.project,
            'provider': 'osfstorage'
        }
        self._create_file_with_comment(node=source['node'], path=source['path'])
        payload = self._create_payload('move', self.user, source, destination, self.file._id, destination_file_id=destination['path'].strip('/'))
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class('osfstorage', FileNode.FILE).get_or_create(destination['node'], destination['path'])
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #13
0
def create_new_file(obj, source, destination, destination_node):
    if not source['path'].endswith('/'):
        data = dict(destination)
        new_file = FileNode.resolve_class(destination['provider'], FileNode.FILE).get_or_create(destination_node, destination['path'])
        if destination['provider'] != 'osfstorage':
            new_file.update(revision=None, data=data)
    else:
        new_file = find_and_create_file_from_metadata(destination.get('children', []), source, destination, destination_node, obj)
        if not new_file:
            if source['provider'] == 'box':
                new_path = obj.referent.path
            else:
                new_path = obj.referent.materialized_path.replace(source['materialized'], destination['materialized'])
            new_file = FileNode.resolve_class(destination['provider'], FileNode.FILE).get_or_create(destination_node, new_path)
            new_file.name = new_path.split('/')[-1]
            new_file.materialized_path = new_path
            new_file.save()
    return new_file
예제 #14
0
    def get_file_item(self, item):
        file_node = FileNode.resolve_class(
            item['provider'],
            FileNode.FOLDER if item['kind'] == 'folder'
            else FileNode.FILE
        ).get_or_create(self.get_node(), item['path'])

        file_node.update(None, item, user=self.request.user)

        return file_node
예제 #15
0
    def get_file_item(self, item):
        file_node = FileNode.resolve_class(
            item['provider'], FileNode.FOLDER
            if item['kind'] == 'folder' else FileNode.FILE).get_or_create(
                self.get_node(check_object_permissions=False), item['path'])

        file_node.update(None, item, user=self.request.user)

        self.check_object_permissions(self.request, file_node)

        return file_node
예제 #16
0
파일: views.py 프로젝트: hmoco/osf.io
    def get_file_item(self, item):
        file_node = FileNode.resolve_class(
            item['provider'],
            FileNode.FOLDER if item['kind'] == 'folder'
            else FileNode.FILE
        ).get_or_create(self.get_node(check_object_permissions=False), item['path'])

        file_node.update(None, item, user=self.request.user)

        self.check_object_permissions(self.request, file_node)

        return file_node
예제 #17
0
def find_and_create_file_from_metadata(children, source, destination, destination_node, obj):
    """ Given a Guid obj, recursively search for the metadata of its referent (a file obj)
    in the waterbutler response. If found, create a new addon FileNode with that metadata
    and return the new file.
    """
    for item in children:
        if item['kind'] == 'folder':
            return find_and_create_file_from_metadata(item.get('children', []), source, destination, destination_node, obj)
        elif item['kind'] == 'file' and item['materialized'].replace(destination['materialized'], source['materialized']) == obj.referent.materialized_path:
            data = dict(item)
            new_file = FileNode.resolve_class(destination['provider'], FileNode.FILE).get_or_create(destination_node, item['path'])
            if destination['provider'] != 'osfstorage':
                new_file.update(revision=None, data=data)
            return new_file
예제 #18
0
    def test_comments_move_when_file_moved_from_subfolder_to_root(self):
        source = {"path": "/subfolder/file.txt", "node": self.project, "provider": self.provider}
        destination = {"path": "/file.txt", "node": self.project, "provider": self.provider}
        self._create_file_with_comment(node=source["node"], path=source["path"])
        payload = self._create_payload("move", self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination["node"], event_type="addon_file_moved", payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(self.provider, FileNode.FILE).get_or_create(
            destination["node"], self._format_path(destination["path"], file_id=self.file._id)
        )
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q("root_target", "eq", self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #19
0
파일: comment.py 프로젝트: mchelen/osf.io
def update_comment_root_target_file(self, node, event_type, payload, user=None):
    if event_type == 'addon_file_moved':
        source = payload['source']
        destination = payload['destination']
        source_node = Node.load(source['node']['_id'])
        destination_node = node

        if (source.get('provider') == destination.get('provider') == 'osfstorage') and source_node._id != destination_node._id:
            old_file = FileNode.load(source.get('path').strip('/'))
            new_file = FileNode.resolve_class(destination.get('provider'), FileNode.FILE).get_or_create(destination_node, destination.get('path'))

            Comment.update(Q('root_target', 'eq', old_file._id), data={'node': destination_node})

            # update node record of commented files
            if old_file._id in source_node.commented_files:
                destination_node.commented_files[new_file._id] = source_node.commented_files[old_file._id]
                del source_node.commented_files[old_file._id]
                source_node.save()
                destination_node.save()
예제 #20
0
    def test_comments_move_when_file_moved_from_subfolder_to_root(self):
        source = {
            'path': '/subfolder/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': '/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        self._create_file_with_comment(node=source['node'], path=source['path'])
        payload = self._create_payload('move', self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(self.provider, FileNode.FILE).get_or_create(destination['node'], self._format_path(destination['path'], file_id=self.file._id))
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #21
0
    def test_comments_move_when_file_moved_from_subfolder_to_root(self):
        source = {
            'path': '/subfolder/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': '/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        self._create_file_with_comment(node=source['node'], path=source['path'])
        payload = self._create_payload('move', self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(self.provider, FileNode.FILE).get_or_create(destination['node'], self._format_path(destination['path'], file_id=self.file._id))
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
예제 #22
0
def update_file_guid_referent(self, node, event_type, payload, user=None):
    if event_type == 'addon_file_moved' or event_type == 'addon_file_renamed':
        source = payload['source']
        destination = payload['destination']
        source_node = Node.load(source['node']['_id'])
        destination_node = node
        file_guids = FileNode.resolve_class(
            source['provider'], FileNode.ANY).get_file_guids(
                materialized_path=source['materialized']
                if source['provider'] != 'osfstorage' else source['path'],
                provider=source['provider'],
                node=source_node)

        if event_type == 'addon_file_renamed' and source[
                'provider'] in settings.ADDONS_BASED_ON_IDS:
            return
        if event_type == 'addon_file_moved' and (
                source['provider'] == destination['provider']
                and source['provider'] in settings.ADDONS_BASED_ON_IDS
        ) and source_node == destination_node:
            return

        for guid in file_guids:
            obj = Guid.load(guid)
            if source_node != destination_node and Comment.find(
                    Q('root_target', 'eq', guid)).count() != 0:
                update_comment_node(guid, source_node, destination_node)

            if source['provider'] != destination['provider'] or source[
                    'provider'] != 'osfstorage':
                old_file = FileNode.load(obj.referent._id)
                obj.referent = create_new_file(obj, source, destination,
                                               destination_node)
                obj.save()
                if old_file and not TrashedFileNode.load(old_file._id):
                    old_file.delete()
예제 #23
0
def get_metadata_files(draft):
    data = draft.registration_metadata
    for q, question in get_file_questions('prereg-prize.json'):
        if not isinstance(data[q]['value'], dict):
            for i, file_info in enumerate(data[q]['extra']):
                provider = file_info['data']['provider']
                if provider != 'osfstorage':
                    raise Http404(
                        'File does not exist in OSFStorage ({}: {})'.format(
                            q, question
                        ))
                file_guid = file_info.get('fileId')
                if file_guid is None:
                    node = Node.load(file_info.get('nodeId'))
                    path = file_info['data'].get('path')
                    item = FileNode.resolve_class(
                        provider,
                        FileNode.FILE
                    ).get_or_create(node, path)
                    file_guid = item.get_guid(create=True)._id
                    data[q]['extra'][i]['fileId'] = file_guid
                    draft.update_metadata(data)
                    draft.save()
                else:
                    guid = Guid.load(file_guid)
                    item = guid.referent
                if item is None:
                    raise Http404(
                        'File with guid "{}" in "{}" does not exist'.format(
                            file_guid, question
                        ))
                yield item
            continue
        for i, file_info in enumerate(data[q]['value']['uploader']['extra']):
            provider = file_info['data']['provider']
            if provider != 'osfstorage':
                raise Http404(
                    'File does not exist in OSFStorage ({}: {})'.format(
                        q, question
                    ))
            file_guid = file_info.get('fileId')
            if file_guid is None:
                node = Node.load(file_info.get('nodeId'))
                path = file_info['data'].get('path')
                item = FileNode.resolve_class(
                    provider,
                    FileNode.FILE
                ).get_or_create(node, path)
                file_guid = item.get_guid(create=True)._id
                data[q]['value']['uploader']['extra'][i]['fileId'] = file_guid
                draft.update_metadata(data)
                draft.save()
            else:
                guid = Guid.load(file_guid)
                item = guid.referent
            if item is None:
                raise Http404(
                    'File with guid "{}" in "{}" does not exist'.format(
                        file_guid, question
                    ))
            yield item
예제 #24
0
파일: views.py 프로젝트: kms6bn/osf.io
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    node = kwargs.get('node') or kwargs['project']

    node_addon = node.get_addon(provider)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if not isinstance(node_addon, StorageAddonBase):
        raise HTTPError(httplib.BAD_REQUEST, {
            'message_short': 'Bad Request',
            'message_long': 'The add-on containing this file is no longer connected to the {}.'.format(node.project_or_component)
        })

    if not node_addon.has_auth:
        raise HTTPError(httplib.UNAUTHORIZED, {
            'message_short': 'Unauthorized',
            'message_long': 'The add-on containing this file is no longer authorized.'
        })

    if not node_addon.complete:
        raise HTTPError(httplib.BAD_REQUEST, {
            'message_short': 'Bad Request',
            'message_long': 'The add-on containing this file is no longer configured.'
        })

    file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create(node, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(
            extras,
            cookie=request.cookies.get(settings.COOKIE_NAME)
        )
    )

    if version is None:
        if file_node.get_guid():
            # If this file has been successfully view before but no longer exists
            # Show a nice error message
            return addon_deleted_file(file_node=file_node, **kwargs)

        raise HTTPError(httplib.NOT_FOUND, {
            'message_short': 'Not Found',
            'message_long': 'This file does not exist'
        })

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', 200, {
            'Location': file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier))
        }))

    if action == 'download':
        return redirect(file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier)))

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(furl.furl('/{}/'.format(guid._id)).set(args=extras).url)

    return addon_view_file(auth, node, file_node, version)
예제 #25
0
파일: views.py 프로젝트: baylee-d/osf.io
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    node = kwargs.get('node') or kwargs['project']

    node_addon = node.get_addon(provider)

    provider_safe = markupsafe.escape(provider)
    path_safe = markupsafe.escape(path)
    project_safe = markupsafe.escape(node.project_or_component)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if not isinstance(node_addon, StorageAddonBase):
        raise HTTPError(httplib.BAD_REQUEST, data={
            'message_short': 'Bad Request',
            'message_long': 'The {} add-on containing {} is no longer connected to {}.'.format(provider_safe, path_safe, project_safe)
        })

    if not node_addon.has_auth:
        raise HTTPError(httplib.UNAUTHORIZED, data={
            'message_short': 'Unauthorized',
            'message_long': 'The {} add-on containing {} is no longer authorized.'.format(provider_safe, path_safe)
        })

    if not node_addon.complete:
        raise HTTPError(httplib.BAD_REQUEST, data={
            'message_short': 'Bad Request',
            'message_long': 'The {} add-on containing {} is no longer configured.'.format(provider_safe, path_safe)
        })

    file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create(node, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(
            extras,
            cookie=request.cookies.get(settings.COOKIE_NAME)
        )
    )

    if version is None:
        return addon_deleted_file(file_node=file_node, path=path, **kwargs)

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', 200, {
            'Location': file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier))
        }))

    if action == 'download':
        return redirect(file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier)))

    if action == 'get_guid':
        draft_id = extras.get('draft')
        draft = DraftRegistration.load(draft_id)
        if draft is None or draft.is_approved:
            raise HTTPError(httplib.BAD_REQUEST, data={
                'message_short': 'Bad Request',
                'message_long': 'File not associated with required object.'
            })
        guid = file_node.get_guid(create=True)
        guid.referent.save()
        return dict(guid=guid._id)

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(furl.furl('/{}/'.format(guid._id)).set(args=extras).url)
    return addon_view_file(auth, node, file_node, version)
예제 #26
0
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    node = kwargs.get('node') or kwargs['project']

    node_addon = node.get_addon(provider)

    provider_safe = markupsafe.escape(provider)
    path_safe = markupsafe.escape(path)
    project_safe = markupsafe.escape(node.project_or_component)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if not isinstance(node_addon, StorageAddonBase):
        raise HTTPError(
            httplib.BAD_REQUEST,
            data={
                'message_short':
                'Bad Request',
                'message_long':
                'The {} add-on containing {} is no longer connected to {}.'.
                format(provider_safe, path_safe, project_safe)
            })

    if not node_addon.has_auth:
        raise HTTPError(
            httplib.UNAUTHORIZED,
            data={
                'message_short':
                'Unauthorized',
                'message_long':
                'The {} add-on containing {} is no longer authorized.'.format(
                    provider_safe, path_safe)
            })

    if not node_addon.complete:
        raise HTTPError(
            httplib.BAD_REQUEST,
            data={
                'message_short':
                'Bad Request',
                'message_long':
                'The {} add-on containing {} is no longer configured.'.format(
                    provider_safe, path_safe)
            })

    file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create(
        node, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(extras, cookie=request.cookies.get(settings.COOKIE_NAME)))

    if version is None:
        return addon_deleted_file(file_node=file_node, path=path, **kwargs)

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', 200, {
            'Location':
            file_node.generate_waterbutler_url(
                **dict(extras, direct=None, version=version.identifier))
        }))

    if action == 'download':
        return redirect(
            file_node.generate_waterbutler_url(
                **dict(extras, direct=None, version=version.identifier)))

    if action == 'get_guid':
        draft_id = extras.get('draft')
        draft = DraftRegistration.load(draft_id)
        if draft is None or draft.is_approved:
            raise HTTPError(httplib.BAD_REQUEST,
                            data={
                                'message_short':
                                'Bad Request',
                                'message_long':
                                'File not associated with required object.'
                            })
        guid = file_node.get_guid(create=True)
        guid.referent.save()
        return dict(guid=guid._id)

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(
            furl.furl('/{}/'.format(guid._id)).set(args=extras).url)
    return addon_view_file(auth, node, file_node, version)
예제 #27
0
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    node = kwargs.get('node') or kwargs['project']

    node_addon = node.get_addon(provider)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if not isinstance(node_addon, StorageAddonBase):
        raise HTTPError(
            httplib.BAD_REQUEST, {
                'message_short':
                'Bad Request',
                'message_long':
                'The add-on containing this file is no longer connected to the {}.'
                .format(node.project_or_component)
            })

    if not node_addon.has_auth:
        raise HTTPError(
            httplib.UNAUTHORIZED, {
                'message_short':
                'Unauthorized',
                'message_long':
                'The add-on containing this file is no longer authorized.'
            })

    if not node_addon.complete:
        raise HTTPError(
            httplib.BAD_REQUEST, {
                'message_short':
                'Bad Request',
                'message_long':
                'The add-on containing this file is no longer configured.'
            })

    file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create(
        node, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(extras, cookie=request.cookies.get(settings.COOKIE_NAME)))

    if version is None:
        if file_node.get_guid():
            # If this file has been successfully view before but no longer exists
            # Show a nice error message
            return addon_deleted_file(file_node=file_node, **kwargs)

        raise HTTPError(
            httplib.NOT_FOUND, {
                'message_short': 'Not Found',
                'message_long': 'This file does not exist'
            })

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', 200, {
            'Location':
            file_node.generate_waterbutler_url(
                **dict(extras, direct=None, version=version.identifier))
        }))

    if action == 'download':
        return redirect(
            file_node.generate_waterbutler_url(
                **dict(extras, direct=None, version=version.identifier)))

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(
            furl.furl('/{}/'.format(guid._id)).set(args=extras).url)

    return addon_view_file(auth, node, file_node, version)