Example #1
0
def posts(request, payload={}, short_id=None):
    """
    Posts endpoint of the example.com public api

    Request with an id parameter:

        /public_api/posts/1qkx8

    POST JSON in the following format:

        POST /public_api/posts/
        {"ids":["1qkx8","ma6fz"]}
    """
    Metrics.api_comment.record(request)
    ids = payload.get('ids')

    if short_id and not ids:
        try:
            comment = Comment.details_by_id(long_id(short_id), promoter=PublicAPICommentDetails)
            (comment,) = CachedCall.multicall([comment])
            return comment.to_client()
        except (ObjectDoesNotExist, util.Base36DecodeException):
            raise ServiceError("Post not found")

    elif ids:
        ids = [long_id(x) for x in set(ids)]
        calls = [Comment.details_by_id(id, ignore_not_found=True, promoter=PublicAPICommentDetails) for id in ids]
        comments = CachedCall.multicall(calls, skip_decorator=True)
        return {'posts': [x.to_client() for x in comments if x]}
    def _make_activities(self, activity_ids, earlier_than=None, later_than=None):
        from apps.activity.models import Activity, LegacyActivity

        def filter_by_ts(query):
            if earlier_than is not None:
                query = query.filter(timestamp__lt=earlier_than)

            if later_than is not None:
                query = query.filter(timestamp__gt=later_than)

            return query

        activity_ids = [int(id_) for id_ in activity_ids]

        activities = Activity.objects.filter(id__in=activity_ids).order_by('-timestamp')
        activities = filter_by_ts(activities)
        activities = CachedCall.queryset_details(activities)

        if len(activities) < len(activity_ids):
            legacy_ids = set(activity_ids) - set(int(activity['id']) for activity in activities)
            legacy_activities = LegacyActivity.objects.filter(id__in=legacy_ids).order_by('-timestamp')
            legacy_activities = filter_by_ts(legacy_activities)
            legacy_activities = CachedCall.queryset_details(legacy_activities)
            activities.extend(legacy_activities)

        ret = []

        for activity_data in activities:
            try:
                ret.append(self._activity_types[activity_data['activity_type']](activity_data))
            except KeyError as e:
                continue

        return ret
Example #3
0
    def test_two_cachedcalls_with_same_key_use_same_cache(self):
        fun = CB(retvalue='bar')
        cc1 = CachedCall('qix', fun)
        cc2 = CachedCall('qix', fun)

        self.assertEqual(cc1(), cc2())
        self.assertEqual(1, fun.called)
Example #4
0
    def test_force_returns_new_value(self):
        fun = CB(retvalue=1)
        cc = CachedCall('key', fun)
        cc()

        fun.retvalue = 2
        self.assertEqual(2, cc.force())
 def test_force_returns_new_value(self):
     fun = CB(retvalue=1)
     cc = CachedCall('key', fun)
     cc()
     
     fun.retvalue = 2
     self.assertEqual(2, cc.force())
Example #6
0
def search_stamps(request, query, start):
    """
    Searches the special "stamps" group for stamps that match the search query.

    Returns {comments: [list of comment details]}
    """
    qs = query
    try:
        start = int(start)
    except TypeError:
        raise ServiceError('Invalid "start" parameter.')

    stamps = models.Category.objects.get(name="stamps")
    if qs:
        ids = [
            x for x in models.Comment.objects.filter(
                category=stamps).filter(Q(
                    title__icontains=qs)).values_list('id', flat=True)
        ]
        ids = ids[start:start + 32]
        comments = models.Comment.curated.exclude(
            reply_content__id=None).in_bulk(ids)
        details = CachedCall.multicall(
            [comments[id].details for id in ids if id in comments])

    else:
        comments = models.Comment.curated.filter(category=stamps).exclude(
            reply_content__id=None).order_by('-id')
        comments = comments[start:start + 32]
        details = CachedCall.queryset_details(comments)

    return {'comments': details}
