def handle(self, *args, **options): self.stdout.write('Start updating\n') redis_client = redis.Redis(host=settings.REDIS_HOST, port=6379, db=0) self.stdout.write('Update uiset\n') uis = User_Item.objects.all() for ui in uis: key = 'uiset_' + str(ui.user_id) # set of item_ids that a user shares/fav redis_client.sadd(key, ui.item_id) self.stdout.write('Update itset\n') its = Item_Topic.objects.all() for it in its: key = 'itset_topic_' + str(it.topic_id) # set of item_ids that belongs to a topic redis_client.sadd(key, it.item_id) key2 = 'itset_item_' + str(it.item_id) # set of topic_ids that are tags of a item redis_client.zadd(key2, it.topic_id, 1) self.stdout.write('Update item_count for topics\n') t_count_dict = {} it_topic_keys = redis_client.keys(pattern='itset_topic_*') for key in it_topic_keys: topic_id = key.lstrip('itset_topic_') try: topic = Topic.objects.get(pk=topic_id) topic.item_count = redis_client.scard(key) topic.save() t_count_dict[topic_id] = topic.item_count except: continue #This only works for topics that user followed #uts = User_Topic.objects.all() #for ut in uts: # common_set = redis_client.sinter('uiset_' + str(ut.user_id), 'itset_topic_' + str(ut.topic_id)) # ut.item_count = len(common_set) # ut.save() self.stdout.write('Update item_count for user_topic\n') users = Profile.objects.filter(share_count__gt=0) for u in users: print u.pk followed = User_Topic.objects.filter(user=u.pk, followed=True) uiset = redis_client.smembers('uiset_'+ str(u.pk)) source_dict = dict([('itset_item_'+x,1) for x in uiset]) redis_client.zunionstore('topic_dict_'+str(u.pk), source_dict) topic_dict = dict(redis_client.zrevrange('topic_dict_'+str(u.pk), 0, -1, withscores=True, score_cast_func=int)) redis_client.delete('topic_dict_'+str(u.pk)) if len(topic_dict) == 0: continue for ut in followed: str_t = str(ut.topic_id) if str_t in topic_dict: ut.item_count = topic_dict[str_t] ut.normalized_score = ut.item_count*1.0 / (t_count_dict.get(str_t, 1)+10) ut.save() del topic_dict[str_t] quota = 50 - len(followed) if quota < 0: #User has expressed enough interest, no need to suggest more, just ignore this one continue normalize_topic_dict = {} for k in topic_dict: normalize_topic_dict[k] = topic_dict[k]*1.0 / (t_count_dict.get(k, 1)+10) nts = sorted(normalize_topic_dict.iteritems(), key=operator.itemgetter(1), reverse=True) nts = dict(nts[:quota]) rts_d = {} for k in nts: rts_d[k] = topic_dict[k] not_followed = User_Topic.objects.filter(user=u.pk, followed=False) for nf in not_followed: if not str(nf.topic_id) in rts_d: nf.delete() else: nf.item_count = rts_d[str(nf.topic_id)] nf.normalized_score = nts[str(nf.topic_id)] nf.save() del rts_d[str(nf.topic_id)] #save the user_topics never saved before for t in rts_d: if rts_d[t] < 3: #not a signification indicator continue ut = User_Topic(followed = False, item_count = rts_d[t], normalized_score = nts[t]) ut.user_id = u.pk ut.topic_id = int(t) ut.save() self.stdout.write('Update item_count for topics and clean up\n') #Clean up all the keys ui_keys = redis_client.keys(pattern='uiset_*') redis_client.delete(*tuple(ui_keys)) redis_client.delete(*tuple(it_topic_keys)) it_item_keys = redis_client.keys(pattern='itset_item_*') redis_client.delete(*tuple(it_item_keys)) self.stdout.write('Finished updating\n')
def add_topic_action(user_id, topic_id=0, topic_name='', comment=''): """ Used by add_topic(indirecly used by add_item_topic) and add_topic_parent; either topic_id or topic_name is passed. if topic_id is passed, revert deleting this topic; \ if topic_name is passed, add this topic. Return: #. Success: return_value['topic_id'] (long type) #. Failed: return_value['error_message'] (string) """ return_value = {} return_value['error_message'] = '' if not topic_id and not topic_name.strip(): return '话题名不能为空' if topic_name: #Get the topic by name since 1,the topic is deleted and not shown in query suggestion; #2,Ajax is too slow to show it topic_set = Topic.objects.filter(name=topic_name) if topic_set: topic = topic_set[0] else: topic = None else: topic = Topic.objects.get(pk=topic_id) if topic: if topic.locked: return_value['error_message'] = '此话题已被锁定,只有管理员可以更改' return return_value elif topic.deleted: #undelete the topic topic.deleted = False topic.save() item_topic_set = Item_Topic.objects.filter(topic__id=topic.pk) if item_topic_set: for item_topic in item_topic_set: item_topic.topic_deleted = False item_topic.save() topic_parent_set = Topic_Parent.objects.filter(parent__id=topic.pk) if topic_parent_set: for topic_parent in topic_parent_set: topic_parent.parent_deleted = False topic_parent.save() refs = Topic_Revision.objects.filter(topic__id=topic.pk, operation='d').order_by('-pk') if refs: reference = refs[0] if reference.user_id != user_id: notification = Notification(operation='a') notification.user_id = reference.user_id notification.related_user_id = user_id notification.topic_id = topic.pk notification.incr_count_in_profile() notification.save() update_user_topic_fame(topic_id, user_id, reference.user_id) else: reference = None update_user_topic_fame(topic_id, user_id) topic_revision = Topic_Revision(operation='a', reference=reference, comment=comment) topic_revision.topic_id = topic.pk topic_revision.user_id = user_id topic_revision.save() return_value['topic_id'] = topic.pk return return_value else: return_value['error_message'] = '此话题已存在' return return_value elif topic_name: #The topic name does not exist, add brand new topic if len(topic_name) > 25: #Each Chinese character only counts 1 here return_value['error_message'] = '话题名字过长' return return_value topic_with_alias_set = Topic_Alias.objects.filter(alias=topic_name) if topic_with_alias_set: topic_with_alias = topic_with_alias_set[0] return_value['error_message'] = '此话题已作为话题' + topic_with_alias.topic.name.encode('utf-8') + '的别名存在' return return_value if SensitiveWord.objects.filter(name=topic_name, disabled=False): return_value['error_message'] = '根据当地法律,此话题不能被添加' return return_value topic = Topic(name=topic_name) #Automatically detects whether the language is in ASCII, if not, set to be Chinese #TODO:Need to add ability of detecting more languages is_English = True for char in topic_name: if ord(char) >= 128: is_English = False break if is_English: topic.language = 'en' else: topic.language = 'zh' topic.creator_id = user_id topic.follower_count = 1 #creator automatically follows this topic topic.save() user_topic = User_Topic() user_topic.user_id = user_id user_topic.topic_id = topic.pk user_topic.save() update_user_topic_fame(topic.pk, user_id) topic_revision = Topic_Revision(operation='a') topic_revision.topic_id = topic.pk topic_revision.user_id = user_id topic_revision.save() return_value['topic_id'] = topic.pk return return_value else: #The passed in value is topic_id but it does not exist return_value['error_message'] = '此话题不存在,不能重新添加' return return_value