import math from celery.utils.log import get_task_logger from django.db import models from pingcap_sso.celery import app as celery_app from pingcap_sso.models import User from pingcap_sso.blog.models import Post from pingcap_sso.discourse import api as discourse_api logger = get_task_logger(__name__) BLOG_BADGE_RULES = [ {'badge_id': 156, 'min_posts': 1}, {'badge_id': 157, 'min_posts': 5}, {'badge_id': 158, 'min_posts': 20}, {'badge_id': 159, 'min_posts': 50}, ] @celery_app.task def grant_blog_badges_to_users(): for rule in BLOG_BADGE_RULES: badge_id = rule['badge_id'] min_posts = rule['min_posts'] openids = list(Post.objects.filter( status=Post.STATUS_PUBLISHED, deleted_at__isnull=True ).values_list( 'author__openid' ).annotate( cnt=models.Count('id') ).filter(cnt__gte=min_posts).values_list('author__openid', flat=True)) usernames = User.objects.filter(openid__in=openids).values_list('username', flat=True) step = 200 for i in range(math.ceil(len(usernames) / step)): sliced_usernames = usernames[i * step: (i + 1) * step] if sliced_usernames: discourse_api.grant_badge_to_users(sliced_usernames, badge_id)