Example #1
0
    def to_file_dict(self):
        """Returns a dictionary correctly formatted
            as a data api response.

        This method first constructs a dictionary that looks like
        a response from an agave call to `files.listing`. After this
        it instantiates a :class:`~designsafe.apps.api.agave.files.AgaveFile` object
        and returns the result of :meth:`~designsafe.apps.api.agave.files.AgaveFile.to_dict`.
        We hand off the dict construction to the 
        :class:`~designsafe.apps.api.agave.files.AgaveFile` class so we don't have to
        implement it twice.

        :param string pems_user: User to filter permissions for

        :returns: dict object representation of a file
        :rtype: dict

        .. note:: in future releases the ES documents in the index should look like
            the response of an agave call to `files.listing`. We would need to keep
            this method to hand of the dict construction to the
            :class:`~designsafe.apps.api.agave.files.AgaveFile` class
        """
        try:
            lm = dateutil.parser.parse(self.lastModified)
        except AttributeError:
            lm = datetime.datetime.now()

        pems = self.to_dict()['permissions']

        wrap = {
            'format': getattr(self, 'format', 'folder'),
            'lastModified': lm,
            'length': self.length,
            'mimeType': self.mimeType,
            'name': self.name,
            'path': os.path.join(self.path, self.name).strip('/'),
            'permissions': pems,
            'system': self.systemId,
            'type': self.type,
            '_pems': pems
        }
        f = AgaveFile(wrap = wrap)
        extra = {
            'meta':
            {
                'keywords': self.to_dict().get('keywords', list([])), 
                'systemTags': self.to_dict().get('systemTags', list([]))
            }
        }
        return f.to_dict(extra = extra)
