async def before_insert(self, values_lst: List[SQLValuesToWrite]): for values in values_lst: relate_type = values.get('related_type', None) if not (relate_type and relate_type in POST_TYPES.values()): return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") try: cid = config.POST_ID_GENERATOR(values['related_id']) post = POST_TYPES.get_post(relate_type, cid) if not post: return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") if relate_type == POST_TYPES.TOPIC: if post.state == POST_STATE.CLOSE: return self.finish(RETCODE.INVALID_POSTDATA, "无法评论指定内容") elif post.visible in (POST_VISIBLE.HIDE, ): return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") except TypeError: return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") if 'content' not in values or not values['content']: return self.finish(RETCODE.INVALID_POSTDATA, "评论内容不能为空") if 'reply_to_cmt_id' in values: try: rtid = config.POST_ID_GENERATOR(values['reply_to_cmt_id']) except TypeError: return self.finish(RETCODE.INVALID_POSTDATA, "指定被回复的内容不存在") c: Comment = Comment.get_by_pk(rtid.to_bin()) if not c: return self.finish(RETCODE.INVALID_POSTDATA, "指定被回复的内容不存在") if c.related_id != post.id: return self.finish(RETCODE.INVALID_POSTDATA, "指定被回复的内容不存在") values['reply_to_cmt_id'] = rtid.to_bin() if not isinstance(config.LONG_ID_GENERATOR, config.SQLSerialGenerator): values['id'] = config.LONG_ID_GENERATOR().to_bin() values['related_id'] = cid.to_bin() values['related_type'] = int(values['related_type']) values['user_id'] = self.current_user.id values['time'] = int(time.time()) values['content'], self.do_mentions = check_content_mention( values['content']) if relate_type == POST_TYPES.TOPIC: post: Topic await post.weight_inc()
async def info(self): """ 一些后端信息,一般是首次打开页面时获得 :return: """ extra = { 'midnight_time': get_today_start_timestamp() } # 每日首次访问奖励 if self.current_user: daily_reward = self.current_user.daily_access_reward() if daily_reward: extra['daily_reward'] = { 'exp': daily_reward } self.finish(RETCODE.SUCCESS, { 'extra': extra, 'POST_TYPES': POST_TYPES.to_dict(), 'POST_TYPES_TXT': POST_TYPES.txt, 'POST_STATE': POST_STATE.to_dict(), 'POST_STATE_TXT': POST_STATE.txt, 'POST_VISIBLE': POST_VISIBLE.to_dict(), 'POST_VISIBLE_TXT': POST_VISIBLE.txt, 'MANAGE_OPERATION': MANAGE_OPERATION.to_dict(), 'MANAGE_OPERATION_TXT': MANAGE_OPERATION.txt, 'USER_GROUP': USER_GROUP.to_dict(), 'USER_GROUP_TXT': USER_GROUP.txt, 'USER_GROUP_TO_ROLE': USER_GROUP.GROUP_TO_ROLE, 'NOTIF_TYPE': NOTIF_TYPE.to_dict(), 'BACKEND_CONFIG': { 'USER_SECURE_AUTH_ENABLE': config.USER_SECURE_AUTH_ENABLE, 'USER_SECURE_AUTH_FRONTEND_SALT': config.USER_SECURE_AUTH_FRONTEND_SALT, 'USER_NICKNAME_MIN': config.USER_NICKNAME_MIN, 'USER_NICKNAME_MAX': config.USER_NICKNAME_MAX, 'USER_NICKNAME_CN_FOR_REG_MIN': config.USER_NICKNAME_CN_FOR_REG_MIN, 'USER_NICKNAME_FOR_REG_MIN': config.USER_NICKNAME_FOR_REG_MIN, 'USER_NICKNAME_FOR_REG_MAX': config.USER_NICKNAME_FOR_REG_MAX, 'USER_PASSWORD_MIN': config.USER_PASSWORD_MIN, 'USER_PASSWORD_MAX': config.USER_PASSWORD_MAX, 'TOPIC_TITLE_LENGTH_MIN': config.TOPIC_TITLE_LENGTH_MIN, 'TOPIC_TITLE_LENGTH_MAX': config.TOPIC_TITLE_LENGTH_MAX, 'TOPIC_CONTENT_LENGTH_MAX': config.TOPIC_CONTENT_LENGTH_MAX, 'UPLOAD_STATIC_HOST': config.UPLOAD_STATIC_HOST, 'UPLOAD_QINIU_DEADLINE_OFFSET': config.UPLOAD_QINIU_DEADLINE_OFFSET, }, 'retcode': RETCODE.to_dict(), 'retinfo_cn': RETCODE.txt_cn, })
async def after_insert(self, raw_post: Dict, values: SQLValuesToWrite, record: DataRecord): post_stats_do_comment(record['related_type'], record['related_id'], record['id']) post_number = Comment.select().where( Comment.related_id == record['related_id'], Comment.id <= record['id']).count() Comment.update(post_number=post_number).where( Comment.id == record['id']).execute() if self.do_mentions: # 创建提醒 loc = [record['related_type'], record['related_id']] # record['related_id']: memoryview loc_title = POST_TYPES.get_post_title_by_list(loc)[ record['related_id'].tobytes()] related = [POST_TYPES.COMMENT, record['id']] self.do_mentions(record['user_id'], loc_title, loc, related)
def es_update_comment(id): post: CommentModel = CommentModel.get_by_id(id) if not post: return u: UserModel = UserModel.get_by_id(post.user_id) if not u: return p = POST_TYPES.get_post(post.related_type, post.related_id) body = get_post_base_body(post) body.update({ 'user_nickname': u.nickname, 'content': post.content, 'brief': post.content[:100], 'related_title': p.get_title() if p else None, 'related_type': post.related_type, 'related_id': to_hex(post.related_id) }) es.index(index=INDEX_NAME, doc_type="doc", id=to_hex(post.id), body=body)
async def after_insert(self, values_lst: List[SQLValuesToWrite], records: List[DataRecord]): for record in records: post_stats_do_comment(record['related_type'], record['related_id'], record['id']) post_number = Comment.select().where( Comment.related_id == record['related_id'], Comment.id <= record['id']).count() Comment.update(post_number=post_number).where( Comment.id == record['id']).execute() if self.do_mentions: # 创建提醒 loc = [record['related_type'], record['related_id']] # record['related_id']: memoryview loc_title = POST_TYPES.get_post_title_by_list(loc)[ get_bytes_from_blob(record['related_id'])] related = [POST_TYPES.COMMENT, record['id']] self.do_mentions(record['user_id'], loc_title, loc, related) if config.SEARCH_ENABLE: run_in_thread(esdb.es_update_comment, record['id'])
async def info(self): """ 一些后端信息,一般是首次打开页面时获得 :return: """ results = { 'POST_TYPES': POST_TYPES.to_dict(), 'POST_TYPES_TXT': POST_TYPES.txt, 'POST_STATE': POST_STATE.to_dict(), 'POST_STATE_TXT': POST_STATE.txt, 'POST_VISIBLE': POST_VISIBLE.to_dict(), 'POST_VISIBLE_TXT': POST_VISIBLE.txt, 'MANAGE_OPERATION': MANAGE_OPERATION.to_dict(), 'MANAGE_OPERATION_TXT': MANAGE_OPERATION.txt, 'USER_GROUP': USER_GROUP.to_dict(), 'USER_GROUP_TXT': USER_GROUP.txt, 'USER_GROUP_TO_ROLE': USER_GROUP.GROUP_TO_ROLE, 'NOTIF_TYPE': NOTIF_TYPE.to_dict(), 'BACKEND_CONFIG': { 'SITE_NAME': config.SITE_NAME, 'SITE_LOGO_TEXT': config.SITE_LOGO_TEXT, 'SITE_TITLE_TEXT': config.SITE_TITLE_TEXT, 'SITE_URL': config.SITE_URL, 'SITE_CONTACT_EMAIL': config.SITE_CONTACT_EMAIL, 'ABOUT_PAGE_ENABLE': config.ABOUT_PAGE_ENABLE, 'ABOUT_CUSTOM_HTML': config.ABOUT_CUSTOM_HTML, 'SIGNUP_LICENSE_HTML': config.SIGNUP_LICENSE_HTML, 'FOOTER_EXTRA_HTML': config.FOOTER_EXTRA_HTML, 'USER_SECURE_AUTH_FRONTEND_SALT': config.USER_SECURE_AUTH_FRONTEND_SALT, 'WIKI_ENABLE': config.WIKI_ENABLE, 'SEARCH_ENABLE': config.SEARCH_ENABLE, 'USER_NICKNAME_MIN': config.USER_NICKNAME_MIN, 'USER_NICKNAME_MAX': config.USER_NICKNAME_MAX, 'USER_NICKNAME_CN_FOR_REG_MIN': config.USER_NICKNAME_CN_FOR_REG_MIN, 'USER_NICKNAME_FOR_REG_MIN': config.USER_NICKNAME_FOR_REG_MIN, 'USER_NICKNAME_FOR_REG_MAX': config.USER_NICKNAME_FOR_REG_MAX, 'USER_PASSWORD_MIN': config.USER_PASSWORD_MIN, 'USER_PASSWORD_MAX': config.USER_PASSWORD_MAX, 'TOPIC_TITLE_LENGTH_MIN': config.TOPIC_TITLE_LENGTH_MIN, 'TOPIC_TITLE_LENGTH_MAX': config.TOPIC_TITLE_LENGTH_MAX, 'TOPIC_CONTENT_LENGTH_MAX': config.TOPIC_CONTENT_LENGTH_MAX, 'EMAIL_ACTIVATION_ENABLE': config.EMAIL_ACTIVATION_ENABLE, 'UPLOAD_ENABLE': config.UPLOAD_ENABLE, 'UPLOAD_BACKEND': config.UPLOAD_BACKEND, 'UPLOAD_STATIC_HOST': config.UPLOAD_STATIC_HOST, 'UPLOAD_QINIU_DEADLINE_OFFSET': config.UPLOAD_QINIU_DEADLINE_OFFSET, 'UPLOAD_QINIU_IMAGE_STYLE_TOPIC': config.UPLOAD_QINIU_IMAGE_STYLE_TOPIC, }, 'retcode': RETCODE.to_dict(), 'retinfo_cn': RETCODE.txt_cn, 'extra': { 'midnight_time': get_today_start_timestamp() } } # 每日首次访问奖励 if self.current_user: user = self.current_user results['user'] = { 'id': to_hex(user.id), 'daily_reward': user.daily_access_reward() } self.finish(RETCODE.SUCCESS, results)
def fetch_notif_of_log(user_id, last_manage_log_id=b'\x00'): from model.manage_log import ManageLog, MOP if last_manage_log_id is None: last_manage_log_id = b'\x00' item_lst = ManageLog.select().where( ManageLog.related_user_id == user_id, ManageLog.id > last_manage_log_id, ManageLog.operation.in_( (MOP.POST_STATE_CHANGE, MOP.USER_PASSWORD_CHANGE, MOP.USER_PASSWORD_RESET, MOP.USER_KEY_RESET, MOP.USER_GROUP_CHANGE, MOP.USER_CREDIT_CHANGE, MOP.USER_REPUTE_CHANGE, MOP.USER_NICKNAME_CHANGE, MOP.TOPIC_BOARD_MOVE, MOP.TOPIC_AWESOME_CHANGE, MOP.TOPIC_STICKY_WEIGHT_CHANGE) ) ).order_by(ManageLog.id.desc()) moves = [] def wrap(item: ManageLog): # 总不能把MANAGE_OPERATION的内容换个号码,抄一遍写在上面。 # 因此选择过滤掉一些,其他全部归为一类。 if item.operation == MOP.USER_CREDIT_CHANGE: if item.note == '每日签到': # 签到得分忽略 return elif item.operation == MOP.USER_EXP_CHANGE: if item.note == '每日登录': # 签到得分忽略 return if item.operation == MOP.TOPIC_BOARD_MOVE: moves.append([POST_TYPES.BOARD, to_bin(item.value['change'][0])]) moves.append([POST_TYPES.BOARD, to_bin(item.value['change'][1])]) return { 'type': NOTIF_TYPE.MANAGE_INFO_ABOUT_ME, 'time': item.time, 'loc_post_type': item.related_type, 'loc_post_id': item.related_id, 'loc_post_title': None, 'sender_ids': (item.user_id,), 'receiver_id': user_id, 'from_post_type': None, # 来源为managelog,但并非post 'from_post_id': item.id, 'related_type': item.related_type, # 提醒类型较为特殊 'related_id': item.related_id, 'data': { 'op': item.operation, 'role': item.role, 'value': item.value, 'title': None # 进行二次填充 } } ret_items = list(filter(lambda x: x, map(wrap, item_lst))) info = POST_TYPES.get_post_title_by_list(*[[i['related_type'], i['related_id']] for i in ret_items]) info2 = POST_TYPES.get_post_title_by_list(*moves) for i in ret_items: t = info.get(get_bytes_from_blob(i['related_id']), None) if t: i['data']['title'] = t if i['related_type'] == POST_TYPES.COMMENT: # 这里不是批量,可能要付出较大代价 c: Comment = Comment.get_by_id(i['related_id']) if not c: continue p = POST_TYPES.get_post(c.related_type, c.related_id) if not p: continue i['loc_post_type'] = c.related_type i['loc_post_id'] = c.related_id i['loc_post_title'] = p.get_title() i['data']['comment'] = { 'related_type': c.related_type, 'related_id': c.related_id, 'related_title': p.get_title(), 'post_number': c.post_number, 'content': c.content } if i['data']['op'] == MOP.TOPIC_BOARD_MOVE: val = i['data']['value']['change'] i['data']['move_info'] = [ info2.get(to_bin(val[0]), None), info2.get(to_bin(val[1]), None) ] return ret_items