Ejemplo n.º 1
0
    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()

            ManageLogModel.add_by_credit_changed_sys(get_bytes_from_blob(self.id), credit, self.credit, note='每日签到')
            ManageLogModel.add_by_exp_changed_sys(get_bytes_from_blob(self.id), exp, self.exp, note='每日签到')

            return {
                'credit': 5,
                'exp': 5,
                'time': self.last_check_in_time,
                'check_in_his': self.check_in_his
            }
Ejemplo n.º 2
0
Archivo: user.py Proyecto: EleComb/slim
    def _auth_base(self, password_text):
        """
        已获取了用户对象,进行密码校验
        :param password_text:
        :return:
        """
        dk = hashlib.pbkdf2_hmac(config.PASSWORD_HASH_FUNC_NAME,
                                 password_text.encode('utf-8'),
                                 get_bytes_from_blob(self.salt),
                                 config.PASSWORD_HASH_ITERATIONS)

        if get_bytes_from_blob(self.password) == get_bytes_from_blob(dk):
            return self
Ejemplo n.º 3
0
def check_is_me(ability, user, action, record: DataRecord,
                available_columns: list):
    # 拒绝其他人写入自己的个人资料
    if user:
        if record.get('id') != get_bytes_from_blob(user.id):
            available_columns.clear()
    return True
Ejemplo n.º 4
0
 def __repr__(self):
     if isinstance(self.id, (bytes, memoryview)):
         return '<User id:%x nickname:%r>' % (int.from_bytes(get_bytes_from_blob(self.id), 'big'), self.nickname)
     elif isinstance(self.id, int):
         return '<User id:%d nickname:%r>' % (self.id, self.nickname)
     else:
         return '<User id:%s nickname:%r>' % (self.id, self.nickname)
Ejemplo n.º 5
0
    def get_post_title_by_list(cls, *lst) -> Dict[bytes, str]:
        """
        :param lst: [[related_type, related_id], ...]
        :return:
        """
        ret = {}
        info = {}
        for related_type, related_id in lst:
            info.setdefault(related_type, [])
            info[related_type].append(related_id)

        for related_type, id_lst in info.items():
            m = cls.get_model(related_type)
            fields = [
                m._meta.primary_key,
            ]

            # 获取标题列
            title_field = cls.TITLE_FIELD.get(related_type)
            if title_field:
                fields.append(getattr(m, title_field))

            # 按分类分别执行查询
            for i in m.select(*fields).where(m.id.in_(id_lst)):
                ret[get_bytes_from_blob(i.id)] = i.get_title()

        return ret
Ejemplo n.º 6
0
 def get_main_page_article(cls):
     try:
         return cls.select().where(cls.flag == 2).get()
     except cls.DoesNotExist:
         a = cls.insert(time=int(time.time()), user_id=None, flag=2, title="主页面",
                        content=DEFAULT_WIKI_CONTENT, ref=None).execute()
         post_stats_new(POST_TYPES.WIKI, get_bytes_from_blob(a))
         return cls.get(cls.id == a)
Ejemplo n.º 7
0
    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()
            ManageLogModel.add_by_exp_changed_sys(get_bytes_from_blob(self.id), exp, self.exp, note='每日登录')
            return {'exp': 5}
Ejemplo n.º 8
0
    def _to_dict(self):
        data = {}
        fields = self.val._meta.fields
        for name, v in model_to_dict(self.val, recurse=False).items():
            if isinstance(fields[name], peewee.ForeignKeyField):
                name = name + '_id'
            elif isinstance(fields[name], peewee.BlobField):
                v = get_bytes_from_blob(v)
            if self.selected != ALL_COLUMNS and (self.selected and
                                                 (name not in self.selected)):
                continue
            data[name] = v

        if self.available_columns != ALL_COLUMNS:
            return dict_filter(data, self.available_columns)

        return data
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
def ignore_hide_board(ability: Ability, user, query: 'SQLQueryInfo'):
    roles = {ability.role} if not user else set(user.roles)
    if roles & {'superuser', 'admin'}:
        return

    if roles & {'inactive_user', 'user', 'wiki_editor'}:
        visible_limit = POST_VISIBLE.ADMIN_ONLY
    else:
        visible_limit = POST_VISIBLE.USER_ONLY

    # TODO: 以后这种请求加cache
    ignored_board_ids = [
        get_bytes_from_blob(x.id) for x in Board.select(Board.id).where(~(
            (Board.state > POST_STATE.APPLY)
            & (Board.visible > POST_VISIBLE.HIDE)
            & (Board.visible < visible_limit)))
    ]

    query.add_condition('board_id', SQL_OP.NOT_IN, ignored_board_ids)
