コード例 #1
0
ファイル: documents.py プロジェクト: letaniaferreira/portal
    def search_query(cls, username, q, fields=[], sanitize=True, **kwargs):
        """Search the Elasticsearch index using a query string

        Use a query string to search the ES index. This method will search
        on the fields **name**, and **keywords**

        :param str username: username making the request
        :param str q: string to query the ES index
        :param list fields: list of strings

        .. note:: In order to make this method scalable more fields can be
            searched by passing a **fields** keyword argument. You can add
            the **systemTags** field like so:
            >>> Object.search('username', 'txt', fields = ['systemTags'])
        """
        if isinstance(fields, basestring):
            fields = fields.split(',')

        search_fields = ['name', 'name._exact', 'keywords']

        if fields:
            search_fields += fields

        sq = Q('bool',
               must=query_utils.files_wildcard_query(q, search_fields),
               filter=query_utils.files_access_filter(username))
        s = cls.search()
        s.query = sq
        s = s.sort('path._exact', 'name._exact')

        res, s = cls._execute_search(s)
        offset, limit = cls.get_paginate_limits(res, **kwargs)
        #logger.debug('limit: %s. offset: %s' % (limit, offset))
        return res, s[offset:limit]
コード例 #2
0
ファイル: documents.py プロジェクト: DesignSafe-CI/portal
    def search_query(cls, username, q, fields = [], sanitize = True, **kwargs):
        """Search the Elasticsearch index using a query string

        Use a query string to search the ES index. This method will search 
        on the fields **name**, and **keywords**

        :param str username: username making the request
        :param str q: string to query the ES index
        :param list fields: list of strings

        .. note:: In order to make this method scalable more fields can be
            searched by passing a **fields** keyword argument. You can add
            the **systemTags** field like so:
            >>> Object.search('username', 'txt', fields = ['systemTags'])
        """
        if isinstance(fields, basestring):
            fields = fields.split(',')

        search_fields = ['name', 'name._exact', 'keywords']

        if fields:
            search_fields += fields

        sq = Q('filtered',
                query = query_utils.files_wildcard_query(q, search_fields),
                filter = query_utils.files_access_filter(username)
                )
        s = cls.search()
        s.query = sq
        s = s.sort('path._exact', 'name._exact')

        res, s = cls._execute_search(s)
        offset, limit = cls.get_paginate_limits(res, **kwargs)
        #logger.debug('limit: %s. offset: %s' % (limit, offset))
        return res, s[offset:limit]
コード例 #3
0
ファイル: documents.py プロジェクト: letaniaferreira/portal
    def from_file_path(cls, system, username, file_path):
        """Retrieves a document from the ES index based on a path.

        :param str system: system id
        :param str username: username making the request
        :param str file_path: path of a file

        :returns: instance of this class or None if the file
            doesn't exists in the index
        :rtype: :class:`Object`
        """
        path, name = os.path.split(file_path)
        path = path or '/'
        q = Q('bool',
              must=Q('bool',
                     must=[
                         Q({'term': {
                             'path._exact': path
                         }}),
                         Q({'term': {
                             'name._exact': name
                         }})
                     ]),
              filter=query_utils.files_access_filter(username, system))

        s = cls.search()
        s.query = q
        res, s = cls._execute_search(s)
        if res.hits.total:
            return res[0]
        else:
            return None
コード例 #4
0
ファイル: documents.py プロジェクト: DesignSafe-CI/portal
    def from_file_path(cls, system, username, file_path):
        """Retrieves a document from the ES index based on a path.

        :param str system: system id
        :param str username: username making the request
        :param str file_path: path of a file

        :returns: instance of this class or None if the file
            doesn't exists in the index
        :rtype: :class:`Object`
        """
        path, name = os.path.split(file_path)
        path = path or '/'
        q = Q('filtered',
             query = Q('bool',
                      must = [
                        Q({'term': {'path._exact': path}}),
                        Q({'term': {'name._exact': name}})
                        ]
                     ),
            filter = query_utils.files_access_filter(username, system)
            )

        s = cls.search()
        s.query = q
        res, s = cls._execute_search(s)
        if res.hits.total:
            return res[0]
        else:
            return None
