예제 #1
0
    async def _resolve_path_to_ids(self, path, start_at=None):
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        # parts is list of [path_part_name, is_folder]
        parts = [[parse.unquote(x), True] for x in path.strip('/').split('/')]

        if not path.endswith('/'):
            parts[-1][1] = False
        while parts:
            current_part = parts.pop(0)
            query = "title = '{}' " \
                    "and trashed = false " \
                    "and mimeType != 'application/vnd.google-apps.form' " \
                    "and mimeType != 'application/vnd.google-apps.map' " \
                    "and mimeType {} '{}'".format(
                        clean_query(current_part[0]),
                        '=' if current_part[1] else '!=',
                        self.FOLDER_MIME_TYPE
                    )
            async with self.request(
                'GET',
                self.build_url('files', item_id, 'children', q=query, fields='items(id)'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                data = await resp.json()

            try:
                item_id = data['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    raise exceptions.MetadataError('{} not found'.format(str(path)), code=http.client.NOT_FOUND)
                name, ext = os.path.splitext(current_part[0])
                if ext not in ('.gdoc', '.gdraw', '.gslides', '.gsheet'):
                    return ret + [{
                        'id': None,
                        'title': current_part[0],
                        'mimeType': 'folder' if path.endswith('/') else '',
                    }]
                parts.append([name, current_part[1]])

            async with self.request(
                'GET',
                self.build_url('files', item_id, fields='id,title,mimeType'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                ret.append(await resp.json())

        return ret
예제 #2
0
    async def _resolve_path_to_ids(self, path, start_at=None):
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        # parts is list of [path_part_name, is_folder]
        parts = [[parse.unquote(x), True] for x in path.strip('/').split('/')]

        if not path.endswith('/'):
            parts[-1][1] = False
        while parts:
            current_part = parts.pop(0)
            query = "title = '{}' " \
                    "and trashed = false " \
                    "and mimeType != 'application/vnd.google-apps.form' " \
                    "and mimeType {} '{}'".format(
                        clean_query(current_part[0]),
                        '=' if current_part[1] else '!=',
                        self.FOLDER_MIME_TYPE
                    )
            async with self.request(
                'GET',
                self.build_url('files', item_id, 'children', q=query, fields='items(id)'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                data = await resp.json()

            try:
                item_id = data['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    raise exceptions.MetadataError('{} not found'.format(str(path)), code=http.client.NOT_FOUND)
                name, ext = os.path.splitext(current_part[0])
                if ext not in ('.gdoc', '.gdraw', '.gslides', '.gsheet'):
                    return ret + [{
                        'id': None,
                        'title': current_part[0],
                        'mimeType': 'folder' if path.endswith('/') else '',
                    }]
                parts.append([name, current_part[1]])

            async with self.request(
                'GET',
                self.build_url('files', item_id, fields='id,title,mimeType'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                ret.append(await resp.json())

        return ret
예제 #3
0
    def _resolve_path_to_ids(self, path, start_at=None):
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        parts = [parse.unquote(x) for x in path.strip('/').split('/')]

        while parts:
            current_part = parts.pop(0)

            resp = yield from self.make_request(
                'GET',
                self.build_url('files',
                               item_id,
                               'children',
                               q="title = '{}'".format(
                                   clean_query(current_part)),
                               fields='items(id)'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            )

            try:
                item_id = (yield from resp.json())['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    raise exceptions.MetadataError('{} not found'.format(
                        str(path)),
                                                   code=http.client.NOT_FOUND)
                name, ext = os.path.splitext(current_part)
                if ext not in ('.gdoc', '.gdraw', '.gslides', '.gsheet'):
                    return ret + [
                        {
                            'id': None,
                            'title': current_part,
                            'mimeType': 'folder' if path.endswith('/') else '',
                        }
                    ]
                parts.append(name)

            resp = yield from self.make_request(
                'GET',
                self.build_url('files', item_id, fields='id,title,mimeType'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            )

            ret.append((yield from resp.json()))

        return ret
예제 #4
0
    async def _search_tree_for_path(self, path, tree_sha, recursive=True):
        """Search through the given tree for an entity matching the name and type of `path`.
        """
        tree = await self._fetch_tree(tree_sha, recursive=True)

        if tree['truncated']:
            raise GitHubUnsupportedRepoError

        implicit_type = 'tree' if path.endswith('/') else 'blob'

        for entity in tree['tree']:
            if entity['path'] == path.strip('/') and entity['type'] == implicit_type:
                return entity

        raise exceptions.NotFoundError(str(path))
예제 #5
0
    async def _search_tree_for_path(self, path, tree_sha, recursive=True):
        """Search through the given tree for an entity matching the name and type of `path`.
        """
        tree = await self._fetch_tree(tree_sha, recursive=True)

        if tree['truncated']:
            raise GitHubUnsupportedRepoError

        implicit_type = 'tree' if path.endswith('/') else 'blob'

        for entity in tree['tree']:
            if entity['path'] == path.strip(
                    '/') and entity['type'] == implicit_type:
                return entity

        raise exceptions.NotFoundError(str(path))
예제 #6
0
    def _resolve_path_to_ids(self, path, start_at=None):
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        parts = [parse.unquote(x) for x in path.strip('/').split('/')]

        while parts:
            current_part = parts.pop(0)

            resp = yield from self.make_request(
                'GET',
                self.build_url('files', item_id, 'children', q='title = "{}"'.format(current_part.replace('"', '\\"')), fields='items(id)'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            )

            try:
                item_id = (yield from resp.json())['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    raise exceptions.MetadataError('{} not found'.format(str(path)), code=http.client.NOT_FOUND)
                name, ext = os.path.splitext(current_part)
                if ext not in ('.gdoc', '.gsheet'):
                    return ret + [{
                        'id': None,
                        'title': current_part,
                        'mimeType': 'folder' if path.endswith('/') else '',
                    }]
                parts.append(name)

            resp = yield from self.make_request(
                'GET',
                self.build_url('files', item_id, fields='id,title,mimeType'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            )

            ret.append((yield from resp.json()))

        return ret
예제 #7
0
    def _resolve_path_to_ids(self, path, start_at=None):
        ret = start_at or [{"title": "", "mimeType": "folder", "id": self.folder["id"]}]
        item_id = ret[0]["id"]
        parts = [parse.unquote(x) for x in path.strip("/").split("/")]

        while parts:
            current_part = parts.pop(0)

            resp = yield from self.make_request(
                "GET",
                self.build_url(
                    "files", item_id, "children", q="title = '{}'".format(clean_query(current_part)), fields="items(id)"
                ),
                expects=(200,),
                throws=exceptions.MetadataError,
            )

            try:
                item_id = (yield from resp.json())["items"][0]["id"]
            except (KeyError, IndexError):
                if parts:
                    raise exceptions.MetadataError("{} not found".format(str(path)), code=http.client.NOT_FOUND)
                name, ext = os.path.splitext(current_part)
                if ext not in (".gdoc", ".gdraw", ".gslides", ".gsheet"):
                    return ret + [
                        {"id": None, "title": current_part, "mimeType": "folder" if path.endswith("/") else ""}
                    ]
                parts.append(name)

            resp = yield from self.make_request(
                "GET",
                self.build_url("files", item_id, fields="id,title,mimeType"),
                expects=(200,),
                throws=exceptions.MetadataError,
            )

            ret.append((yield from resp.json()))

        return ret
예제 #8
0
    async def _resolve_path_to_ids(self, path, start_at=None):
        """Takes a path and traverses the file tree (ha!) beginning at ``start_at``, looking for
        something that matches ``path``.  Returns a list of dicts for each part of the path, with
        ``title``, ``mimeType``, and ``id`` keys.
        """
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        # parts is list of [path_part_name, is_folder]
        parts = [[parse.unquote(x), True] for x in path.strip('/').split('/')]

        if not path.endswith('/'):
            parts[-1][1] = False
        while parts:
            current_part = parts.pop(0)
            query = "title = '{}' " \
                    "and trashed = false " \
                    "and mimeType != 'application/vnd.google-apps.form' " \
                    "and mimeType != 'application/vnd.google-apps.map' " \
                    "and mimeType {} '{}'".format(
                        clean_query(current_part[0]),
                        '=' if current_part[1] else '!=',
                        self.FOLDER_MIME_TYPE
                    )
            async with self.request(
                    'GET',
                    self.build_url('files',
                                   item_id,
                                   'children',
                                   q=query,
                                   fields='items(id)'),
                    expects=(200, ),
                    throws=exceptions.MetadataError,
            ) as resp:
                data = await resp.json()

            try:
                item_id = data['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    # if we can't find an intermediate path part, that's an error
                    raise exceptions.MetadataError('{} not found'.format(
                        str(path)),
                                                   code=http.client.NOT_FOUND)

                # Couldn't find id for last part of path. If path includes Google Doc extension,
                # search again without extension (gdrive won't find it if included). Otherwise,
                # assume file or folder doesn't yet exist (i.e. id = None)
                name, ext = os.path.splitext(current_part[0])
                if ext not in ('.gdoc', '.gdraw', '.gslides', '.gsheet'):
                    return ret + [
                        {
                            'id': None,
                            'title': current_part[0],
                            'mimeType': 'folder' if path.endswith('/') else '',
                        }
                    ]
                # strip google docs extension and try again
                parts.append([name, current_part[1]])
                continue

            async with self.request(
                    'GET',
                    self.build_url('files',
                                   item_id,
                                   fields='id,title,mimeType'),
                    expects=(200, ),
                    throws=exceptions.MetadataError,
            ) as resp:
                ret.append(await resp.json())

        return ret
예제 #9
0
    async def _resolve_path_to_ids(self, path, start_at=None):
        """Takes a path and traverses the file tree (ha!) beginning at ``start_at``, looking for
        something that matches ``path``.  Returns a list of dicts for each part of the path, with
        ``title``, ``mimeType``, and ``id`` keys.
        """
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        # parts is list of [path_part_name, is_folder]
        parts = [[parse.unquote(x), True] for x in path.strip('/').split('/')]

        if not path.endswith('/'):
            parts[-1][1] = False
        while parts:
            current_part = parts.pop(0)
            part_name, part_is_folder = current_part[0], current_part[1]
            name, ext = os.path.splitext(part_name)
            if not part_is_folder and ext in ('.gdoc', '.gdraw', '.gslides', '.gsheet'):
                gd_ext = drive_utils.get_mimetype_from_ext(ext)
                query = "title = '{}' " \
                        "and trashed = false " \
                        "and mimeType = '{}'".format(clean_query(name), gd_ext)
            else:
                query = "title = '{}' " \
                        "and trashed = false " \
                        "and mimeType != 'application/vnd.google-apps.form' " \
                        "and mimeType != 'application/vnd.google-apps.map' " \
                        "and mimeType {} '{}'".format(
                            clean_query(part_name),
                            '=' if part_is_folder else '!=',
                            self.FOLDER_MIME_TYPE
                        )
            async with self.request(
                'GET',
                self.build_url('files', item_id, 'children', q=query, fields='items(id)'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                data = await resp.json()

            try:
                item_id = data['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    # if we can't find an intermediate path part, that's an error
                    raise exceptions.MetadataError('{} not found'.format(str(path)), code=http.client.NOT_FOUND)
                return ret + [{
                    'id': None,
                    'title': part_name,
                    'mimeType': 'folder' if part_is_folder else '',
                }]

            async with self.request(
                'GET',
                self.build_url('files', item_id, fields='id,title,mimeType'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                ret.append(await resp.json())

        return ret
예제 #10
0
    async def _resolve_path_to_ids(self, path, start_at=None):
        """Takes a path and traverses the file tree (ha!) beginning at ``start_at``, looking for
        something that matches ``path``.  Returns a list of dicts for each part of the path, with
        ``title``, ``mimeType``, and ``id`` keys.
        """
        ret = start_at or [{
            'title': '',
            'mimeType': 'folder',
            'id': self.folder['id'],
        }]
        item_id = ret[0]['id']
        # parts is list of [path_part_name, is_folder]
        parts = [[parse.unquote(x), True] for x in path.strip('/').split('/')]

        if not path.endswith('/'):
            parts[-1][1] = False
        while parts:
            current_part = parts.pop(0)
            query = "title = '{}' " \
                    "and trashed = false " \
                    "and mimeType != 'application/vnd.google-apps.form' " \
                    "and mimeType != 'application/vnd.google-apps.map' " \
                    "and mimeType {} '{}'".format(
                        clean_query(current_part[0]),
                        '=' if current_part[1] else '!=',
                        self.FOLDER_MIME_TYPE
                    )
            async with self.request(
                'GET',
                self.build_url('files', item_id, 'children', q=query, fields='items(id)'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                data = await resp.json()

            try:
                item_id = data['items'][0]['id']
            except (KeyError, IndexError):
                if parts:
                    # if we can't find an intermediate path part, that's an error
                    raise exceptions.MetadataError('{} not found'.format(str(path)), code=http.client.NOT_FOUND)

                # Couldn't find id for last part of path. If path includes Google Doc extension,
                # search again without extension (gdrive won't find it if included). Otherwise,
                # assume file or folder doesn't yet exist (i.e. id = None)
                name, ext = os.path.splitext(current_part[0])
                if ext not in ('.gdoc', '.gdraw', '.gslides', '.gsheet'):
                    return ret + [{
                        'id': None,
                        'title': current_part[0],
                        'mimeType': 'folder' if path.endswith('/') else '',
                    }]
                # strip google docs extension and try again
                parts.append([name, current_part[1]])
                continue

            async with self.request(
                'GET',
                self.build_url('files', item_id, fields='id,title,mimeType'),
                expects=(200, ),
                throws=exceptions.MetadataError,
            ) as resp:
                ret.append(await resp.json())

        return ret