Example #7
0
def search_stamps(request, query, start):
    """
    Searches the special "stamps" group for stamps that match the search query.

    Returns {comments: [list of comment details]}
    """
    qs = query
    try:
        start = int(start)
    except TypeError:
        raise ServiceError('Invalid "start" parameter.')

    stamps = models.Category.objects.get(name="stamps")
    if qs:
        ids = [x for x in models.Comment.objects.filter(category=stamps).filter(
            Q(reply_text__icontains=qs) | Q(title__icontains=qs)
        ).values_list('id', flat=True)]
        ids = ids[start:start+32]
        comments = models.Comment.curated.exclude(reply_content__id=None).in_bulk(ids)
        details = CachedCall.multicall([comments[id].details for id in ids if id in comments])

    else:
        comments = models.Comment.curated.filter(category=stamps).exclude(reply_content__id=None).order_by('-id')
        comments = comments[start:start+32]
        details = CachedCall.queryset_details(comments)

    return {'comments': details}
    def test_queryset_details(self):
        comments = [create_comment(reply_content=create_content()) for _ in xrange(10)]
        details1 = CachedCall.multicall([cmt.details for cmt in comments])

        queryset = Comment.objects.filter(id__in=[cmt.id for cmt in comments])
        details2 = CachedCall.queryset_details(queryset)

        self.assertEquals(details1, details2)
 def test_skip_decorator(self):
     def decorator(self):
         raise Exception
         
     fun = CB()
     cc = CachedCall('key', fun, decorator=decorator)
     self.assertEquals(fun.retvalue, cc(skip_decorator=True))
     self.assertEquals(fun.retvalue, cc.force(skip_decorator=True))
    def test_force_updates_cached_value(self):
        fun = CB(retvalue=1)
        cc = CachedCall('key', fun)
        cc()

        fun.retvalue = 2
        cc.force()
        self.assertEqual(2, cc())
Example #11
0
    def test_force_updates_cached_value(self):
        fun = CB(retvalue=1)
        cc = CachedCall('key', fun)
        cc()

        fun.retvalue = 2
        cc.force()
        self.assertEqual(2, cc())
Example #12
0
    def test_skip_decorator(self):
        def decorator(self):
            raise Exception

        fun = CB()
        cc = CachedCall('key', fun, decorator=decorator)
        self.assertEquals(fun.retvalue, cc(skip_decorator=True))
        self.assertEquals(fun.retvalue, cc.force(skip_decorator=True))
Example #13
0
    def test_many_multicall(self):
        f1, f2, f3, f4, f5, f6 = [
            CachedCall('key_%s' % n, CB(retvalue=n))
            for n in [1, 2, 3, 4, 5, 6]
        ]

        self.assertEquals([[1], [2, 3], [4, 5, 6]],
                          CachedCall.many_multicall([f1], [f2, f3],
                                                    [f4, f5, f6]))
Example #14
0
    def test_multicall_half_cached_returns_results(self):
        funs = [CB(retvalue=n) for n in [1, 2, 3, 4, 5]]
        calls = [CachedCall("key_%s" % e, fun) for e, fun in enumerate(funs)]

        # Uncached
        self.assertEquals([1, 2, 3], CachedCall.multicall(calls[:3]))

        # Half cached
        self.assertEquals([1, 2, 3, 4, 5], CachedCall.multicall(calls))
        self.assertEquals([1] * len(funs), [fun.called for fun in funs])
    def test_multicall_half_cached_returns_results(self):
        funs = [CB(retvalue=n) for n in [1,2,3,4,5]]
        calls = [CachedCall("key_%s" % e, fun) for e,fun in enumerate(funs)]

        # Uncached
        self.assertEquals([1,2,3], CachedCall.multicall(calls[:3]))
        
        # Half cached
        self.assertEquals([1,2,3,4,5], CachedCall.multicall(calls))
        self.assertEquals([1] * len(funs), [fun.called for fun in funs])
Example #16
0
    def test_queryset_details(self):
        comments = [
            create_comment(reply_content=create_content()) for _ in xrange(10)
        ]
        details1 = CachedCall.multicall([cmt.details for cmt in comments])

        queryset = Comment.objects.filter(id__in=[cmt.id for cmt in comments])
        details2 = CachedCall.queryset_details(queryset)

        self.assertEquals(details1, details2)