Example #2
0
    def to_file_dict(self):
        """Returns a dictionary correctly formatted
            as a data api response.

        This method first constructs a dictionary that looks like
        a response from an agave call to `files.listing`. After this
        it instantiates a :class:`~designsafe.apps.api.agave.files.AgaveFile` object
        and returns the result of :meth:`~designsafe.apps.api.agave.files.AgaveFile.to_dict`.
        We hand off the dict construction to the
        :class:`~designsafe.apps.api.agave.files.AgaveFile` class so we don't have to
        implement it twice.

        :param string pems_user: User to filter permissions for

        :returns: dict object representation of a file
        :rtype: dict

        .. note:: in future releases the ES documents in the index should look like
            the response of an agave call to `files.listing`. We would need to keep
            this method to hand of the dict construction to the
            :class:`~designsafe.apps.api.agave.files.AgaveFile` class
        """
        try:
            lm = dateutil.parser.parse(self.lastModified)
        except AttributeError:
            lm = datetime.datetime.now()

        pems = self.to_dict()['permissions']

        wrap = {
            'format': getattr(self, 'format', 'folder'),
            'lastModified': lm,
            'length': self.length,
            'mimeType': self.mimeType,
            'name': self.name,
            'path': os.path.join(self.path, self.name).strip('/'),
            'permissions': pems,
            'system': self.systemId,
            'type': self.type,
            '_pems': pems
        }
        f = AgaveFile(wrap=wrap)
        extra = {
            'meta': {
                'keywords': self.to_dict().get('keywords', list([])),
                'systemTags': self.to_dict().get('systemTags', list([]))
            }
        }
        return f.to_dict(extra=extra)
    def preview(self, file_id, **kwargs):
        system, file_path = self.parse_file_id(file_id)

        f = AgaveFile.from_file_path(system, None, file_path, agave_client=self.agave_client, source="public")

        if f.previewable:
            fmt = kwargs.get("format", "json")
            if fmt == "html":
                context = {}
                ext = f.ext.lower()
                if ext in AgaveFile.SUPPORTED_IMAGE_PREVIEW_EXTS:
                    postit = f.create_postit(force=False, lifetime=360)
                    context["image_preview"] = postit["_links"]["self"]["href"]
                elif ext in AgaveFile.SUPPORTED_TEXT_PREVIEW_EXTS:
                    content = f.download()
                    context["text_preview"] = content
                elif ext in AgaveFile.SUPPORTED_OBJECT_PREVIEW_EXTS:
                    postit = f.create_postit(force=False)
                    context["object_preview"] = postit["_links"]["self"]["href"]
                return "designsafe/apps/api/data/agave/preview.html", context
            else:
                preview_url = (
                    reverse("designsafe_api:file", args=[self.resource, file_id]) + "?action=preview&format=html"
                )
                return {"href": preview_url}
        else:
            return None
    def test_file__init__(self):
        ac = mock.Mock(spec=Agave)
        af = AgaveFile(wrap=self.afile_json, agave_client=ac)

        self.assertEqual(af.agave_client, ac)
        self.assertDictEqual(af._wrap, self.afile_json)
        self.assertFalse(af._permissions)
    def preview(self, file_id, **kwargs):
        system, file_path = self.parse_file_id(file_id)

        f = AgaveFile.from_file_path(system,
                                     None,
                                     file_path,
                                     agave_client=self.agave_client,
                                     source='public')

        if f.previewable:
            fmt = kwargs.get('format', 'json')
            if fmt == 'html':
                context = {}
                ext = f.ext.lower()
                if ext in AgaveFile.SUPPORTED_IMAGE_PREVIEW_EXTS:
                    postit = f.create_postit(force=False, lifetime=360)
                    context['image_preview'] = postit['_links']['self']['href']
                elif ext in AgaveFile.SUPPORTED_TEXT_PREVIEW_EXTS:
                    content = f.download()
                    context['text_preview'] = content
                elif ext in AgaveFile.SUPPORTED_OBJECT_PREVIEW_EXTS:
                    postit = f.create_postit(force=False)
                    context['object_preview'] = postit['_links']['self'][
                        'href']
                return 'designsafe/apps/api/data/agave/preview.html', context
            else:
                preview_url = reverse('designsafe_api:file',
                                      args=[self.resource, file_id
                                            ]) + '?action=preview&format=html'
                return {'href': preview_url}
        else:
            return None
    def _agave_listing(self, system, file_path, **kwargs):
        """Returns a "listing" dict constructed with the response from Agave.

        :param str sytem: System id
        :param str file_path: Path to list

        :returns: A dict with information of the listed file and, when possible, 
        a list of :class:`~designsafe.apps.api.data.agave.files.AgaveFile` objects
        dict in the key ``children``
        :rtype: dict

        Notes:
        -----

            This should not be called directly. See py:meth:`listing(file_id)`
            for more information.
        """
        listing = AgaveFile.listing(system, file_path, self.agave_client, source="public", **kwargs)

        root_file = filter(lambda x: x.full_path == file_path, listing)

        default_pems = [
            {
                "username": self.username,
                "permission": {"read": True, "write": False, "execute": True},
                "recursive": True,
            }
        ]

        list_data = root_file[0].to_dict(default_pems=default_pems)
        list_data["children"] = [o.to_dict(default_pems=default_pems) for o in listing if o.full_path != file_path]

        return list_data
    def test_folder__init__(self):
        ac = mock.Mock(spec=Agave)
        af = AgaveFile(wrap=self.afile_json, agave_client=ac)

        self.assertEqual(af.agave_client, ac)
        self.assertDictEqual(af._wrap, self.afile_json)
        self.assertEqual(af.name, af.path.split('/')[-1])
        self.assertFalse(af._permissions)
    def test_folder__init__with_pems(self):
        ac = mock.Mock(spec=Agave)
        self.afile_json['permissions'] = self.apems_json
        af = AgaveFile(wrap=self.afile_json, agave_client=ac)

        self.assertEqual(af.agave_client, ac)
        self.assertDictEqual(af._wrap, self.afile_json)
        self.assertEqual(af.name, af.path.split('/')[-1])
        for i, pem in enumerate(af.permissions):
            self.assertDictEqual(pem, self.apems_json[i])
