diff --git a/tildes/tildes/__init__.py b/tildes/tildes/__init__.py index 02df50d..655aee9 100644 --- a/tildes/tildes/__init__.py +++ b/tildes/tildes/__init__.py @@ -137,10 +137,11 @@ def current_listing_base_url( The `query` argument allows adding query variables to the generated url. """ - if request.matched_route.name not in ('home', 'group'): + if request.matched_route.name not in ('home', 'group', 'user'): raise AttributeError('Current route is not supported.') - base_view_vars = ('order', 'period', 'per_page', 'tag', 'unfiltered') + base_view_vars = ( + 'order', 'period', 'per_page', 'tag', 'type', 'unfiltered') query_vars = { key: val for key, val in request.GET.copy().items() if key in base_view_vars @@ -165,7 +166,7 @@ def current_listing_normal_url( The `query` argument allows adding query variables to the generated url. """ - if request.matched_route.name not in ('home', 'group'): + if request.matched_route.name not in ('home', 'group', 'user'): raise AttributeError('Current route is not supported.') normal_view_vars = ('order', 'period', 'per_page') diff --git a/tildes/tildes/models/comment/comment_query.py b/tildes/tildes/models/comment/comment_query.py index 672367b..fb029f8 100644 --- a/tildes/tildes/models/comment/comment_query.py +++ b/tildes/tildes/models/comment/comment_query.py @@ -4,12 +4,12 @@ from typing import Any from pyramid.request import Request -from tildes.models import ModelQuery +from tildes.models.pagination import PaginatedQuery from .comment import Comment from .comment_vote import CommentVote -class CommentQuery(ModelQuery): +class CommentQuery(PaginatedQuery): """Specialized ModelQuery for Comments.""" def __init__(self, request: Request) -> None: diff --git a/tildes/tildes/templates/macros/user_menu.jinja2 b/tildes/tildes/templates/macros/user_menu.jinja2 index 761a85a..0033ab9 100644 --- a/tildes/tildes/templates/macros/user_menu.jinja2 +++ b/tildes/tildes/templates/macros/user_menu.jinja2 @@ -7,7 +7,7 @@ diff --git a/tildes/tildes/templates/user.jinja2 b/tildes/tildes/templates/user.jinja2 index 1e3a1f1..a043528 100644 --- a/tildes/tildes/templates/user.jinja2 +++ b/tildes/tildes/templates/user.jinja2 @@ -10,13 +10,33 @@ {{ user.username }} {% endblock %} -{% block main_heading %}{{ user.username }}'s recent activity{% endblock %} +{# Only show the heading if they can't see the type tabs #} +{% block main_heading %} + {% if not request.has_permission('view_types', user) %} + {{ user.username }}'s recent activity + {% endif %} +{% endblock %} {% block content %} +{% if request.has_permission('view_types', user) %} +
+ +
  • + Recent activity +
  • +
  • + Topics +
  • +
  • + Comments +
  • +
    +
    +{% endif %} -{% if merged_posts %} +{% if posts %}
      - {% for post in merged_posts if request.has_permission('view', post) %} + {% for post in posts if request.has_permission('view', post) %}
    1. {% if post is topic %} {{ render_topic_for_listing(post, show_group=True) }} @@ -27,6 +47,22 @@
    2. {% endfor %}
    + + {% if post_type and (posts.has_prev_page or posts.has_next_page) %} + + {% endif %} {% else %}

    This user hasn't made any posts

    diff --git a/tildes/tildes/views/user.py b/tildes/tildes/views/user.py index f5ced8a..c7da379 100644 --- a/tildes/tildes/views/user.py +++ b/tildes/tildes/views/user.py @@ -1,19 +1,24 @@ """Views related to a specific user.""" +from typing import List, Union + +from marshmallow.fields import String +from marshmallow.validate import OneOf from pyramid.request import Request from pyramid.view import view_config from sqlalchemy.sql.expression import desc +from webargs.pyramidparser import use_kwargs from tildes.models.comment import Comment from tildes.models.topic import Topic -from tildes.models.user import UserInviteCode - +from tildes.models.user import User, UserInviteCode +from tildes.schemas.topic_listing import TopicListingSchema -@view_config(route_name='user', renderer='user.jinja2') -def get_user(request: Request) -> dict: - """Generate the main user info page.""" - user = request.context +def _get_user_recent_activity( + request: Request, + user: User, +) -> List[Union[Comment, Topic]]: page_size = 20 # Since we don't know how many comments or topics will be needed to make @@ -54,9 +59,56 @@ def get_user(request: Request) -> dict: ) merged_posts = merged_posts[:page_size] + return merged_posts + + +@view_config(route_name='user', renderer='user.jinja2') +@use_kwargs(TopicListingSchema(only=('after', 'before', 'per_page'))) +@use_kwargs({ + 'post_type': String( + load_from='type', + validate=OneOf(('topic', 'comment')), + ), +}) +def get_user( + request: Request, + after: str, + before: str, + per_page: int, + post_type: str = None, +) -> dict: + """Generate the main user history page.""" + user = request.context + + if not request.has_permission('view_types', user): + post_type = None + + if post_type: + if post_type == 'topic': + query = request.query(Topic).filter(Topic.user == user) + elif post_type == 'comment': + query = request.query(Comment).filter(Comment.user == user) + + if before: + query = query.before_id36(before) + + if after: + query = query.after_id36(after) + + query = query.join_all_relationships() + + # include removed posts if the user's looking at their own page + if user == request.user: + query = query.include_removed() + + posts = query.get_page(per_page) + else: + posts = _get_user_recent_activity(request, user) + return { 'user': user, - 'merged_posts': merged_posts, + 'posts': posts, + 'post_type': post_type, }