Пример #1
0
    def get_all_translation_opportunities(
        cls, page_size: int, urlsafe_start_cursor: Optional[str],
        language_code: str
    ) -> Tuple[List['ExplorationOpportunitySummaryModel'], Optional[str],
               bool]:
        """Returns a list of opportunities available for translation in a
        specific language.

        Args:
            page_size: int. The maximum number of entities to be returned.
            urlsafe_start_cursor: str or None. If provided, the list of
                returned entities starts from this datastore cursor.
                Otherwise, the returned entities start from the beginning
                of the full list of entities.
            language_code: str. The language for which translation opportunities
                are to be fetched.

        Returns:
            3-tuple of (results, cursor, more). As described in fetch_page() at:
            https://developers.google.com/appengine/docs/python/ndb/queryclass,
            where:
                results: list(ExplorationOpportunitySummaryModel). A list
                    of query results.
                cursor: str or None. A query cursor pointing to the next
                    batch of results. If there are no more results, this might
                    be None.
                more: bool. If True, there are (probably) more results after
                    this batch. If False, there are no further results after
                    this batch.
        """
        if urlsafe_start_cursor:
            start_cursor = datastore_services.make_cursor(
                urlsafe_cursor=urlsafe_start_cursor)
        else:
            start_cursor = datastore_services.make_cursor()

        language_query = cls.query(
            cls.incomplete_translation_language_codes == language_code).order(
                cls.incomplete_translation_language_codes)

        results, cursor, _ = (language_query.fetch_page(
            page_size, start_cursor=start_cursor))
        # TODO(#13462): Refactor this so that we don't do the lookup.
        # Do a forward lookup so that we can know if there are more values.
        plus_one_query_models, _, _ = (language_query.fetch_page(
            page_size + 1, start_cursor=start_cursor))
        more_results = len(plus_one_query_models) == page_size + 1
        # The urlsafe returns bytes and we need to decode them to string.
        return (cast(List[ExplorationOpportunitySummaryModel], results),
                (cursor.urlsafe().decode('utf-8') if cursor else None),
                more_results)
Пример #2
0
    def fetch_page(
            cls,
            page_size: int,
            urlsafe_start_cursor: Optional[str],
            sort_by: Optional[str]
    ) -> Tuple[List['SkillSummaryModel'], Optional[str], bool]:
        """Returns the models according to values specified.

        Args:
            page_size: int. Number of skills to fetch.
            urlsafe_start_cursor: str|None. The cursor to the next page or
                None. If None, this means that the search should start from the
                first page of results.
            sort_by: str|None. A string indicating how to sort the result.

        Returns:
            3-tuple(query_models, urlsafe_start_cursor, more). where:
                query_models: list(SkillSummary). The list of summaries
                    of skills starting at the given cursor.
                urlsafe_start_cursor: str or None. A query cursor pointing to
                    the next batch of results. If there are no more results,
                    this might be None.
                more: bool. If True, there are (probably) more results after
                    this batch. If False, there are no further results
                    after this batch.
        """
        cursor = (
            datastore_services.make_cursor(urlsafe_cursor=urlsafe_start_cursor))
        sort = -cls.skill_model_created_on
        if sort_by == (
                constants.TOPIC_SKILL_DASHBOARD_SORT_OPTIONS[
                    'DecreasingCreatedOn']):
            sort = cls.skill_model_created_on
        elif sort_by == (
                constants.TOPIC_SKILL_DASHBOARD_SORT_OPTIONS[
                    'IncreasingUpdatedOn']):
            sort = -cls.skill_model_last_updated
        elif sort_by == (
                constants.TOPIC_SKILL_DASHBOARD_SORT_OPTIONS[
                    'DecreasingUpdatedOn']):
            sort = cls.skill_model_last_updated

        sort_query = cls.query().order(sort)
        query_models, next_cursor, _ = (
            sort_query.fetch_page(page_size, start_cursor=cursor))
        # TODO(#13462): Refactor this so that we don't do the lookup.
        # Do a forward lookup so that we can know if there are more values.
        plus_one_query_models, _, _ = (
            sort_query.fetch_page(page_size + 1, start_cursor=cursor))
        # The urlsafe returns bytes and we need to decode them to string.
        more_results = len(plus_one_query_models) == page_size + 1
        new_urlsafe_start_cursor = (
            next_cursor.urlsafe().decode('utf-8')
            if (next_cursor and more_results) else None
        )
        return (
            cast(List[SkillSummaryModel], query_models),
            new_urlsafe_start_cursor, more_results)