Ejemplo n.º 11
0
    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)[
                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'])
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
def check_is_users_post(ability, user, action, record: DataRecord,
                        available_columns: Set):
    if user:
        if record.get('user_id') != get_bytes_from_blob(user.id):
            available_columns.clear()
    return True
Ejemplo n.º 14
0
 def __repr__(self):
     return '<User id:%x nickname:%r>' % (int.from_bytes(
         get_bytes_from_blob(self.id), 'big'), self.nickname)
Ejemplo n.º 15
0
async def same_user(view: BaseView) -> Union[bytes, None]:
    if view.current_user:
        return get_bytes_from_blob(view.current_user.id)

    view.finish(RETCODE.PERMISSION_DENIED)
Ejemplo n.º 16
0
 def get_token(self):
     return get_bytes_from_blob(self.id)
Ejemplo n.º 17
0
    async def create_user(self, password, email=None, phone=None) -> User:
        values = {}
        nprefix = config.USER_NICKNAME_AUTO_PREFIX + '_'

        if config.POST_ID_GENERATOR != config.AutoGenerator:
            # 若不使用数据库生成id
            uid = User.gen_id()
            values['id'] = uid.to_bin()
            values['nickname'] = nprefix + uid.to_hex()

        values['is_new_user'] = True
        values['change_nickname_chance'] = 1

        if email:
            values['email'] = email.lower()

        if phone:
            values['phone'] = phone

        # 密码
        ret = User.gen_password_and_salt(password)
        values.update(ret)

        values['group'] = USER_GROUP.NORMAL
        values['state'] = POST_STATE.NORMAL

        # 注册IP地址
        values['ip_registered'] = await get_fuzz_ip(self)

        # 生成 access_token
        values.update(User.gen_key())
        values['time'] = int(time.time())

        try:
            uid = User.insert(values).execute()
            u = User.get_by_pk(uid)
        except peewee.IntegrityError as e:
            db.rollback()
            if e.args[0].startswith('duplicate key'):
                return self.finish(RETCODE.ALREADY_EXISTS)
            return self.finish(RETCODE.FAILED)
        except peewee.DatabaseError:
            db.rollback()
            return self.finish(RETCODE.FAILED)

        times = 3
        success = False
        u.nickname = nprefix + to_hex(get_bytes_from_blob(u.id))

        # 尝试填充用户名
        while times >= 0:
            try:
                if u.number == 1:
                    u.group = USER_GROUP.ADMIN
                u.save()
                success = True
                break
            except peewee.DatabaseError:
                db.rollback()
                times -= 1
                u.nickname = nprefix + to_hex(os.urandom(8))

        if not success:
            return self.finish(RETCODE.FAILED)

        # 清理现场
        if email:
            await User.reg_code_cleanup(email)

        # 添加统计记录
        post_stats_new(POST_TYPES.USER, u.id)
        UserNotifLastInfo.new(u.id)

        return u
Ejemplo n.º 18
0
Archivo: user.py Proyecto: EleComb/slim
def func(ability: Ability, user, query: 'SQLQueryInfo'):
    for i in query.conditions.find('id'):
        if i[1] == SQL_OP.EQ and i[2] == get_bytes_from_blob(user.id):
            query.select.add('email')
            query.select.add('token_time')