Example #9
0
    def test_from_file_path(self):
        ac = mock.Mock(autospec = Agave)
        ac.files.list.return_value = [self.afile_json]
        
        file_path = '%s/%s' % (self.user.username, self.afile_json['path'])
        af = AgaveFile.from_file_path(settings.AGAVE_STORAGE_SYSTEM,
                self.user.username, file_path, agave_client = ac)

        ac.files.list.assert_called_with(systemId= settings.AGAVE_STORAGE_SYSTEM, filePath = file_path)
        self.assertEqual(af.full_path, self.afile_json['path'])
Example #10
0
    def test_mkdir(self, mock_from_file_path):
        ac = mock.Mock(autospec = Agave)
        ac.files.manage.return_value = self.afile_json
        
        tail, head = os.path.split(self.afile_json['path'])
        file_path = self.afile_json['path']
        af = AgaveFile.mkdir(settings.AGAVE_STORAGE_SYSTEM,
                self.user.username, tail, head, agave_client = ac)

        body = '{{"action": "mkdir", "path": "{}"}}'.format(head)
        ac.files.manage.assert_called_with(systemId= settings.AGAVE_STORAGE_SYSTEM, filePath = tail, body = body)
        mock_from_file_path.assert_called_with(settings.AGAVE_STORAGE_SYSTEM, self.user.username, file_path, ac)
Example #11
0
    def test_from_file_path(self):
        ac = mock.Mock(autospec=Agave)
        ac.files.list.return_value = [self.afile_json]

        file_path = '%s/%s' % (self.user.username, self.afile_json['path'])
        af = AgaveFile.from_file_path(settings.AGAVE_STORAGE_SYSTEM,
                                      self.user.username,
                                      file_path,
                                      agave_client=ac)

        ac.files.list.assert_called_with(
            systemId=settings.AGAVE_STORAGE_SYSTEM, filePath=file_path)
        self.assertEqual(af.full_path, self.afile_json['path'])
Example #12
0
    def test_listing(self):
        with open('designsafe/apps/api/fixtures/agave_home_listing.json') as f:
            listing_json = json.load(f)
        ac = mock.Mock(autospec = Agave)
        ac.files.list.return_value = listing_json
        file_path = '%s/%s' % (self.user.username, self.afile_json['path'])

        listing = AgaveFile.listing(settings.AGAVE_STORAGE_SYSTEM,
                                    file_path, agave_client = ac)

        ac.files.list.assert_called_with(systemId = settings.AGAVE_STORAGE_SYSTEM, filePath = file_path, limit = 100, offset = 0)
        for i, af in enumerate(listing):
            self.assertEqual(af.full_path, listing_json[i]['path'])
Example #13
0
    def test_mkdir(self, mock_from_file_path):
        ac = mock.Mock(autospec=Agave)
        ac.files.manage.return_value = self.afile_json

        tail, head = os.path.split(self.afile_json['path'])
        file_path = self.afile_json['path']
        af = AgaveFile.mkdir(settings.AGAVE_STORAGE_SYSTEM,
                             self.user.username,
                             tail,
                             head,
                             agave_client=ac)

        body = '{{"action": "mkdir", "path": "{}"}}'.format(head)
        ac.files.manage.assert_called_with(
            systemId=settings.AGAVE_STORAGE_SYSTEM, filePath=tail, body=body)
        mock_from_file_path.assert_called_with(settings.AGAVE_STORAGE_SYSTEM,
                                               self.user.username, file_path,
                                               ac)