Example #17
0
    def test_decorator(self):
        tocache = {'animals': 2}
        toadd = {'people': 3}
        decorator = lambda c: dict(c, **toadd)
        expected = dict(tocache, **toadd)

        fun = CB(retvalue=tocache)
        cc = CachedCall('key', fun, decorator=decorator)
        self.assertEquals(expected, cc())
        # Now test cached.
        cc = CachedCall('key', fun, decorator=decorator)
        self.assertEquals(expected, cc())
        self.assertEquals(1, fun.called)
Example #18
0
    def test_inprocess_cached_prevents_multiple_fetches_in_multicall(self):
        funs = [CB(retvalue=n) for n in [1, 2, 3, 4, 5]]
        calls = [CachedCall("key_%s" % e, fun) for e, fun in enumerate(funs)]

        # Uncached
        self.assertEquals([1, 2, 3], CachedCall.multicall(calls[:3]))

        # Remove some of the backing stores
        cache.delete('key_0')
        cache.delete('key_1')
        CachedCall.inprocess_cache.delete('key_2')

        # 1,2 in-process only, 3 in redis only, 4,5 uncached
        self.assertEquals([1, 2, 3, 4, 5], CachedCall.multicall(calls))
        self.assertEquals([1] * len(funs), [fun.called for fun in funs])
Example #19
0
def archived_quests():
    """ Returns quest details. """
    archived_quests = ScheduledQuest.archived(select_quests=True)
    quests = CachedCall.multicall(
        [archived.quest.details for archived in archived_quests])

    return quests
Example #20
0
def user_comments(user,
                  viewer,
                  offset='top',
                  include_ugq=True,
                  include_reactions=True):
    comments = QuestComment.by_author(user)

    if not include_ugq:
        comments = comments.filter(parent_comment__ugq=False)

    if viewer.id != user.id:
        comments = comments.exclude(visibility=Visibility.CURATED)

        if viewer.is_authenticated():
            comments = comments.exclude(flags__user=viewer)

    pagination = Paginator(comments, knobs.COMMENTS_PER_PAGE, offset=offset)

    comments = pagination.items

    promoter = None if include_reactions else QuestCommentGalleryDetails
    comments = CachedCall.queryset_details(comments, promoter=promoter)

    add_viewer_has_starred_field(comments, viewer=viewer)

    return comments, pagination
Example #21
0
def twitter_followers_on_drawquest(request, twitter_access_token,
                                   twitter_access_token_secret):
    """ Returns one field, `users`, a list of `User` dicts. """
    twitter_user = TwitterUser.get_or_create_from_access_token(
        twitter_access_token, twitter_access_token_secret)
    twitter_friends = twitter_user.followers_on_drawquest(
        twitter_access_token, twitter_access_token_secret)
    twitter_friends = list(twitter_friends.select_related('user'))

    twitter_friend_uids = dict(
        (friend.user_id, friend.twitter_uid) for friend in twitter_friends)

    users = CachedCall.multicall([
        User.details_by_id(twitter_friend.user_id)
        for twitter_friend in twitter_friends
        if twitter_friend.user_id is not None
    ])

    for user in users:
        user.twitter_uid = twitter_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #22
0
def api_monster_details(request, short_id, payload={}):
    view_data = CommentViewData(request, short_id)
    main_comment = view_data.op_comment
    replies = [Comment.details_by_id(cid) for cid in view_data.reply_ids]
    has_replies = len(replies) > 0

    (
        (main_comment,),
        replies
    ) = CachedCall.many_multicall(
        [main_comment],
        replies,
    )

    treplies = []
    made_bottom = False
    for reply in replies:
        cur = reply.to_client()
        if reply.real_author == request.user.username:
            cur['current_user_authored'] = made_bottom = True
        treplies.append(cur)

    ctx = {
        'top': main_comment,
        'bottoms': treplies,
        'current_user_made_bottom': made_bottom,
        'current_user_made_top': main_comment.real_author == request.user.username,
        'start_content': Content.all_objects.get(id=Content.SMALL_DRAW_FROM_SCRATCH_PK).details(),
    }

    return ctx
