Beispiel #1
0
class TopicListingSchema(Schema):
    """Marshmallow schema to validate arguments for a topic listing page."""

    DEFAULT_TOPICS_PER_PAGE = 50

    order = Enum(TopicSortOption)
    period = ShortTimePeriod(allow_none=True)
    after = ID36()
    before = ID36()
    per_page = Integer(
        validate=Range(min=1, max=100),
        missing=DEFAULT_TOPICS_PER_PAGE,
    )
    rank_start = Integer(load_from='n', validate=Range(min=1), missing=None)
    tag = Ltree(missing=None)
    unfiltered = Boolean(missing=False)

    @validates_schema
    def either_after_or_before(self, data: dict) -> None:
        """Fail validation if both after and before were specified."""
        if data.get('after') and data.get('before'):
            raise ValidationError("Can't specify both after and before.")

    @pre_load
    def reset_rank_start_on_first_page(self, data: dict) -> dict:
        """Reset rank_start to 1 if this is a first page (no before/after)."""
        if not (data.get('before') or data.get('after')):
            data['rank_start'] = 1

        return data

    class Meta:
        """Always use strict checking so error handlers are invoked."""

        strict = True
Beispiel #2
0
def _get_default_settings(request: Request, order: Any) -> DefaultSettings:
    if isinstance(request.context, Group):
        is_home_page = False
        user_settings = (request.query(UserGroupSettings).filter(
            UserGroupSettings.user == request.user,
            UserGroupSettings.group == request.context,
        ).one_or_none())
    else:
        is_home_page = True
        user_settings = None

    if user_settings and user_settings.default_order:
        default_order = user_settings.default_order
    elif request.user.home_default_order:
        default_order = request.user.home_default_order
    else:
        default_order = TopicSortOption.ACTIVITY

    # the default period depends on what the order is, so we need to see if
    # we're going to end up using the default order here as well
    if order is missing:
        order = default_order

    if user_settings and user_settings.default_period:
        user_default = user_settings.default_period
        default_period = ShortTimePeriod().deserialize(user_default)
    elif request.user.home_default_period:
        user_default = request.user.home_default_period
        default_period = ShortTimePeriod().deserialize(user_default)
    else:
        # Overall default periods, if the user doesn't have either a
        # group-specific or a home default set up:
        #   * "all time" if sorting by new
        #   * "all time" if sorting by activity and inside a group
        #   * "3 days" if sorting by activity and on home page
        #   * "1 day" otherwise (sorting by most votes or most comments)
        if order == TopicSortOption.NEW:
            default_period = None
        elif order == TopicSortOption.ACTIVITY and not is_home_page:
            default_period = None
        elif order == TopicSortOption.ACTIVITY:
            default_period = SimpleHoursPeriod(72)
        else:
            default_period = SimpleHoursPeriod(24)

    return DefaultSettings(order=default_order, period=default_period)
Beispiel #3
0
def _get_default_settings(
    request: Request, order: Optional[TopicSortOption]
) -> DefaultSettings:
    if isinstance(request.context, Group) and request.user:
        user_settings = (
            request.query(UserGroupSettings)
            .filter(
                UserGroupSettings.user == request.user,
                UserGroupSettings.group == request.context,
            )
            .one_or_none()
        )
    else:
        user_settings = None

    if user_settings and user_settings.default_order:
        default_order = user_settings.default_order
    elif request.user and request.user.home_default_order:
        default_order = request.user.home_default_order
    else:
        default_order = TopicSortOption.ACTIVITY

    # the default period depends on what the order is, so we need to see if we're going
    # to end up using the default order here as well
    if not order:
        order = default_order

    if user_settings and user_settings.default_period:
        user_default = user_settings.default_period
        default_period = ShortTimePeriod().deserialize(user_default)
    elif request.user and request.user.home_default_period:
        user_default = request.user.home_default_period
        default_period = ShortTimePeriod().deserialize(user_default)
    else:
        # Overall default periods, if the user doesn't have either a group-specific or a
        # home default set up:
        #   * "1 day" if sorting by most votes or most comments
        #   * "all time" otherwise
        if order in (TopicSortOption.VOTES, TopicSortOption.COMMENTS):
            default_period = SimpleHoursPeriod(24)
        else:
            default_period = None

    return DefaultSettings(order=default_order, period=default_period)
Beispiel #4
0
class TopicListingSchema(PaginatedListingSchema):
    """Marshmallow schema to validate arguments for a topic listing page."""

    period = ShortTimePeriod(allow_none=True)
    order = Enum(TopicSortOption)
    tag = Ltree(missing=None)
    unfiltered = Boolean(missing=False)
    rank_start = Integer(load_from="n", validate=Range(min=1), missing=None)

    @pre_load
    def reset_rank_start_on_first_page(self, data: dict) -> dict:
        """Reset rank_start to 1 if this is a first page (no before/after)."""
        if not (data.get("before") or data.get("after")):
            data["rank_start"] = 1

        return data