コード例 #5
0
ファイル: documents.py プロジェクト: DesignSafe-CI/portal
    def listing_recursive(cls, system, username, file_path, **kwargs):
        """Do a listing recursevly

        This method will first check if the file_path that is been listing
        is not a shared file, if so, it will use :func:`_listing_recursive`.
        If ``file_path`` is a shared file it will combine the listing into
        common denominators. This approach is neccesary in order to avoid
        showing empty shared directories or directories where there are
        no files shared with the requesting user. This gives the user
        a more fluent navigation.

        .. example::
            **Reasoning behind combining the listing into common 
            denomintaros**.

            Say there are three folders ``a/b``, ``a/c`` and ``a/d``.
            And say a user has shared a few files and directories
            like this:
            - ``a/b/path/to/folder``
            - ``a/b/path/to/folder/file1.txt``
            - ``a/c/path/another/folder``
            - ``a/c/path/another/folder2``
            - ``a/d/file``
            Then the listing should show as this:
            - ``a/b/path/to/folder``
            - ``a/c/path/another``
            - ``a/d/file``
            Thus making a more fluent navigation.
        .. note::
            This function assumes than when listing the root path 
            (``/`` or `` ``) then we are doing a listing of shared
            files.
        """
        owner = file_path.split('/')[0]
        #If we are listing something inside the requesting user's home dir.
        if username == owner or username == 'ds_admin':
            return cls._listing_recursive(system, username, file_path)
        
        #Everything else should be something shared. If we are listing the
        #root path get everything.
        if file_path == '/' or file_path == '':
            q = Q('filtered',
                  filter = query_utils.files_access_filter(username, system)
                  )
            s = cls.search()
            s = s.sort('path._path', 'name._exact')
            s.query = q
            logger.debug('Recursive Listing query: {}'.format(s.to_dict()))
            r, s = cls._execute_search(s)
        else:
            #Get recursive listing for shared path.
            r, s = cls._listing_recursive(system, username, file_path)

        listing = merge_file_paths(system, username, file_path, s)
        r.hits.total = len(listing)
        offset, limit = cls.get_paginate_limits(r, **kwargs)
        return r, listing[offset:limit]
コード例 #6
0
ファイル: documents.py プロジェクト: letaniaferreira/portal
    def listing_recursive(cls, system, username, file_path, **kwargs):
        """Do a listing recursevly

        This method will first check if the file_path that is been listing
        is not a shared file, if so, it will use :func:`_listing_recursive`.
        If ``file_path`` is a shared file it will combine the listing into
        common denominators. This approach is neccesary in order to avoid
        showing empty shared directories or directories where there are
        no files shared with the requesting user. This gives the user
        a more fluent navigation.

        .. example::
            **Reasoning behind combining the listing into common
            denomintaros**.

            Say there are three folders ``a/b``, ``a/c`` and ``a/d``.
            And say a user has shared a few files and directories
            like this:
            - ``a/b/path/to/folder``
            - ``a/b/path/to/folder/file1.txt``
            - ``a/c/path/another/folder``
            - ``a/c/path/another/folder2``
            - ``a/d/file``
            Then the listing should show as this:
            - ``a/b/path/to/folder``
            - ``a/c/path/another``
            - ``a/d/file``
            Thus making a more fluent navigation.
        .. note::
            This function assumes than when listing the root path
            (``/`` or `` ``) then we are doing a listing of shared
            files.
        """
        owner = file_path.split('/')[0]
        #If we are listing something inside the requesting user's home dir.
        if username == owner or username == 'ds_admin':
            return cls._listing_recursive(system, username, file_path)

        #Everything else should be something shared. If we are listing the
        #root path get everything.
        if file_path == '/' or file_path == '':
            q = Q('bool',
                  filter=query_utils.files_access_filter(username, system))
            s = cls.search()
            s = s.sort('path._exact', 'name._exact')
            s.query = q
            logger.debug('Recursive Listing query: {}'.format(s.to_dict()))
            r, s = cls._execute_search(s)
        else:
            #Get recursive listing for shared path.
            r, s = cls._listing_recursive(system, username, file_path)

        listing = merge_file_paths(system, username, file_path, s)
        r.hits.total = len(listing)
        offset, limit = cls.get_paginate_limits(r, **kwargs)
        return r, listing[offset:limit]