Example #23
0
 def from_ids(cls, comment_ids):
     """ Returns a list of CommentDetails instances. Does not include user pins. """
     from canvas.models import Comment
     details = [
         Comment.details_by_id(comment_id) for comment_id in comment_ids
     ]
     return CachedCall.many_multicall(details)[0]
Example #24
0
def get_suggested_tags(user):
    number_to_suggest = 3
    suggested = set(knobs.SUGGESTED_TOPICS)
    followed = set(user.redis.followed_tags[:]
                   ) | user.redis.muted_suggested_tags.smembers()
    unfollowed = suggested - followed

    # Add preview to tag
    unfollowed = [{'name': topic} for topic in unfollowed]
    topic_previews = canvas.models.Content.all_objects.filter(
        id__in=knobs.SUGGESTED_TOPIC_PREVIEWS.values())
    topic_previews = CachedCall.multicall(
        [preview.details for preview in topic_previews])
    preview_mapping = dict([(content['id'], content)
                            for content in topic_previews])
    for topic in unfollowed:
        topic['preview'] = preview_mapping.get(
            knobs.SUGGESTED_TOPIC_PREVIEWS[topic['name']])

    size = len(unfollowed)
    if size >= number_to_suggest:
        return sample(unfollowed, number_to_suggest)
    elif size > 0:
        return list(unfollowed)
    else:
        return []
    def test_inprocess_cached_prevents_multiple_fetches_in_multicall(self):
        funs = [CB(retvalue=n) for n in [1,2,3,4,5]]
        calls = [CachedCall("key_%s" % e, fun) for e,fun in enumerate(funs)]

        # Uncached
        self.assertEquals([1,2,3], CachedCall.multicall(calls[:3]))
        
        # Remove some of the backing stores
        cache.delete('key_0')
        cache.delete('key_1')
        CachedCall.inprocess_cache.delete('key_2')
        
        
        # 1,2 in-process only, 3 in redis only, 4,5 uncached
        self.assertEquals([1,2,3,4,5], CachedCall.multicall(calls))
        self.assertEquals([1] * len(funs), [fun.called for fun in funs])
Example #26
0
    def test_cache_stores_json_correctly(self):
        fun = CB(retvalue={'foo': ['bar']})
        cc = CachedCall('key', fun)

        self.assertEquals(fun.retvalue, cc())
        self.assertEquals(fun.retvalue, cc())
        self.assertEquals(1, fun.called)
Example #27
0
 def brief_replies(self):
     ids = [x for x in self.replies.values_list('id', flat=True)]
     calls = [
         Comment.details_by_id(id, promoter=BriefPublicAPICommentDetails)
         for id in ids
     ]
     return CachedCall.multicall(calls, skip_decorator=True)
Example #28
0
def gallery_comments(quest, offset='top', direction='next', force_comment=None, viewer=None,
                     include_reactions=True):
    """
    Returns comments, pagination. Each comment is itself a dict.
    """
    if force_comment is not None:
        newer_comments = QuestComment.objects.filter(parent_comment=quest, id__gt=force_comment.id).order_by('id').values_list('id', flat=True)
        try:
            offset = list(newer_comments[:knobs.COMMENTS_PER_PAGE / 2])[-1]
        except IndexError:
            offset = force_comment.id

    pagination = Paginator(_exclude_flagged(_all_gallery_comments(quest), viewer), knobs.COMMENTS_PER_PAGE, offset=offset, direction=direction)

    comments = pagination.items

    promoter = None if include_reactions else QuestCommentGalleryDetails
    comments = CachedCall.queryset_details(comments, promoter=promoter)

    add_viewer_has_starred_field(comments, viewer=viewer)

    if force_comment is not None and force_comment.id not in [cmt['id'] for cmt in comments]:
        if force_comment.visibility != Visibility.CURATED:
            raise Http404()

        comments.append(force_comment.details())
        comments = sorted(comments, key=lambda cmt: -cmt['id'])

    if viewer is not None and viewer.is_authenticated():
        following = viewer.following_ids()

        for comment in comments:
            comment.user.viewer_is_following = comment.user.id in following

    return comments, pagination
