def after_update(self, raw_post: Dict, values: SQLValuesToWrite, old_records: List[DataRecord], records: List[DataRecord]): for old_record, record in zip(old_records, records): # 管理日志:修改评论状态 ManageLog.add_by_post_changed(self, 'state', MOP.POST_STATE_CHANGE, POST_TYPES.COMMENT, values, old_record, record)
async def change_nickname(self): u = self.current_user if not u: return self.finish(RETCODE.PERMISSION_DENIED) post = await self.post_data() form = NicknameForm(**post) if not form.validate(): return self.finish(RETCODE.INVALID_POSTDATA, form.errors) if u.change_nickname_chance > 0: try: old_nickname = u.nickname u.nickname = form['nickname'].data u.change_nickname_chance -= 1 u.is_new_user = False u.save() self.finish( RETCODE.SUCCESS, { 'nickname': u.nickname, 'change_nickname_chance': u.change_nickname_chance }) # note: 虽然有点奇怪,但下面这句其实没问题 18.11.13 ManageLog.add_by_post_changed(self, 'nickname', MOP.USER_NICKNAME_CHANGE, POST_TYPES.USER, True, {'nickname': old_nickname}, u) return except peewee.DatabaseError: db.rollback() self.finish(RETCODE.FAILED)
async def change_nickname(self): u: User = self.current_user if not u: return self.finish(RETCODE.PERMISSION_DENIED) vpost: ChangeNicknameDataModel = self._.validated_post if u.change_nickname_chance > 0: try: old_nickname = u.nickname u.nickname = vpost.nickname u.change_nickname_chance -= 1 u.is_new_user = False u.save() self.finish( RETCODE.SUCCESS, { 'nickname': u.nickname, 'change_nickname_chance': u.change_nickname_chance }) # note: 虽然有点奇怪,但下面这句其实没问题 18.11.13 ManageLog.add_by_post_changed(self, 'nickname', MOP.USER_NICKNAME_CHANGE, POST_TYPES.USER, True, {'nickname': old_nickname}, u) return except peewee.DatabaseError: db.rollback() self.finish(RETCODE.FAILED)
def after_update(self, raw_post: Dict, values: SQLValuesToWrite, old_records: List[DataRecord], records: List[DataRecord]): for old_record, record in zip(old_records, records): manage_try_add = lambda column, op: ManageLog.add_by_post_changed( self, column, op, POST_TYPES.WIKI, values, old_record, record) manage_try_add_with_diff = lambda column, op: ManageLog.add_by_post_changed( self, column, op, POST_TYPES.WIKI, values, old_record, record, diff_func=diff) title_changed = manage_try_add('title', MOP.POST_TITLE_CHANGE) # 管理日志:标题编辑 content_changed = manage_try_add_with_diff( 'content', MOP.POST_CONTENT_CHANGE) # 管理日志:正文编辑 if title_changed or content_changed: post_stats_do_edit(record['id'], record['user_id']) manage_try_add('ref', MOP.WIKI_REF_CHANGE) # 管理日志:链接编辑 manage_try_add('state', MOP.POST_STATE_CHANGE) # 管理日志:改变状态 manage_try_add('visible', MOP.POST_VISIBLE_CHANGE) # 管理日志:改变可见度 if config.SEARCH_ENABLE: run_in_thread(esdb.es_update_wiki, record['id'])
def check_in(self): self.last_check_in_time = self.last_check_in_time or 0 old_time = self.last_check_in_time last_midnight = get_today_start_timestamp() # 今日未签到 if self.last_check_in_time < last_midnight: self.last_check_in_time = int(time.time()) # 三天内有签到,连击 if old_time > last_midnight - config.USER_CHECKIN_COUNTER_INTERVAL: self.check_in_his += 1 else: self.check_in_his = 1 self.save() # 签到加分 credit = self.credit exp = self.exp self.credit += 5 self.exp += 5 self.save() ManageLog.add_by_credit_changed_sys(self.id.tobytes(), credit, self.credit, note='每日签到') ManageLog.add_by_exp_changed_sys(self.id.tobytes(), exp, self.exp, note='每日签到') return { 'credit': 5, 'exp': 5, 'time': self.last_check_in_time, 'check_in_his': self.check_in_his }
def after_update(self, raw_post: Dict, values: SQLValuesToWrite, old_records: List[DataRecord], records: List[DataRecord]): for old_record, record in zip(old_records, records): manage_try_add = lambda column, op: ManageLog.add_by_post_changed( self, column, op, POST_TYPES.USER, values, old_record, record ) # 管理日志:重置访问令牌 ManageLog.add_by_post_changed(self, 'key', MOP.USER_KEY_RESET, POST_TYPES.USER, values, old_record, record, value=None) # 管理日志:重置密码 ManageLog.add_by_post_changed(self, 'password', MOP.USER_PASSWORD_CHANGE, POST_TYPES.USER, values, old_record, record, value=None) manage_try_add('state', MOP.POST_STATE_CHANGE) manage_try_add('visible', MOP.POST_VISIBLE_CHANGE) manage_try_add('group', MOP.USER_GROUP_CHANGE) manage_try_add('exp', MOP.USER_EXP_CHANGE) def manage_try_add_resource(column, op): if column not in values: return uid = self.current_user.id src = json.loads(raw_post['$src']) # TODO: 检查一下是否真的存在 def func(info): info['related_type'] = src['type'] info['related_id'] = to_bin(src['id']) info['related_user_id'] = uid ManageLog.add_by_post_changed(self, column, op, POST_TYPES.USER, values, old_record, record, cb=func) manage_try_add_resource('credit', MOP.USER_CREDIT_CHANGE) manage_try_add_resource('repute', MOP.USER_REPUTE_CHANGE)
async def after_insert(self, raw_post: Dict, values: SQLValuesToWrite, record: DataRecord): # 添加统计记录 post_stats_new(POST_TYPES.BOARD, record['id']) # 管理日志:新建板块 ManageLog.post_new(self, POST_TYPES.BOARD, record)
def after_update(self, raw_post: Dict, values: SQLValuesToWrite, old_records: List[DataRecord], records: List[DataRecord]): for old_record, record in zip(old_records, records): manage_try_add = lambda column, op: ManageLog.add_by_post_changed( self, column, op, POST_TYPES.TOPIC, values, old_record, record ) manage_try_add_with_diff = lambda column, op: ManageLog.add_by_post_changed( self, column, op, POST_TYPES.TOPIC, values, old_record, record, diff_func=diff ) title_changed = manage_try_add('title', MOP.POST_TITLE_CHANGE) # 管理日志:标题编辑 content_changed = manage_try_add_with_diff('content', MOP.POST_CONTENT_CHANGE) # 管理日志:正文编辑 if title_changed or content_changed: post_stats_do_edit(record['id'], record['user_id']) Topic.update(edit_count=Topic.edit_count + 1).where(Topic.id == record['id']).execute() manage_try_add('state', MOP.POST_STATE_CHANGE) # 管理日志:状态修改 manage_try_add('visible', MOP.POST_VISIBLE_CHANGE) # 管理日志:改变可见度 manage_try_add('awesome', MOP.TOPIC_AWESOME_CHANGE) # 管理日志:设置精华 manage_try_add('sticky_weight', MOP.TOPIC_STICKY_WEIGHT_CHANGE) # 管理日志:置顶权重 manage_try_add('weight', MOP.TOPIC_WEIGHT_CHANGE) # 管理日志:修改权重 # 管理日志:移动板块 if manage_try_add('board_id', MOP.TOPIC_BOARD_MOVE): post_stats_topic_move(old_record['board_id'], record['board_id'], record['id'])
async def after_insert(self, values_lst: List[SQLValuesToWrite], records: List[DataRecord]): for record in records: # 添加统计记录 post_stats_new(POST_TYPES.BOARD, record['id']) # 管理日志:新建板块 ManageLog.post_new(self, POST_TYPES.BOARD, record)
async def after_insert(self, raw_post: Dict, values: SQLValuesToWrite, record: DataRecord): # 添加统计记录 post_stats_new(POST_TYPES.WIKI, record['id']) # 添加创建记录 ManageLog.post_new(self, POST_TYPES.WIKI, record) if config.SEARCH_ENABLE: run_in_thread(esdb.es_update_wiki, record['id'])
async def after_insert(self, values_lst: List[SQLValuesToWrite], records: List[DataRecord]): for record in records: # 添加统计记录 post_stats_new(POST_TYPES.WIKI, record['id']) # 添加创建记录 ManageLog.post_new(self, POST_TYPES.WIKI, record) if config.SEARCH_ENABLE: run_in_thread(esdb.es_update_wiki, record['id'])
def after_update(self, raw_post: Dict, values: SQLValuesToWrite, old_records: List[DataRecord], records: List[DataRecord]): for old_record, record in zip(old_records, records): # 管理日志:修改评论状态 ManageLog.add_by_post_changed(self, 'state', MOP.POST_STATE_CHANGE, POST_TYPES.COMMENT, values, old_record, record) if config.SEARCH_ENABLE: run_in_thread(esdb.es_update_comment, record['id'])
def daily_access_reward(self): self.access_time = self.access_time or 0 old_time = self.access_time self.update_access_time() if old_time < get_today_start_timestamp(): exp = self.exp self.exp += 5 self.save() ManageLog.add_by_exp_changed_sys(self.id.tobytes(), exp, self.exp, note='每日登录') return {'exp': 5}
def manage_try_add_resource(column, op): if column not in values: return uid = self.current_user.id src = json.loads(raw_post['$src']) # TODO: 检查一下是否真的存在 def func(info): info['related_type'] = src['type'] info['related_id'] = to_bin(src['id']) info['related_user_id'] = uid ManageLog.add_by_post_changed(self, column, op, POST_TYPES.USER, values, old_record, record, cb=func)
def after_update(self, raw_post: Dict, values: SQLValuesToWrite, old_records: List[DataRecord], records: List[DataRecord]): for old_record, record in zip(old_records, records): # 注:此处记录不考虑可写不可读的情况。代码比较丑陋,后面改吧 o = old_record.to_dict() n = record.to_dict() to_remove = set() for k, v in n.items(): if k in o and o[k] == v: to_remove.add(k) for k, v in o.items(): if k in n and n[k] == v: to_remove.add(k) for k in to_remove: del o[k] del n[k] # 管理日志 ManageLog.new(self.current_user, self.current_role, POST_TYPES.BOARD, record['id'], record['user_id'], MOP.BOARD_INFO_CHANGE, [o, n])
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
def work(): sql_execute('drop table "wiki_history";') sql_execute('drop table "wiki_item";') sql_execute('drop table "wiki_article";') sql_execute('drop table "statistic24h";') sql_execute('drop table "statistic24h_log";') sql_execute('ALTER TABLE statistic RENAME TO post_stats;') sql_execute('ALTER TABLE post_stats ADD edit_count int DEFAULT 0 NULL;') sql_execute('ALTER TABLE post_stats DROP viewed_users;') sql_execute('ALTER TABLE post_stats DROP edited_users;') sql_execute('ALTER TABLE post_stats DROP commented_users;') sql_execute('ALTER TABLE post_stats DROP bookmarked_users;') sql_execute('ALTER TABLE post_stats DROP upvoted_users;') sql_execute('ALTER TABLE post_stats DROP downvoted_users;') sql_execute('ALTER TABLE post_stats DROP thanked_users;') sql_execute( 'ALTER TABLE post_stats ADD last_edit_time bigint DEFAULT NULL NULL;') sql_execute( 'ALTER TABLE post_stats ADD last_edit_user_id BYTEA DEFAULT NULL NULL;' ) sql_execute( 'CREATE INDEX post_stats_last_edit_time_index ON post_stats (last_edit_time);' ) sql_execute( 'ALTER TABLE post_stats ADD update_time bigint DEFAULT NULL NULL;') sql_execute('CREATE INDEX update_time_index ON post_stats (update_time);') sql_execute( r"ALTER TABLE user_notif_last_info ADD last_manage_log_id bytea DEFAULT '\x00' NULL;" ) sql_execute('ALTER TABLE notif ALTER COLUMN from_post_type DROP NOT NULL;') sql_execute('ALTER TABLE notif ALTER COLUMN from_post_id DROP NOT NULL;') sql_execute( 'ALTER TABLE "user" ADD is_wiki_editor BOOLEAN DEFAULT FALSE NOT NULL;' ) sql_execute( 'ALTER TABLE "user" ADD is_board_moderator BOOLEAN DEFAULT FALSE NOT NULL;' ) sql_execute( 'ALTER TABLE "user" ADD is_forum_master BOOLEAN DEFAULT FALSE NOT NULL;' ) sql_execute( 'CREATE INDEX user_is_wiki_editor_index ON "user" (is_wiki_editor);') sql_execute( 'CREATE INDEX user_is_board_moderator_index ON "user" (is_board_moderator);' ) sql_execute( 'CREATE INDEX user_is_forum_master_index ON "user" (is_forum_master);') # 移除 MOP.TOPIC_TITLE_CHANGE 300 ManageLog.update(operation=MOP.POST_TITLE_CHANGE).where( ManageLog.operation == 300).execute() # 移除 MOP.TOPIC_CONTENT_CHANGE 301 ManageLog.update(operation=MOP.POST_CONTENT_CHANGE).where( ManageLog.operation == 301).execute() # 移除 MOP.COMMENT_STATE_CHANGE 500 ManageLog.update(operation=MOP.POST_STATE_CHANGE).where( ManageLog.operation == 500).execute() # BOARD_NEW 200 for i in ManageLog.select().where(ManageLog.operation == 200): i.operation = MOP.POST_CREATE i.value = {'title': i.value} i.save() for i in ManageLog.select(): if i and i.value: if i.operation == MOP.POST_CREATE: # wiki 改动 if not isinstance(i.value, dict): i.value = {'title': i.value} i.save() elif isinstance(i.value, list): i.value = {'change': i.value} i.save() elif isinstance(i.value, dict): pass else: if i.operation == MOP.POST_CONTENT_CHANGE: i.value = {'change': i.value} i.save()