def refresh(cls, user_id, cooldown=config.NOTIF_FETCH_COOLDOWN): new = [] r: UserNotifRecord = UserNotifRecord.get_by_pk(user_id) if not r: return if cooldown and (time.time() - r.update_time < cooldown): return for i in r.get_notifications(True): if i['type'] == NOTIF_TYPE.BE_COMMENTED: new.append({ 'id': config.LONG_ID_GENERATOR().to_bin(), 'sender_ids': (i['comment']['user']['id'], ), 'receiver_id': user_id, 'type': NOTIF_TYPE.BE_COMMENTED, 'time': i['time'], 'data': i, }) elif i['type'] == NOTIF_TYPE.BE_REPLIED: new.append({ 'id': config.LONG_ID_GENERATOR().to_bin(), 'sender_ids': (i['comment']['user']['id'], ), 'receiver_id': user_id, 'type': NOTIF_TYPE.BE_REPLIED, 'time': i['time'], 'data': i, }) if new: cls.insert_many(new).execute() return len(new)
def do_mentions(sender_id, loc_title, location, related, data=None): """ :param sender_id: :param loc_title: 地点标题 :param location: [post_type, post_id] 形式,指向事件发生的主要地点,例如文章中的评论里@,主要地点是文章 :param related: [post_type, post_id] 形式,指向事件发生的准确地点,例如文章中的评论里@,主要地点是评论 :param data: :return: """ items = [] t = int(time.time()) for i in mentioned_users.values(): i: User if i.id == sender_id: continue items.append({ 'id': config.LONG_ID_GENERATOR().to_bin(), 'user_id': sender_id, 'time': t, 'who': i.id, 'loc_post_type': location[0], 'loc_post_id': location[1], 'loc_post_title': loc_title, 'related_type': related[0], 'related_id': related[1], 'data': data, }) if not items: return Mention.insert_many(items).execute()
def append_post_id(cls, values): """ 若有ID生成器,那么向values中添加生成出的值,若生成器为SQL Serial,则什么都不做 :param values: :return: """ if config.LONG_ID_GENERATOR != config.SQLSerialGenerator: values['id'] = config.LONG_ID_GENERATOR().to_bin()
async def tick(self): """ 定时轮询 :return: """ data = {} now = int(time.time()) if self.current_user: user = self.current_user # 检查未读信息 r = Notification.refresh(user.id) c = Notification.count(user.id) data['notif_count'] = c # 更新在线时间 await redis.zadd(RK_USER_ACTIVE_TIME_ZSET, now, get_bytes_from_blob(user.id)) else: # TODO: 后面再给auid加几个随机数 auid = self.params.get('auid', None) if auid: try: auid = config.LONG_ID_GENERATOR(auid) if not await redis.zscore(RK_USER_ANON_ACTIVE_TIME_ZSET, auid.to_bin()): auid = None except TypeError: auid = None if not auid: new_id = config.LONG_ID_GENERATOR() await redis.zadd(RK_USER_ANON_ACTIVE_TIME_ZSET, now, new_id.to_bin()) data['auid'] = new_id.to_hex() else: await redis.zadd(RK_USER_ANON_ACTIVE_TIME_ZSET, now, auid.to_bin()) offset = 30 data['online'] = await redis.zcount(RK_USER_ACTIVE_TIME_ZSET, min=now - offset) + \ await redis.zcount(RK_USER_ANON_ACTIVE_TIME_ZSET, min=now - offset) self.finish(RETCODE.SUCCESS, data)
def pack_notif(i: Dict): i.update({'id': config.LONG_ID_GENERATOR().to_bin()}) # 注意,insert_many 要求所有列一致,因此不能出现有的数据独有a列,有的数据独有b列 # 要都有才行,因此全部进行默认填充 i.setdefault('related_type', None) i.setdefault('related_id', None) i.setdefault('brief', None) i.setdefault('data', None) return i
def pack_notif(i, sender_ids): # 看得出来初始设计是想要一定程度上合并同类消息,还没来得及搞,先这样吧 return { 'id': config.LONG_ID_GENERATOR().to_bin(), 'sender_ids': sender_ids, 'receiver_id': user_id, 'type': i['type'], 'time': i['time'], 'data': i, }
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()
def new(cls, user_id, role, related_type, related_id, related_user_id, operation, value, note=None): return cls.create( id=config.LONG_ID_GENERATOR().digest(), user_id=user_id, role=role, time=int(time.time()), related_type=related_type, related_id=related_id, related_user_id=related_user_id, operation=operation, value=value, note=note )
def new(cls, user_id, key, size, ext=None, type_name=None, image_info=None): # 之所以有key的情况下还有独立id,是因为上传是一个一对多的过程,多个用户可能上传同一张图片,那么key就相同 return cls.create(id=config.LONG_ID_GENERATOR().digest(), time=int(time.time()), user_id=user_id, key=key, size=int(size), ext=ext, type_name=type_name, image_info=image_info)
def do_mentions(sender_id, related_type, related_id, data): items = [] t = int(time.time()) for i in mentioned_users.values(): i: User if i.id == sender_id: continue items.append({ 'id': config.LONG_ID_GENERATOR().to_bin(), 'user_id': sender_id, 'time': t, 'who': i.id, 'related_id': related_id, 'related_type': related_type, 'data': data, }) if not items: return Mention.insert_many(items).execute()
def get_model_id(): return config.LONG_ID_GENERATOR().to_bin()
async def get_user_data(self): code = self.params print(code) code = code['code'] if code == 'undefined': self.finish(RETCODE.FAILED) return otoken, _ = await self.github.get_access_token(code) github = GithubClient( client_id=config.CLIENT_ID, client_secret=config.CLIENT_SECRET, access_token=otoken, ) response = await github.request('GET', 'user') # response = json.loads(response) if response['id']: try: account = UserOAuth.get(UserOAuth.login_id == response['id'], UserOAuth.platform == 'github') except UserOAuth.DoesNotExist: account = None if account: if account.user_id: # 返回用户已有信息 u = UserModel.get_by_pk(account.user_id) if u: expires = 30 u.refresh_key() self.setup_user_key(u.key, expires) self.finish( RETCODE.SUCCESS, { 'oauthcode': 0, 'user_id': account.user_id, 'state': account.state, 'access_token': u.key }) else: self.finish( RETCODE.SUCCESS, { 'oauthcode': 1, 'state': account.state, 'oauth_id': account.id, 'login_id': account.login_id, 'platform': account.platform }) else: ins = [{ 'login_id': response['id'], 'time': time.time(), 'platform': 'github', 'state': POST_STATE.APPLY }] if not isinstance(config.LONG_ID_GENERATOR, config.SQLSerialGenerator): ins[0]['id'] = config.LONG_ID_GENERATOR().to_bin() UserOAuth.insert_many(ins).execute() self.finish( RETCODE.SUCCESS, { 'oauthcode': 1, 'oauth_id': ins[0]['id'], 'state': ins[0]['state'], 'login_id': ins[0]['login_id'], 'platform': ins[0]['platform'] }) else: self.finish(RETCODE.NOT_FOUND)