Example #29
0
    def test_second_call_returns_value_without_calling_underlying_function(
            self):
        fun = CB()
        cc = CachedCall('key', fun)
        cc()

        self.assertEquals(fun.retvalue, cc())
        self.assertEquals(1, fun.called)
Example #30
0
    def test_inprocess_cache_prevents_multiple_calls_multiple_fetch(self):
        fun = CB()
        cc = CachedCall('key', fun)
        self.assertEqual(fun.retvalue, cc())
        cache.delete('key')

        self.assertEqual(fun.retvalue, cc())
        self.assertEqual(1, fun.called)
Example #31
0
 def from_queryset(cls, comments):
     bottoms, tops = CachedCall.many_multicall([cmt.details           for cmt in comments],
                                               [cmt.thread.op.details for cmt in comments])
     tiles = []
     for bottom, top in zip(bottoms, tops):
         tile = cls(bottom, top)
         tiles.append(tile)
     return tiles
Example #32
0
def wrap_comments(comment_list, cls=None):
    """ `comment_list` must be an iterable containing Comment instances. """
    if not cls:
        cls = CommentDetails
    return [
        cls(d)
        for d in CachedCall.multicall([cmt.details for cmt in comment_list])
    ]
Example #33
0
    def get_from_comment(cls, comment):
        candidates = Comment.public.in_bulk_list([comment.id] + comment.top_replies[:10])
        candidates = [post for post in candidates if post.reply_content]
        candidates = sorted(candidates, key=lambda comment: -comment.get_score()[0])
        thread = [comment] + candidates[:5]

        (posts,) = CachedCall.many_multicall([post.details for post in thread])

        return cls(*posts)
Example #34
0
def starred_comments_gallery(user, offset='top', direction='next'):
    stars = CommentSticker.objects.filter(user=user).order_by('-timestamp')
    pagination = Paginator(stars, knobs.COMMENTS_PER_PAGE, offset=offset, direction=direction)

    comments = CachedCall.multicall([QuestComment.details_by_id(id_)
                                     for id_
                                     in pagination.items.values_list('comment_id', flat=True)])

    return comments, pagination
Example #35
0
 def from_queryset(cls, comments):
     bottoms, tops = CachedCall.many_multicall(
         [cmt.details for cmt in comments],
         [cmt.thread.op.details for cmt in comments])
     tiles = []
     for bottom, top in zip(bottoms, tops):
         tile = cls(bottom, top)
         tiles.append(tile)
     return tiles
Example #36
0
 def from_queryset_with_viewer_stickers(cls, viewer, comments):
     bottoms, tops = CachedCall.many_multicall([cmt.details           for cmt in comments],
                                               [cmt.thread.op.details for cmt in comments])
     tiles = []
     for bottom, top in zip(bottoms, tops):
         tile = cls(bottom, top)
         tile.viewer_sticker = Comment.get_sticker_from_user_for_comment_id(bottom.id, viewer)
         tiles.append(tile)
     return tiles
Example #37
0
def explore_comment_details(viewer=None):
    comments = CachedCall.multicall([
        QuestComment.details_by_id(id_, promoter=QuestCommentExploreDetails)
        for id_ in preloaded_explore_comment_ids()
    ])

    add_viewer_has_starred_field(comments, viewer=viewer)

    return comments
Example #38
0
def _profile(request, user, template='profiles/profile.html'):
    comments = QuestComment.by_author(user)

    top_comments = models.top_comments(user)

    if top_comments is None:
        comments = CachedCall.queryset_details(comments)
    else:
        comments, top_comments = CachedCall.many_queryset_details(comments, top_comments)

    follow_counts = following_models.counts(user)

    return r2r_jinja(template, {
        'target_user': user,
        'comments': comments,
        'top_comments': top_comments,
        'follower_count': follow_counts['followers'],
        'following_count': follow_counts['following'],
    }, request)