Пример #3
0
    def get_skill_opportunities(
            cls,
            page_size: int,
            urlsafe_start_cursor: Optional[str]
    ) -> Tuple[Sequence['SkillOpportunityModel'], Optional[str], bool]:
        """Returns a list of skill opportunities available for adding questions.

        Args:
            page_size: int. The maximum number of entities to be returned.
            urlsafe_start_cursor: str or None. If provided, the list of
                returned entities starts from this datastore cursor.
                Otherwise, the returned entities start from the beginning
                of the full list of entities.

        Returns:
            3-tuple of (results, cursor, more). As described in fetch_page() at:
            https://developers.google.com/appengine/docs/python/ndb/queryclass,
            where:
                results: list(SkillOpportunityModel). A list
                    of query results.
                cursor: str or None. A query cursor pointing to the next
                    batch of results. If there are no more results, this might
                    be None.
                more: bool. If True, there are (probably) more results after
                    this batch. If False, there are no further results after
                    this batch.
        """
        start_cursor = datastore_services.make_cursor(
            urlsafe_cursor=urlsafe_start_cursor)

        created_on_query = cls.get_all().order(cls.created_on)
        fetch_result: Tuple[
            Sequence[SkillOpportunityModel], datastore_services.Cursor, bool
        ] = created_on_query.fetch_page(page_size, start_cursor=start_cursor)
        query_models, cursor, _ = fetch_result
        # TODO(#13462): Refactor this so that we don't do the lookup.
        # Do a forward lookup so that we can know if there are more values.
        fetch_result = created_on_query.fetch_page(
            page_size + 1, start_cursor=start_cursor)
        plus_one_query_models, _, _ = fetch_result
        more_results = len(plus_one_query_models) == page_size + 1
        # The urlsafe returns bytes and we need to decode them to string.
        return (
            query_models,
            (cursor.urlsafe().decode('utf-8') if cursor else None),
            more_results
        )
Пример #4
0
def fetch_exploration_task_history_page(
    exploration: exp_domain.Exploration,
    urlsafe_start_cursor: Optional[str] = None
) -> Tuple[List[improvements_domain.TaskEntry], Optional[str], bool]:
    """Fetches a page from the given exploration's history of resolved tasks.

    Args:
        exploration: exp_domain.Exploration. The exploration to fetch the
            history page for.
        urlsafe_start_cursor: str or None. Starting point for the search. When
            None, the starting point is the very beginning of the history
            results (i.e. starting from the most recently resolved task entry).

    Returns:
        tuple. Contains the following 3 items:
            results: list(improvements_domain.TaskEntry). The query results.
            urlsafe_cursor: str or None. a query cursor pointing to the "next"
                batch of results. If there are no more results, this might be
                None.
            more: bool. Indicates whether there are (likely) more results after
                this batch. If False, there are no more results; if True, there
                are probably more results.
    """
    results: Sequence[improvements_models.TaskEntryModel] = []
    start_cursor = (datastore_services.make_cursor(
        urlsafe_cursor=urlsafe_start_cursor) if urlsafe_start_cursor else None)
    results, cursor, more = (improvements_models.TaskEntryModel.query(
        improvements_models.TaskEntryModel.entity_type == (
            constants.TASK_ENTITY_TYPE_EXPLORATION),
        improvements_models.TaskEntryModel.entity_id == exploration.id,
        improvements_models.TaskEntryModel.status == (
            constants.TASK_STATUS_RESOLVED
        )).order(-improvements_models.TaskEntryModel.resolved_on).fetch_page(
            feconf.MAX_TASK_MODELS_PER_HISTORY_PAGE,
            start_cursor=start_cursor))
    # The urlsafe returns bytes and we need to decode them to string.
    return ([get_task_entry_from_model(model) for model in results],
            cursor.urlsafe().decode('utf-8') if cursor else None, more)