コード例 #7
0
ファイル: documents.py プロジェクト: DesignSafe-CI/portal
    def _listing_recursive(cls, system, username, file_path):
        """Do a listing recursively

        This method is an efficient way to recursively do a "listing" of a 
        folder. This is because of the hierarcical tokenizer we have in 
        `path._path`. The returning listing will be sorted by path and name

        :param str system: system id
        :param str username: username making the request
        :param str file_path: path of the folder to list

        :returns: list of :class:`Object`
        :rtype: list

        .. note:: the returned list does not contain the parent file

        Examples:
        ---------
            Sort listing by depth

            .. code-block:: python

                >>> listing = Object.listing_recursive('agave.system.id',
                ...                     'username', 'username/path/folder')
                >>> sorted(listing, key=lambda x: len(x.full_path.split('/')))

            .. note:: Python sorting is stable. In theory we could sort the listing
                alphabetically (default behaivour) and then sort the listing
                by depth and we'll end up with a listing sorted both by depth
                and alphabetically.

        """
        #logger.debug('Using username: {}'.format(username))
        q = Q('filtered',
              query = Q('bool',
                        must = [
                          Q({'term': {'path._path': file_path}})
                          ]
                      ),
              filter = query_utils.files_access_filter(username, system)
              )
        s = cls.search()
        s = s.sort('path._exact', 'name._exact')
        s.query = q
        return cls._execute_search(s)
コード例 #8
0
ファイル: documents.py プロジェクト: letaniaferreira/portal
    def _listing_recursive(cls, system, username, file_path):
        """Do a listing recursively

        This method is an efficient way to recursively do a "listing" of a
        folder. This is because of the hierarcical tokenizer we have in
        `path._path`. The returning listing will be sorted by path and name

        :param str system: system id
        :param str username: username making the request
        :param str file_path: path of the folder to list

        :returns: list of :class:`Object`
        :rtype: list

        .. note:: the returned list does not contain the parent file

        Examples:
        ---------
            Sort listing by depth

            .. code-block:: python

                >>> listing = Object.listing_recursive('agave.system.id',
                ...                     'username', 'username/path/folder')
                >>> sorted(listing, key=lambda x: len(x.full_path.split('/')))

            .. note:: Python sorting is stable. In theory we could sort the listing
                alphabetically (default behaivour) and then sort the listing
                by depth and we'll end up with a listing sorted both by depth
                and alphabetically.

        """
        #logger.debug('Using username: {}'.format(username))
        q = Q('bool',
              must=Q('bool', must=[Q({'term': {
                  'path._path': file_path
              }})]),
              filter=query_utils.files_access_filter(username, system))
        s = cls.search()
        s = s.sort('path._exact', 'name._exact')
        s.query = q
        return cls._execute_search(s)
コード例 #9
0
ファイル: documents.py プロジェクト: letaniaferreira/portal
    def listing(cls, system, username, file_path, **kwargs):
        """Do a listing of one level.

        :param str system: system id
        :param str username: username making the request
        :param str file_path: file path to list

        :returns: list of :class:`Object`
        :rtype: list
        """
        q = Q('bool',
              must=Q({'term': {
                  'path._exact': file_path
              }}),
              filter=query_utils.files_access_filter(username, system))
        s = cls.search()
        s.query = q
        s = s.sort({'name._exact': 'asc'})

        res, s = cls._execute_search(s)
        offset, limit = cls.get_paginate_limits(res, **kwargs)

        return res, s[offset:limit]
コード例 #10
0
ファイル: documents.py プロジェクト: DesignSafe-CI/portal
    def listing(cls, system, username, file_path, **kwargs):
        """Do a listing of one level.

        :param str system: system id
        :param str username: username making the request
        :param str file_path: file path to list

        :returns: list of :class:`Object`
        :rtype: list
        """
        q = Q('filtered',
              query = Q('bool',
                        must = Q({'term': {'path._exact': file_path}})
                        ),
              filter = query_utils.files_access_filter(username, system)
              )
        s = cls.search()
        s.query = q
        s = s.sort({'name._exact': 'asc'})

        res, s = cls._execute_search(s)
        offset, limit = cls.get_paginate_limits(res, **kwargs)

        return res, s[offset:limit]