Example #39
0
 def from_queryset_with_viewer_stickers(cls, viewer, comments):
     bottoms, tops = CachedCall.many_multicall(
         [cmt.details for cmt in comments],
         [cmt.thread.op.details for cmt in comments])
     tiles = []
     for bottom, top in zip(bottoms, tops):
         tile = cls(bottom, top)
         tile.viewer_sticker = Comment.get_sticker_from_user_for_comment_id(
             bottom.id, viewer)
         tiles.append(tile)
     return tiles
Example #40
0
def staff_pick_stamps(request, page):
    page = int(page)
    page_size = 20

    b36_ids = knobs.REMIX_IMAGES_STAFF_PICKS[page*page_size:(page+1)*page_size]

    ids = [util.base36decode(b36_id) for b36_id in b36_ids]

    details = CachedCall.queryset_details(Comment.objects.in_bulk_list(ids))

    return {'comments': details}
Example #41
0
def mobile_details_from_queryset(comments):
    bottoms, tops = CachedCall.many_multicall([cmt.details           for cmt in comments],
                                              [cmt.thread.op.details for cmt in comments])
    tiles = []
    for bottom, top in zip(bottoms, tops):
        tile = {
            'top': top,
            'bottom': bottom,
        }
        tiles.append(tile)
    return tiles
Example #42
0
    def _make_activities(self,
                         activity_ids,
                         earlier_than=None,
                         later_than=None):
        from apps.activity.models import Activity, LegacyActivity

        def filter_by_ts(query):
            if earlier_than is not None:
                query = query.filter(timestamp__lt=earlier_than)

            if later_than is not None:
                query = query.filter(timestamp__gt=later_than)

            return query

        activity_ids = [int(id_) for id_ in activity_ids]

        activities = Activity.objects.filter(
            id__in=activity_ids).order_by('-timestamp')
        activities = filter_by_ts(activities)
        activities = CachedCall.queryset_details(activities)

        if len(activities) < len(activity_ids):
            legacy_ids = set(activity_ids) - set(
                int(activity['id']) for activity in activities)
            legacy_activities = LegacyActivity.objects.filter(
                id__in=legacy_ids).order_by('-timestamp')
            legacy_activities = filter_by_ts(legacy_activities)
            legacy_activities = CachedCall.queryset_details(legacy_activities)
            activities.extend(legacy_activities)

        ret = []

        for activity_data in activities:
            try:
                ret.append(self._activity_types[activity_data['activity_type']]
                           (activity_data))
            except KeyError as e:
                continue

        return ret
Example #43
0
def staff_pick_stamps(request, page):
    page = int(page)
    page_size = 20

    b36_ids = knobs.REMIX_IMAGES_STAFF_PICKS[page * page_size:(page + 1) *
                                             page_size]

    ids = [util.base36decode(b36_id) for b36_id in b36_ids]

    details = CachedCall.queryset_details(Comment.objects.in_bulk_list(ids))

    return {'comments': details}
def avatar_url(user):
    """ DO NOT CALL THIS FOR ANONYMOUS POSTS. """
    key = 'column'
    avatar, = CachedCall.multicall([
        User.avatar_by_username(user.username),
    ])
    if key in avatar:
        url = avatar[key]['name']
    else:
        key = user.id if user.is_authenticated() else 0
        url = _default_avatar_url(key)
    return url
Example #45
0
    def get_from_comment(cls, comment):
        candidates = Comment.public.in_bulk_list([comment.id] +
                                                 comment.top_replies[:10])
        candidates = [post for post in candidates if post.reply_content]
        candidates = sorted(candidates,
                            key=lambda comment: -comment.get_score()[0])
        thread = [comment] + candidates[:5]

        (posts, ) = CachedCall.many_multicall(
            [post.details for post in thread])

        return cls(*posts)