Beispiel #5
0
class TopicListingSchema(PaginatedListingSchema):
    """Marshmallow schema to validate arguments for a topic listing page."""

    period = ShortTimePeriod(allow_none=True)
    order = Enum(TopicSortOption, missing=None)
    tag = Ltree(missing=None)
    unfiltered = Boolean(missing=False)
    rank_start = Integer(data_key="n", validate=Range(min=1), missing=None)

    @pre_load
    def reset_rank_start_on_first_page(
        self, data: dict, many: bool, partial: Any
    ) -> dict:
        """Reset rank_start to 1 if this is a first page (no before/after)."""
        # pylint: disable=unused-argument
        if "rank_start" not in self.fields:
            return data

        if not (data.get("before") or data.get("after")):
            data["n"] = 1

        return data
Beispiel #6
0
    # doing an atomic decrement on request.user.invite_codes_remaining is going to make
    # it unusable as an integer in the template, so store the expected value after the
    # decrement first, to be able to use that instead
    num_remaining = request.user.invite_codes_remaining - 1
    request.user.invite_codes_remaining = User.invite_codes_remaining - 1

    return {"code": code, "num_remaining": num_remaining}


@ic_view_config(
    route_name="user_default_listing_options",
    request_method="PUT",
    permission="edit_default_listing_options",
)
@use_kwargs(
    {"order": Enum(TopicSortOption), "period": ShortTimePeriod(allow_none=True)}
)
def put_default_listing_options(
    request: Request, order: TopicSortOption, period: Optional[ShortTimePeriod]
) -> dict:
    """Set the user's default listing options."""
    user = request.context

    user.home_default_order = order
    if period:
        user.home_default_period = period.as_short_form()
    else:
        user.home_default_period = "all"

    return IC_NOOP
Beispiel #7
0
            synchronize_session=False)

    # manually commit the transaction so triggers will execute
    request.tm.commit()

    # re-query the group to get complete data
    group = (request.query(Group).join_all_relationships().filter_by(
        group_id=group.group_id).one())

    return {"group": group}


@ic_view_config(route_name="group_user_settings", request_method="PATCH")
@use_kwargs({
    "order": Enum(TopicSortOption),
    "period": ShortTimePeriod(allow_none=True)
})
def patch_group_user_settings(request: Request, order: TopicSortOption,
                              period: Optional[ShortTimePeriod]) -> dict:
    """Set the user's default listing options."""
    if period:
        default_period = period.as_short_form()
    else:
        default_period = "all"

    statement = (insert(UserGroupSettings.__table__).values(
        user_id=request.user.user_id,
        group_id=request.context.group_id,
        default_order=order,
        default_period=default_period,
    ).on_conflict_do_update(
Beispiel #8
0
    request.tm.commit()

    # re-query the group to get complete data
    group = (request.query(Group).join_all_relationships().filter_by(
        group_id=group.group_id).one())

    return {'group': group}


@ic_view_config(
    route_name='group_user_settings',
    request_method='PATCH',
)
@use_kwargs({
    'order': Enum(TopicSortOption),
    'period': ShortTimePeriod(allow_none=True),
})
def patch_group_user_settings(
    request: Request,
    order: TopicSortOption,
    period: Optional[ShortTimePeriod],
) -> dict:
    """Set the user's default listing options."""
    if period:
        default_period = period.as_short_form()
    else:
        default_period = 'all'

    statement = (insert(UserGroupSettings.__table__).values(
        user_id=request.user.user_id,
        group_id=request.context.group_id,
Beispiel #9
0
    # decrement first, to be able to use that instead
    num_remaining = request.user.invite_codes_remaining - 1
    request.user.invite_codes_remaining = User.invite_codes_remaining - 1

    return {"code": code, "num_remaining": num_remaining}


@ic_view_config(
    route_name="user_default_listing_options",
    request_method="PUT",
    permission="edit_default_listing_options",
)
@use_kwargs(
    {
        "order": Enum(TopicSortOption),
        "period": ShortTimePeriod(allow_none=True, missing=None),
    },
    locations=(
        "form", ),  # will crash due to trying to find JSON data without this
)
def put_default_listing_options(request: Request, order: TopicSortOption,
                                period: Optional[SimpleHoursPeriod]) -> dict:
    """Set the user's default listing options."""
    user = request.context

    user.home_default_order = order
    if period:
        user.home_default_period = period.as_short_form()
    else:
        user.home_default_period = "all"