예제 #1
0
파일: views.py 프로젝트: eiritana/canvas
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]}
예제 #2
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])
예제 #4
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])
예제 #5
0
파일: api.py 프로젝트: StetHD/canvas-2
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}
예제 #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}
예제 #7
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 []
예제 #8
0
파일: models.py 프로젝트: eiritana/canvas
 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)
예제 #9
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,
    }
    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])
예제 #11
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
예제 #12
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])
    ]
    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)
예제 #14
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
예제 #15
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
예제 #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)
예제 #17
0
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
예제 #18
0
파일: api.py 프로젝트: StetHD/canvas-2
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}
예제 #19
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
예제 #20
0
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)
예제 #21
0
파일: views.py 프로젝트: eiritana/canvas
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)
예제 #22
0
파일: api.py 프로젝트: eiritana/canvas
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}
예제 #23
0
파일: views.py 프로젝트: StetHD/canvas-2
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)
예제 #24
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,
    }
예제 #25
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,
    }
예제 #26
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 []
예제 #27
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,
    }
예제 #28
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
 def test_empty_multicall_returns_empty_results(self):
     self.assertEquals([], CachedCall.multicall([]))
 def from_ids(cls, user_ids):
     from drawquest.apps.drawquest_auth.models import User
     return CachedCall.multicall([User.details_by_id(user_id, promoter=cls)
                                  for user_id in user_ids])
예제 #31
0
 def get_cached(archived_quests):
     return CachedCall.multicall([archived.quest.details for archived in archived_quests])
 def from_ids(cls, user_ids):
     from drawquest.apps.drawquest_auth.models import User
     return CachedCall.multicall([
         User.details_by_id(user_id, promoter=cls) for user_id in user_ids
     ])
예제 #33
0
파일: models.py 프로젝트: eiritana/canvas
 def get_from_comment(cls, comment):
     (post, ) = CachedCall.multicall([comment.details])
     return cls(comment.details().to_client())
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])]
예제 #35
0
 def get_from_comment(cls, comment):
     (post,) = CachedCall.multicall([comment.details])
     return cls(comment.details().to_client())
예제 #36
0
 def test_empty_multicall_returns_empty_results(self):
     self.assertEquals([], CachedCall.multicall([]))
예제 #37
0
파일: models.py 프로젝트: StetHD/canvas-2
 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)
예제 #38
0
파일: models.py 프로젝트: StetHD/canvas-2
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
예제 #39
0
파일: models.py 프로젝트: StetHD/canvas-2
 def comments_details(self):
     cmts = QuestComment.objects.filter(parent_comment=self).order_by('-id')
     return CachedCall.multicall([cmt.details for cmt in cmts])
예제 #40
0
 def comments_details(self):
     cmts = QuestComment.objects.filter(parent_comment=self).order_by('-id')
     return CachedCall.multicall([cmt.details for cmt in cmts])