Example #46
0
def _profile(request, user, template='profiles/profile.html'):
    comments = QuestComment.by_author(user)

    top_comments = models.top_comments(user)

    if top_comments is None:
        comments = CachedCall.queryset_details(comments)
    else:
        comments, top_comments = CachedCall.many_queryset_details(
            comments, top_comments)

    follow_counts = following_models.counts(user)

    return r2r_jinja(
        template, {
            'target_user': user,
            'comments': comments,
            'top_comments': top_comments,
            'follower_count': follow_counts['followers'],
            'following_count': follow_counts['following'],
        }, request)
Example #47
0
def user_comments(request, username, page='top'):
    user = get_object_or_404(User, username=username)
    comments = QuestComment.by_author(user)

    if request.user.id != user.id:
        comments = comments.exclude(visibility=Visibility.CURATED)

    comments = comments[:knobs.COMMENTS_PER_PAGE]
    comments = CachedCall.queryset_details(comments)

    return {
        'comments': comments,
    }
Example #48
0
def ugq_by_user(user, offset='top', direction='next', viewer=None):
    quests = Quest.objects.filter(author=user, ugq=True)

    if viewer is not None and viewer.is_authenticated():
        quests = quests.exclude(flags__user=viewer)

    quests = quests.order_by('-id')

    pagination = Paginator(quests, knobs.QUESTS_PER_PAGE, offset=offset, direction=direction)
    quests = pagination.items
    quests = CachedCall.queryset_details(quests)

    return quests, pagination
Example #49
0
def user_comments(request, username, since_id=None, before_id=None):
    user = get_object_or_404(User, username=username)

    comments = QuestComment.by_author(user)

    paginator = Paginator(comments, knobs.COMMENTS_PER_PAGE, since_id=since_id, before_id=before_id)
    comments = paginator.items

    comments = CachedCall.multicall([cmt.details for cmt in comments])

    comments = filter_frozen_comments(comments)

    return {'comments': comments, 'pagination': paginator}
def _square_avatar(username, image_type, width, height):
    avatar, = CachedCall.multicall([
        User.avatar_by_username(username),
    ])
    if image_type in avatar:
        url = avatar[image_type]['name']
        size = avatar[image_type]
    else:
        key = reduce(lambda acc, x: ord(x) + acc, username, 0)
        url = _default_avatar_url(key)
        size = {'width':width, 'height':height}

    return _avatar(url, size, width, height, username)
Example #51
0
    def from_queryset_with_pins(cls, comments):
        """
        Returns a list of tile details.

        This will preload this details object with pins, which is more efficient than loading them on demand.
        """
        # Grab the pin data for this user and these comments.
        details, pins = CachedCall.many_multicall([cmt.details        for cmt in comments],
                                                  [cmt.thread.op.pins for cmt in comments])

        tiles = []
        for cmt, pins in zip(details, pins):
            tile = cls(cmt)
            tile.pins = pins
            tiles.append(tile)
        return tiles
Example #52
0
def suggested_users(request):
    user_list = []
    users = sample(SUGGESTED_USERS, 5)
    users = list(User.objects.filter(username__in=users, is_active=True))
    for user in users:
        if user.userinfo.profile_image is not None:
            avatar_comment = Comment.details_by_id(user.userinfo.profile_image.id)()
        else:
            avatar_comment = None

        is_following = False
        try:
            is_following = request.user.is_following(user)
        except AttributeError:
            pass

        user_list.append({
            'user'              : user,
            'avatar_comment'    : avatar_comment,
            'is_following'      : is_following,
            'is_self'           : request.user == user,
        })

    topics = sample(SUGGESTED_TOPICS, 5)
    topics = [{'name': topic} for topic in topics]
    topic_previews = Content.all_objects.filter(id__in=SUGGESTED_TOPIC_PREVIEWS.values())

    topic_previews = CachedCall.multicall([preview.details for preview in topic_previews])

    preview_mapping = dict([(content['id'], content) for content in topic_previews])

    try:
        followed_tags = request.user.redis.followed_tags
    except AttributeError:
        followed_tags = []

    for topic in topics:
        topic['preview'] = preview_mapping.get(SUGGESTED_TOPIC_PREVIEWS[topic['name']])
        topic['is_following'] = topic['name'] in followed_tags

    ctx = {
        'request': request,
        'users': user_list,
        'topics': topics,
    }
    return r2r_jinja('onboarding/suggested_users.html', ctx, request)
