#!/usr/bin/env python # -*- coding: utf-8 -*- from gm_types.gaia import VOTEOBJECT from django.utils import timezone from talos.libs.datetime_utils import get_timestamp_or_none from talos.models.diary import Diary, DiaryVote from talos.models.topic import TopicVote, TopicReplyVote from qa.portal import ( get_unread_answer_vote_num_by_user_id, get_unread_answer_reply_vote_num_by_user_id, get_answer_vote_infos_by_ids, ) from talos.models.tractate import TractateReplyVote, Tractate, TractateVote class VoteTool(object): """vote tool for user. add vote info into ssdb, if user's topic/diary received new vote. """ def __init__(self, redis_c, user_id, new_version=False): self.user_id = user_id self.redis_c = redis_c self._diary_vote_key_prefix = 'd:' self._topic_vote_key_prefix = 't:' self._tractate_vote_key_prefix = 'tv:' # 新帖子点赞 self._tractate_reply_vote_key_prefix = 'trv:' # 新帖子回复点赞 self._soft_article_vote_key_prefix = 'sv:' #医生后台帖子点赞 self._soft_article_reply_vote_key_prefix = 'srv:' #医生后台帖子回复点赞 self._answer_vote_key_prefix = 'a:' self._answer_reply_vote_key_prefix = 'ar:' self._topic_reply_vote_key_prefix = 'tr:' if not new_version: self._vote_key_prefix_format = 'user:{user_id}:votes:received' else: self._vote_key_prefix_format = 'user:{user_id}:votes:received:v1' self._k = self._vote_key_prefix_format.format(user_id=user_id) def _cache_this(self, k, vote_time): if not vote_time: vote_time = timezone.now() score = get_timestamp_or_none(vote_time) self.redis_c.zadd(self._k, score, k) def receive_diary_vote(self, diaryvote_id, vote_time=None): v = self._diary_vote_key_prefix v = v + str(diaryvote_id) self._cache_this(v, vote_time=vote_time) def receive_topic_vote(self, topicvote_id, vote_time=None): v = self._topic_vote_key_prefix v = v + str(topicvote_id) self._cache_this(v, vote_time=vote_time) def receive_tractate_vote(self, tractate_vote_id, vote_time=None): v = self._tractate_vote_key_prefix v = v + str(tractate_vote_id) self._cache_this(v, vote_time=vote_time) def receive_tractate_reply_vote(self, reply_vote_id, vote_time=None): v = self._tractate_reply_vote_key_prefix v = v + str(reply_vote_id) self._cache_this(v, vote_time=vote_time) def receive_soft_article_vote(self, soft_article_vote_id, vote_time=None): v = self._soft_article_vote_key_prefix v = v + str(soft_article_vote_id) self._cache_this(v, vote_time=vote_time) def receive_soft_article_reply_vote(self, reply_vote_id, vote_time=None): v = self._soft_article_reply_vote_key_prefix v = v + str(reply_vote_id) self._cache_this(v, vote_time=vote_time) def receive_answer_vote(self, answer_id, vote_time=None): v = self._answer_vote_key_prefix v = v + str(answer_id) self._cache_this(v, vote_time=vote_time) def remove_answer_vote(self, answer_id): v = self._answer_vote_key_prefix + str(answer_id) self._del_cache(v) def receive_answer_reply_vote(self, reply_id, vote_time=None): v = self._answer_reply_vote_key_prefix + str(reply_id) self._cache_this(v, vote_time=vote_time) def receive_topic_reply_vote(self, topicreplyvote_id, vote_time=None): v = self._topic_reply_vote_key_prefix v = v + str(topicreplyvote_id) self._cache_this(v, vote_time=vote_time) def get_votes_received(self, start_num=0, count=10): """return list of tuple as [(id, type), ]""" result = self.redis_c.zrevrange(self._k, start_num, start_num + count - 1) if not result: return [] res = [] for r in result: t, v = r.decode("utf-8").split(':') # 数据类型,byte -> str t += ':' # hmmm,,, if t == self._diary_vote_key_prefix: res.append((v, VOTEOBJECT.DIARY)) elif t == self._topic_vote_key_prefix: res.append((v, VOTEOBJECT.TOPIC)) elif t == self._answer_vote_key_prefix: res.append((v, VOTEOBJECT.ANSWER)) elif t == self._answer_reply_vote_key_prefix: res.append((v, VOTEOBJECT.ANSWER_REPLY)) elif t == self._topic_reply_vote_key_prefix: res.append((v, VOTEOBJECT.TOPIC_REPLY)) elif t == self._tractate_vote_key_prefix: res.append((v, VOTEOBJECT.TRACTATE)) elif t == self._tractate_reply_vote_key_prefix: res.append((v, VOTEOBJECT.TRACTATE_REPLY)) elif t == self._soft_article_reply_vote_key_prefix: # 新增医生短文评论点赞类型 res.append((v, VOTEOBJECT.DOCTOR_ARTICLE_REPLY)) return res def get_vote_count(self): return self.redis_c.zcard(self._k) def _del_cache(self, v): self.redis_c.zrem(self._k, v) def remove_tractate_vote(self, tractate_vote_id): v = self._tractate_vote_key_prefix + str(tractate_vote_id) self._del_cache(v) def remove_tractate_reply_vote(self, tractate_reply_id): v = self._tractate_reply_vote_key_prefix + str(tractate_reply_id) self._del_cache(v) def remove_soft_article_vote(self, soft_article_vote_id): v = self._soft_article_vote_key_prefix + str(soft_article_vote_id) self._del_cache(v) def remove_soft_article_reply_vote(self, soft_article_reply_vote_id): v = self._soft_article_reply_vote_key_prefix + str(soft_article_reply_vote_id) self._del_cache(v) def get_unread_vote_num_by_user_id(user_id, add_answer=False): """ 通过user_id 获取当前用户未读得点赞总数 :param user_id: 当前用户id :param add_answer: 是否增加回答的未读点赞数 :return: int count """ count = 0 if not user_id: return count unread_num = TopicVote.objects.filter( topic_author_id=user_id, unread=True ).count() count += unread_num my_diaries = Diary.objects.filter(user_id=user_id) if my_diaries: unread_num = DiaryVote.objects.filter( diary_id__in=my_diaries, unread=True ).count() count += unread_num topic_reply_unread_num = TopicReplyVote.objects.filter( topic_reply__user_id=user_id, unread=True ).count() count += topic_reply_unread_num tra_ids = list(Tractate.objects.filter(user_id=user_id, is_online=True).values_list('id', flat=True)) if tra_ids: tractate_vote_unread_num = TractateVote.objects.filter( tractate_id__in=tra_ids, is_read=False, is_online=True).count() tractate_reply_vote_unread_num = TractateReplyVote.objects.filter( tractate_id__in=tra_ids, is_read=False, is_online=True).count() else: tractate_vote_unread_num = 0 tractate_reply_vote_unread_num = 0 count += tractate_vote_unread_num count += tractate_reply_vote_unread_num if add_answer: answer_num = get_unread_answer_vote_num_by_user_id(user_id) count += answer_num answer_reply_num = get_unread_answer_reply_vote_num_by_user_id(user_id) count += answer_reply_num return count def get_user_unread_vote_count(user_id): """ 通过user_id 获取当前用户的未读数 :param user_id: :return: """ if not user_id: return 0 count = get_unread_vote_num_by_user_id(user_id, add_answer=True) return count def get_answer_vote_info_by_ids(vote_ids): answer_vote_infos = get_answer_vote_infos_by_ids(vote_ids) return answer_vote_infos def get_answer_vote_info_by_id(vote_id): """ 注意字典 key 数据类型 :param vote_id: 回答点赞的id int 类型 :return: {} 字典类型 """ vote_info = get_answer_vote_info_by_ids([vote_id]) return vote_info and vote_info.get(str(vote_id), {}) or {}