import re import logging import urllib.parse from django.conf import settings from pingcap_sso.discourse.models import ( DiscourseBookmark, DiscourseUser, DiscourseTopic, DiscourseUserBadge, DiscourseBadge, DiscourseUserAction, DiscoursePost, DiscourseGroupUser, DiscourseTopicCustomField, ) logger = logging.getLogger(__name__) def is_topic_exists(topic_id): return DiscourseTopic.objects.filter( id=topic_id, deleted_by_id__isnull=True, user_id__gte=1 ).exclude(archetype='private_message').exists() def is_topic_solved(topic_id): return DiscourseTopicCustomField.objects.filter( name='accepted_answer_post_id', topic_id=topic_id, value__isnull=False, ).exists() def _get_asktug_user(user): if not user: return None from pingcap_sso.models import User if isinstance(user, DiscourseUser): pass elif isinstance(user, User): user = user.get_asktug_user(log_error_if_not_exists=False) else: raise Exception('user must be DiscourseUser or User') return user def user_summary(user): user = _get_asktug_user(user) if not user: return user_stat = user.discourseuserstat bookmark_count = DiscourseBookmark.objects.filter(user=user).count() solved_count = DiscourseUserAction.objects.filter( user=user, action_type=DiscourseUserAction.ACTION_SOLVED ).count() summary = { 'topic_count': user_stat.topic_count, 'post_count': user_stat.post_count, 'days_visited': user_stat.days_visited, 'topics_entered': user_stat.topics_entered, 'posts_read_count': user_stat.posts_read_count, 'likes_given': user_stat.likes_given, 'likes_received': user_stat.likes_received, 'solved_count': solved_count, 'bookmark_count': bookmark_count } return summary def badge_list(user): user = _get_asktug_user(user) if user: awarded = DiscourseUserBadge.objects.filter(user=user) else: awarded = DiscourseUserBadge.objects.none() awarded_badges = awarded.values_list('badge_id', flat=True) badges = [] for b in DiscourseBadge.objects.filter(enabled=True).values( 'id', 'name', 'image_upload__url', 'icon'): badges.append({ 'id': b['id'], 'name': b['name'], 'image_url': b['image_upload__url'] and f'{settings.DISCOURSE_ENDPOINT_PREFIX}{b["image_upload__url"]}', 'icon': b['icon'], 'has_badge': True if b['id'] in awarded_badges else False }) return sorted(badges, key=lambda k: k['has_badge'], reverse=True) def extract_tidb_version_from_topic(topic): from pingcap_sso.models import TiDBRelease tidb_versions = list( map( lambda s: s.split('v', 2)[1], TiDBRelease.objects.filter( major_number__gte=3 ).values_list('version', flat=True) ) ) max_major_version = max(map(lambda v: v.split('.')[0], tidb_versions)) version = extract_tidb_version_from_text( topic.title, tidb_versions, max_major_version) if not version: question = DiscoursePost.objects.get(post_number=1, topic=topic) version = extract_tidb_version_from_text( question.raw, tidb_versions, max_major_version) return version def extract_tidb_version_from_text(text, tidb_versions=None, max_major_version=6): if not tidb_versions: from pingcap_sso.models import TiDBRelease tidb_versions = list( map( lambda s: s.split('v', 2)[1], TiDBRelease.objects.all().values_list('version', flat=True) ) ) version = None find = set(re.findall(r"[^\.](?P[2-{max_major_version}]\.\d+\.\d+)[^\.]*".format( max_major_version=max_major_version, ), text, re.IGNORECASE)) MYSQL_VERSION = '5.7.25' if MYSQL_VERSION in find: find.remove(MYSQL_VERSION) if len(find) == 1: find = find.pop() if find in tidb_versions: version = find return version