#!/usr/bin/env python # -*- coding: utf-8 -*- # 问答创建 import datetime import json from gm_types.antispam import DocType from gm_types.doctor import DOCTOR_TITLE_TYPE from gm_types.error import ERROR from gm_types.gaia import ( DOCTOR_PROCESS_STATUS, CONST_STRINGS as const_strings, ) from gm_types.mimas import ( CONTENT_CLASS, MEDIA_IMAGE_URL_SOURCE, QA_CONTENT_TYPE, VIDEO_SOURCE_TYPE, COMMUNITY_CONTENT_TYPE) from communal.tasks import create_fake_task from live.tasks import get_qiniu_persistent_ids from qa.cache.manager import AnswerSortCacheManager from qa.libs import ( format_qa_content_v2, get_media_extra_info, refine_qa_content_data, get_head_image_info, ) from qa.models.answer import ( AnswerTag, Question, AnswerTagV3, AnswerAttrTagV3, ) from qa.serializers import ( AnswerSerializer, ) from qa.tasks import ( check_spam, fake_vote_to_answer, push_to_question_provider, ) from qa.utils.statistic import get_async_args_v2 from talos.logger import irrigation_logger from talos.portal import ( get_doctor_by_user_id, ) from talos.models.doctor import DoctorMessageList from utils.common import get_data_from_rich_text from utils.push import push_time_range_limit from utils.rpc import ( gen, logging_exception, ) from utils.tasks import common_push class AnswerCreateMethod(object): @staticmethod def _create_answer(user, create_data): """ 创建回答 :param user: :param create_data: {question_id:xx, content: ", images: [], platform:None or 99, tag_ids: [], "tag_v3_ids": []} :return: """ result = { "answer": {}, "doctor": None, } question_id = create_data.get("question_id", 0) content = create_data.get("content", "") _images = get_media_extra_info(create_data.get("images", [])) head_images = get_head_image_info(create_data.get("head_images", [])) tag_ids = create_data.get("tag_ids", []) tags = [{'tag': tag} for tag in tag_ids] _data = { "question": question_id, "user": user.id, "content": content, "tags": tags, 'level': create_data.get("level", CONTENT_CLASS.UNAUDITED) } platform = create_data.get("platform", None) if platform: rich_text_dic = refine_qa_content_data(content) rich_images_list = get_media_extra_info(rich_text_dic.get("images_list", [])) for item in rich_images_list: item.update({ "image_url_source": MEDIA_IMAGE_URL_SOURCE.RICH_TEXT, }) _images.extend(rich_images_list) _data.update(format_qa_content_v2(platform, content)) _images = head_images + _images _data.update({ "images": _images, "platform": platform, }) try: doctor = get_doctor_by_user_id(user.id) except IndexError: doctor = None if doctor: _data.update({ "doctor_id": doctor.id, "doctor_title": doctor.title or DOCTOR_TITLE_TYPE.EMPTY, }) result["doctor"] = doctor serializer = AnswerSerializer(data=_data) if not serializer.is_valid(raise_exception=False): gen(ERROR.CONTENT_CREATE_ERROR) serializer.save() answer_data = serializer.data answer_tag_v3s = [AnswerTagV3( answer_id=answer_data["id"], tag_v3_id=tag_v3_id ) for tag_v3_id in create_data.get("tag_v3_ids", [])] if answer_tag_v3s: AnswerTagV3.objects.bulk_create(answer_tag_v3s) if create_data.get("v3_attr_tag_ids", []): AnswerAttrTagV3.objects.bulk_create([ AnswerAttrTagV3( answer_id=answer_data["id"], attr_tag_id=attr_tag_id ) for attr_tag_id in create_data.get("v3_attr_tag_ids", [])]) result["answer"] = answer_data return result @staticmethod def various_logic_after_answer_create(answer_data, doctor): """ 回答创建后触发的逻辑 :param answer_data: :param doctor: :param user: :return: """ question_id = answer_data.get("question", 0) answer_id = answer_data.get("id", 0) if doctor: DoctorMessageList.objects.filter( question_id=question_id, doctor_id=doctor.id ).update(process_status=DOCTOR_PROCESS_STATUS.processed) if answer_data.get("content_type", "") == QA_CONTENT_TYPE.VIDEO: _, video_list = get_data_from_rich_text( answer_data.get("content", ""), u'//video[not(@name="new_video")]/@src' ) if video_list: get_qiniu_persistent_ids.delay( source_id=answer_id, video_type=VIDEO_SOURCE_TYPE.ANSWER, url_list=video_list ) @staticmethod def trigger_tasks_after_answer_reply_create(answer_data, user, **kwargs): """ 回答创建完毕,触发的各种异步任务 :param answer_data: :param user: :param tag_ids: :return: """ question_id = answer_data.get("question", 0) answer_id = answer_data.get("id", 0) tag_ids = kwargs.get("tag_ids", []) tag_v3_ids = kwargs.get("tag_v3_ids", []) answer_sort_cache_manager = AnswerSortCacheManager() answer_sort_cache_manager.calc_cache(question_id) check_spam.delay(answer_id, ['content'], DocType.ANSWER) # push to the question provider question_title = '' try: question = Question.objects.get(id=question_id) question_title = question.title if push_time_range_limit(): push_to_question_provider( user_id=question.user_id, answer_id=answer_id, question_title=question_title, user_name=user.nick_name ) except Question.DoesNotExist: logging_exception() # push to answerer fans common_push.delay( uname=user.nick_name, uid=user.id, topic_id=answer_id, push_type="answer", question_title=question_title ) # kyc 流程自动触发灌水 create_fake_task.delay( answer_id, COMMUNITY_CONTENT_TYPE.ANSWER, kwargs.get('level', CONTENT_CLASS.BAD), user.id ) @classmethod def create(cls, user, question_id, content, images, platform, tags, **kwargs): """ 创建回答 :param user: :param question_id: :param content: :param images: :param platform: :param tags: :return: """ tag_v3_ids = kwargs.get("tag_v3_ids", []) v3_attr_tag_ids = kwargs.get("v3_attr_tag_ids", []) create_data = { "question_id": question_id, "content": content, "images": images, "platform": platform, "tag_ids": tags, "head_images": kwargs.get("head_images", []), "tag_v3_ids": tag_v3_ids, "v3_attr_tag_ids": v3_attr_tag_ids, "level": kwargs.get("content_level", CONTENT_CLASS.UNAUDITED) } try: results = cls._create_answer(user, create_data) answer_data = results.get("answer", {}) cls.various_logic_after_answer_create( answer_data=answer_data, doctor=results.get("doctor", None), ) cls.trigger_tasks_after_answer_reply_create( answer_data=answer_data, user=user, tag_ids=tags, tag_v3_ids=tag_v3_ids, level=kwargs.get("content_level", CONTENT_CLASS.BAD), ) return answer_data except: logging_exception() return gen(ERROR.CONTENT_CREATE_ERROR)