Example #53
0
def top_gallery_comments(quest, viewer=None, include_reactions=False):
    comment_ids = top_gallery_comment_ids(quest)

    comments = QuestComment.objects.filter(id__in=comment_ids).order_by('-star_count')
    comments = _exclude_flagged(comments, viewer)

    promoter = None if include_reactions else QuestCommentGalleryDetails
    comments = CachedCall.queryset_details(comments, promoter=promoter)

    add_viewer_has_starred_field(comments, viewer=viewer)

    if viewer is not None and viewer.is_authenticated():
        following = viewer.following_ids()

        for comment in comments:
            comment.user.viewer_is_following = comment.user.id in following

    return comments
Example #54
0
def twitter_followers_on_drawquest(request, twitter_access_token, twitter_access_token_secret):
    """ Returns one field, `users`, a list of `User` dicts. """
    twitter_user = TwitterUser.get_or_create_from_access_token(twitter_access_token, twitter_access_token_secret)
    twitter_friends = twitter_user.followers_on_drawquest(twitter_access_token, twitter_access_token_secret)
    twitter_friends = list(twitter_friends.select_related('user'))

    twitter_friend_uids = dict((friend.user_id, friend.twitter_uid) for friend in twitter_friends)

    users = CachedCall.multicall([User.details_by_id(twitter_friend.user_id) for twitter_friend in twitter_friends
                                  if twitter_friend.user_id is not None])

    for user in users:
        user.twitter_uid = twitter_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #55
0
def facebook_friends_on_drawquest(request, facebook_access_token):
    """ Returns one field, `users`, a list of `User` dicts. """
    fb_user = FacebookUser.get_or_create_from_access_token(facebook_access_token)
    fb_friends = fb_user.friends_on_drawquest(facebook_access_token).select_related('user')

    fb_friend_uids = dict((friend.user_id, friend.fb_uid) for friend in fb_friends)

    users = CachedCall.multicall([User.details_by_id(fb_friend.user_id) for fb_friend in fb_friends
                                  if fb_friend.user_id is not None])


    for user in users:
        user.fb_uid = fb_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #56
0
def get_suggested_tags(user):
    number_to_suggest = 3
    suggested = set(knobs.SUGGESTED_TOPICS)
    followed = set(user.redis.followed_tags[:]) | user.redis.muted_suggested_tags.smembers()
    unfollowed = suggested - followed

    # Add preview to tag
    unfollowed = [{"name": topic} for topic in unfollowed]
    topic_previews = canvas.models.Content.all_objects.filter(id__in=knobs.SUGGESTED_TOPIC_PREVIEWS.values())
    topic_previews = CachedCall.multicall([preview.details for preview in topic_previews])
    preview_mapping = dict([(content["id"], content) for content in topic_previews])
    for topic in unfollowed:
        topic["preview"] = preview_mapping.get(knobs.SUGGESTED_TOPIC_PREVIEWS[topic["name"]])

    size = len(unfollowed)
    if size >= number_to_suggest:
        return sample(unfollowed, number_to_suggest)
    elif size > 0:
        return list(unfollowed)
    else:
        return []
Example #57
0
def user_comments(user, viewer, offset="top", include_ugq=True, include_reactions=True):
    comments = QuestComment.by_author(user)

    if not include_ugq:
        comments = comments.filter(parent_comment__ugq=False)

    if viewer.id != user.id:
        comments = comments.exclude(visibility=Visibility.CURATED)

        if viewer.is_authenticated():
            comments = comments.exclude(flags__user=viewer)

    pagination = Paginator(comments, knobs.COMMENTS_PER_PAGE, offset=offset)

    comments = pagination.items

    promoter = None if include_reactions else QuestCommentGalleryDetails
    comments = CachedCall.queryset_details(comments, promoter=promoter)

    add_viewer_has_starred_field(comments, viewer=viewer)

    return comments, pagination