Example #14
0
    def test_listing(self):
        with open('designsafe/apps/api/fixtures/agave_home_listing.json') as f:
            listing_json = json.load(f)
        ac = mock.Mock(autospec=Agave)
        ac.files.list.return_value = listing_json
        file_path = '%s/%s' % (self.user.username, self.afile_json['path'])

        listing = AgaveFile.listing(settings.AGAVE_STORAGE_SYSTEM,
                                    file_path,
                                    agave_client=ac)

        ac.files.list.assert_called_with(
            systemId=settings.AGAVE_STORAGE_SYSTEM,
            filePath=file_path,
            limit=100,
            offset=0)
        for i, af in enumerate(listing):
            self.assertEqual(af.full_path, listing_json[i]['path'])
    def download(self, file_id, **kwargs):
        """Get the download link for a file

        :param str file_id: String with the format
        <filesystem id>[/ | /<username> [/ | /<file_path>] ]

        :returns: a dict with a single key `href` which has the direct
            noauth link to download a file
        :rtype: dict

        """
        system, file_path = self.parse_file_id(file_id)

        f = AgaveFile.from_file_path(system, None, file_path, agave_client=self.agave_client, source="public")
        if f.type == "file":
            postit = f.create_postit(force=True, max_uses=10, lifetime=3600)
            return {"href": postit["_links"]["self"]["href"]}
        else:
            return None
    def _agave_listing(self, system, file_path, **kwargs):
        """Returns a "listing" dict constructed with the response from Agave.

        :param str sytem: System id
        :param str file_path: Path to list

        :returns: A dict with information of the listed file and, when possible,
        a list of :class:`~designsafe.apps.api.data.agave.files.AgaveFile` objects
        dict in the key ``children``
        :rtype: dict

        Notes:
        -----

            This should not be called directly. See py:meth:`listing(file_id)`
            for more information.
        """
        listing = AgaveFile.listing(system,
                                    file_path,
                                    self.agave_client,
                                    source='public',
                                    **kwargs)

        root_file = filter(lambda x: x.full_path == file_path, listing)

        default_pems = [{
            'username': self.username,
            'permission': {
                'read': True,
                'write': False,
                'execute': True
            },
            'recursive': True
        }]

        list_data = root_file[0].to_dict(default_pems=default_pems)
        list_data['children'] = [
            o.to_dict(default_pems=default_pems) for o in listing
            if o.full_path != file_path
        ]

        return list_data
    def download(self, file_id, **kwargs):
        """Get the download link for a file

        :param str file_id: String with the format
        <filesystem id>[/ | /<username> [/ | /<file_path>] ]

        :returns: a dict with a single key `href` which has the direct
            noauth link to download a file
        :rtype: dict

        """
        system, file_path = self.parse_file_id(file_id)

        f = AgaveFile.from_file_path(system,
                                     None,
                                     file_path,
                                     agave_client=self.agave_client,
                                     source='public')
        if f.type == 'file':
            postit = f.create_postit(force=True, max_uses=10, lifetime=3600)
            return {'href': postit['_links']['self']['href']}
        else:
            return None
Example #18
0
 def get_mock_agave_file(self):
     ac = mock.Mock()
     wrap = self.afile_json.copy()
     wrap['lastModified'] = dateutil.parser.parse(wrap['lastModified'])
     af = AgaveFile(wrap = wrap, agave_client = ac)
     return af
