import math from datetime import datetime from celery.utils.log import get_task_logger from django.core.mail import send_mail from django.utils.html import strip_tags from django.template.loader import render_to_string from pingcap_sso.models import User, UserPointStat from pingcap_sso.celery import app as celery_app from pingcap_sso.discourse.models import ( DiscourseTopic, DiscourseTopicCustomField ) from pingcap_sso.discourse import api as discourse_api from pingcap_sso.utils.email import get_MX_records_by_email logger = get_task_logger(__name__) @celery_app.task def sync_user_to_discourse(external_id, username, email, name, bio): return discourse_api.sync_user_to_discourse(external_id, username, email, name, bio) WELCOME_NEWBIE_TITLE = '这是来自 TiDB 社区的一封信,请查收!' def welcome_context(user): topic_count = DiscourseTopic.objects.filter( deleted_at__isnull=True, visible=True, archetype='regular' ).count() solved_count = DiscourseTopicCustomField.objects.filter( name='accepted_answer_post_id', value__isnull=False, topic__deleted_at__isnull=True, topic__archetype='regular' ).count() return { 'username': user.username, 'user_count': User.objects.all().count() - 1, 'tidb_age': (datetime.now() - datetime.strptime('2015-04-08', '%Y-%m-%d')).days, 'topic_count': topic_count, 'solved_count': solved_count } @celery_app.task def send_welcome_email_to_newbie(user_id): user = User.objects.get(id=user_id) email_verified = user.email_verified email = user.email or user.signup_email if email and (email_verified or get_MX_records_by_email(email)): html_message = render_to_string( 'pingcap_sso/email/welcome_newbie.html', welcome_context(user) ) send_mail( WELCOME_NEWBIE_TITLE, strip_tags(html_message), None, [email], html_message=html_message ) logger.info('send welcome email to user:{}, email_address:{}'.format(user.id, email)) @celery_app.task def send_welcome_asktug_message_to_newbie(user_id): user = User.objects.get(id=user_id) asktug_message = render_to_string( 'pingcap_sso/asktug_message/welcome_newbie.md', welcome_context(user) ) return discourse_api.send_private_message( [user.username], WELCOME_NEWBIE_TITLE, asktug_message ) CONTRIBUTOR_BADGE_RULES = [ {'level': 1, 'badge_id': 131, 'min_exps': 1000, 'max_exps': 4999}, {'level': 2, 'badge_id': 132, 'min_exps': 5000, 'max_exps': 9999}, {'level': 3, 'badge_id': 133, 'min_exps': 10000, 'max_exps': 19999}, {'level': 4, 'badge_id': 134, 'min_exps': 20000, 'max_exps': float('inf')}, ] @celery_app.task def grant_community_contributor_badges_to_users(): # grant community contributor badges to users by experience # this task can be run repeatedly for rule in CONTRIBUTOR_BADGE_RULES: badge_id = rule['badge_id'] min_exps = rule['min_exps'] point_stats = UserPointStat.objects.using('default').select_related('pingcap_sso.user').all() if not math.isinf(min_exps): point_stats = point_stats.filter(experience__gte=min_exps) usernames = point_stats.values_list('user__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)