Example #19
0
def share_agave(self, username, file_id, permissions, recursive):
    try:
        n = Notification(event_type = 'data',
                         status = 'INFO',
                         operation = 'share_initializing',
                         message = 'File sharing is initializing. Please wait...',
                         user = username,
                         extra = {'target_path': reverse('designsafe_data:data_browser',
                                                         args=['agave', file_id])})
        n.save()
        user = get_user_model().objects.get(username=username)

        from designsafe.apps.api.data import AgaveFileManager
        from designsafe.apps.api.data.agave.file import AgaveFile
        from designsafe.apps.api.data.agave.elasticsearch.documents import Object
        agave_fm = AgaveFileManager(user)
        system_id, file_user, file_path = agave_fm.parse_file_id(file_id)

        f = AgaveFile.from_file_path(system_id, username, file_path,
                                     agave_client=agave_fm.agave_client)
        f.share(permissions, recursive)
        #reindex_agave.apply_async(args=(self.username, file_id))
        # self.indexer.index(system, file_path, file_user, pems_indexing=True)
        
        esf = Object.from_file_path(system_id, username, file_path)
        esf.share(username, permissions, recursive)

        # Notify owner share completed
        n = Notification(event_type = 'data',
                         status = 'SUCCESS',
                         operation = 'share_finished',
                         message = 'File permissions were updated successfully.',
                         user = username,
                         extra = {'target_path': reverse('designsafe_data:data_browser',
                                                         args=['agave', file_id])})
        n.save()

        # Notify users they have new shared files
        for pem in permissions:
            if pem['permission'] != 'NONE':
                message = '%s shared some files with you.' % user.get_full_name()
                n = Notification(event_type = 'data',
                                 status = 'SUCCESS',
                                 operation = 'share_finished',
                                 message = message,
                                 user = pem['user_to_share'],
                                 extra = {'target_path': reverse('designsafe_data:data_browser',
                                                                 args=['agave', file_id])})
                n.save()

    except:
        logger.error('Error sharing file/folder', exc_info=True,
                     extra = {
                         'username': username,
                         'file_id': file_id,
                         'permissions': permissions
                     })
        n = Notification(event_type='data',
                         status=Notification.ERROR,
                         operation='share_error',
                         message='We were unable to share the specified folder/file(s). '
                                 'Please try again...',
                         user=username,
                         extra={})
        n.save()
Example #20
0
def share_agave(self, username, file_id, permissions, recursive):
    try:
        # n = Notification(event_type = 'data',
        #                  status = 'INFO',
        #                  operation = 'share_initializing',
        #                  message = 'File sharing is initializing. Please wait...',
        #                  user = username,
        #                  extra = {'target_path': reverse('designsafe_data:data_depot',
        #                                                  args=['agave', file_id])})
        # n.save()
        user = get_user_model().objects.get(username=username)

        from designsafe.apps.api.data import AgaveFileManager
        from designsafe.apps.api.data.agave.file import AgaveFile
        from designsafe.apps.api.data.agave.elasticsearch.documents import Object
        agave_fm = AgaveFileManager(user)
        system_id, file_user, file_path = agave_fm.parse_file_id(file_id)

        f = AgaveFile.from_file_path(system_id, username, file_path,
                                     agave_client=agave_fm.agave_client)
        f_dict = f.to_dict()

        n = Notification(event_type = 'data',
                         status = 'INFO',
                         operation = 'share_initializing',
                         message = 'File sharing is initializing. Please wait...',
                         user = username,
                         extra = f_dict)
        n.save()

        f.share(permissions, recursive)
        #reindex_agave.apply_async(args=(self.username, file_id))
        # self.indexer.index(system, file_path, file_user, pems_indexing=True)

        esf = Object.from_file_path(system_id, username, file_path)
        esf.share(username, permissions, recursive)

        # Notify owner share completed
        n = Notification(event_type = 'data',
                         status = 'SUCCESS',
                         operation = 'share_finished',
                         message = 'File permissions were updated successfully.',
                         user = username,
                         extra = f_dict)
        n.save()

        # Notify users they have new shared files
        for pem in permissions:
            if pem['permission'] != 'NONE':
                message = '%s shared some files with you.' % user.get_full_name()
                n = Notification(event_type = 'data',
                                 status = 'SUCCESS',
                                 operation = 'share_finished',
                                 message = message,
                                 user = pem['user_to_share'],
                                 extra = f_dict)
                n.save()

    except:
        logger.error('Error sharing file/folder', exc_info=True,
                     extra = {
                         'username': username,
                         'file_id': file_id,
                         'permissions': permissions
                     })
        n = Notification(event_type='data',
                         status=Notification.ERROR,
                         operation='share_error',
                         message='We were unable to share the specified folder/file(s). '
                                 'Please try again...',
                         user=username,
                         extra={'system': system_id,
                                'path': file_path
                         })
        n.save()
Example #21
0
 def get_mock_file(self):
     ac = mock.Mock()
     af = AgaveFile(wrap=self.afile_json.copy(), agave_client=ac)
     return af