コード例 #1
0
def test_get_close_db(app):
    with app.app_context():
        db = get_db()
        assert db is get_db()

    # 退出环境后, 连接应当已关闭
    with pytest.raises(sqlite3.ProgrammingError) as e:
        db.execute('SELECT 1')

    assert 'closed' in str(e.value)
コード例 #2
0
def test_say(client, app):
    assert "你必须说点什么" in send(client, 'say')
    assert "我记在脑子里啦" in send(client, 'say anything')
    with app.app_context():
        db = get_db()
        res = db.execute('select * from treehole').fetchall()
        assert len(res) != 0
コード例 #3
0
def test_log(app):
    with app.app_context():
        c = get_db()
        log = c.execute('select * from log').fetchall()
        for i in log:
            print(tuple(i))
        assert len(log) > 0
コード例 #4
0
ファイル: utils.py プロジェクト: NWUCA/zaobot
def log(context: Context):
    c = get_db()
    log_time = datetime.fromtimestamp(context.time)
    inserted_data = (context.message, context.name,
                     context.user_id, context.time, str(log_time))
    c.execute("insert into log values (?,?,?,?,?)", inserted_data)
    c.commit()
コード例 #5
0
 def unlock():
     with app.app_context():
         try:
             c = get_db()
             c.execute(
                 "update misc set value = '0' where key = 'mutex'")
             c.commit()
         except sqlite3.OperationalError:
             pass
コード例 #6
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
 def dig(self):
     """随机从树洞取一条消息"""
     c = get_db()
     length = c.execute('select count(*) from treehole').fetchone()[0]
     rand = random.randrange(length)
     secret = c.execute(
         f'select message from treehole limit 1 offset {rand}').fetchone(
         )['message']
     return reply("某个人说:" + secret, at_sender=False)
コード例 #7
0
ファイル: utils.py プロジェクト: NWUCA/zaobot
def start_xiuxian(context: Context):
    c = get_db()
    if not 0 <= datetime.fromtimestamp(context.time).time().hour < 5:
        return
    if c.execute(f'select * from xiuxian_emulator where id = {context.user_id}').fetchone() is None:
        c.execute('insert into xiuxian_emulator values (?,?,?,?,?,?)',
                  (context.user_id, context.name, 0, 0, '', ''))
        c.commit()
        send(context, f'[CQ:at,qq={context.user_id}],你已经成功筑基,一个新的世界已经对你敞开!')
        accumulate_exp(context)
コード例 #8
0
ファイル: utils.py プロジェクト: NWUCA/zaobot
def query_ky():
    c = get_db()
    data = c.execute('select * from misc where key = "ky_date"').fetchone()
    if data is None:
        return "管理员还未设定考研时间,使用 /setky 设定考研时间"
    ky_date_str = data['value']
    ky_date = date(int(ky_date_str[:4]), int(ky_date_str[4:6]), int(ky_date_str[6:]))
    days_to_ky = (ky_date - date.today()).days
    if days_to_ky in (0, -1):
        return f"{ky_date_str[:4]}年度研究生考试正在进行中"
    return f"距离{ky_date_str[:4]}年度研究生考试还有{days_to_ky}天"
コード例 #9
0
ファイル: utils.py プロジェクト: NWUCA/zaobot
def randomly_save_message_to_treehole(context: Context):
    c = get_db()
    message = re.sub(r"\[CQ:(image|at).*?]", '', context.message).strip()
    if message == "":
        return
    if random.random() < current_app.config['RANDOMLY_SAVE_TO_TREEHOLE_RATE']:
        timestamp = context.time
        readable_time = datetime.fromtimestamp(timestamp)
        c.execute("insert into treehole values (?,?,?,?,?,'random_pick')",
                  (message, timestamp, readable_time, context.name, context.user_id))
        c.commit()
コード例 #10
0
def ghs_reminder(app):
    c = get_db()
    data = c.execute(
        'select * from misc where key = "last_ghs_date"').fetchone()
    if data is None:
        return
    last_ghs_date = data['value']
    period = (date.today() - date.fromisoformat(last_ghs_date)).days
    if period > 0:
        send(GroupContext.build(group_id=app.config["GHS_NOTIFY_GROUP"]),
             message=f"提醒:距离上次 ghs 已经过去了{period}天。")
    else:
        return
コード例 #11
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
 def rest_statistic(self):
     """获取作息统计信息。"""
     c = get_db()
     rest_list = c.execute('select * from rest_record where id = ?',
                           (self.context.user_id, )).fetchall()
     valid_record = [i for i in rest_list if i['sleep_time'] != '']
     msg = average_rest_time(valid_record, 7) + \
         average_rest_time(valid_record, 30) + \
         average_rest_time(valid_record, 365)
     if msg == "":
         return reply("暂无数据。")
     else:
         return reply(msg)
コード例 #12
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
 def xiuxian_ranking(self):
     """修仙排行"""
     c = get_db()
     res = c.execute(
         'select * from xiuxian_emulator order by exp desc limit 10'
     ).fetchall()
     if len(res) == 0:
         return reply('呜呼!仙道中落,世间竟无人修仙!')
     msg = ""
     for i, person in enumerate(res):
         msg += f"{i + 1}. {person['nickname']} {xiuxian_level[person['level']][0]}期 " \
                f"经验{person['exp']}/{xiuxian_level[person['level']][1]}\n"
     return reply(msg, at_sender=False)
コード例 #13
0
def test_randomly_save_message_to_treehole(app):
    # we don't use HTTP client because it's too slow
    from bot.utils import randomly_save_message_to_treehole
    from bot.context import GroupContext
    data = data_generator('foobar', auto_prefix_slash=False)
    context = GroupContext(data)

    with app.app_context():
        for _ in range(1000):
            randomly_save_message_to_treehole(context)

        db = get_db()
        res = db.execute('select * from treehole').fetchall()
        print("Len =", len(res))
        assert len(res) != 0
コード例 #14
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
 def zaoguys(self):
     """获取起床列表"""
     c = get_db()
     today = date.fromtimestamp(self.context.time)
     zao_list = c.execute(
         'select nickname, wake_timestamp from rest_record where wake_time like ?',
         (str(today) + "%", )).fetchall()
     msg = ""
     index = 1
     for person in zao_list:
         waken_time = datetime.fromtimestamp(person['wake_timestamp'])
         msg += f"\n{index}. {person['nickname']}, {waken_time.hour:02d}:{waken_time.minute:02d}"
         index += 1
     if msg == "":
         return reply('o<<(≧口≦)>>o 还没人起床')
     return reply(msg)
コード例 #15
0
def init_background_tasks(app):
    """
    不同 job 之间的间隔应大于 1 分钟, 否则会导致某些 job 不被执行.
    job 的执行函数第一个参数为当前的 app
    """
    with app.app_context():
        c = get_db()
        c.execute('BEGIN EXCLUSIVE')
        mutex = c.execute("select * from misc where key = 'mutex'").fetchone()
        if mutex is None:
            c.execute("insert into misc values ('mutex', '1')")
            start_flag = 1
        elif mutex['value'] == '0':
            c.execute("update misc set value = '1' where key = 'mutex'")
            start_flag = 1
        else:
            start_flag = 0
        c.commit()  # end of exclusive transaction
    if start_flag:
        apsched = ModifiedBackgroundScheduler(app)
        apsched.add_job(ky_reminder,
                        trigger='cron',
                        hour=12,
                        minute=0,
                        id='ky_reminder')
        apsched.add_job(ghs_reminder,
                        trigger='cron',
                        hour=21,
                        minute=30,
                        id='ghs_reminder')
        apsched.start()

        def unlock():
            with app.app_context():
                try:
                    c = get_db()
                    c.execute(
                        "update misc set value = '0' where key = 'mutex'")
                    c.commit()
                except sqlite3.OperationalError:
                    pass

        atexit.register(unlock)

        return apsched
    return None
コード例 #16
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
    def say(self):
        """向树洞里说一句话"""
        c = get_db()

        try:
            self.context.args[0]
        except IndexError:
            return reply("你必须说点什么。")

        secret = " ".join(self.context.args)
        timestamp = self.context.time
        time = datetime.fromtimestamp(timestamp)
        c.execute(
            "insert into treehole values (?,?,?,?,?,'say')",
            (secret, timestamp, time, self.context.name, self.context.user_id))
        c.commit()
        return reply("我记在脑子里啦!")
コード例 #17
0
def test_scheduled_task(app, requests_mock):
    """
    所有定时任务都在这里测试.
    """
    from bot.scheduled_tasks import init_background_tasks

    r = MessageHandler()
    requests_mock.post('http://127.0.0.1:5700/send_msg', json=r.handler)

    with app.app_context():
        c = get_db()
        c.execute("update misc set value = '0' where key = 'mutex'")
        c.commit()

    scheduler = init_background_tasks(app)

    scheduler.get_job('ky_reminder').func()
    assert '年度研究生考试还有' in r.message

    scheduler.get_job('ghs_reminder').func()
    assert '距离上次 ghs 已经过去' in r.message
コード例 #18
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
 def setky(self):
     """
     设置考研日期
     """
     c = get_db()
     try:
         ky_date_str = self.context.args[0]
         date(int(ky_date_str[:4]), int(ky_date_str[4:6]),
              int(ky_date_str[6:]))
         if len(ky_date_str) != 8:
             raise ValueError
         data = c.execute(
             "select * from misc where key = 'ky_date'").fetchone()
         if data is None:
             c.execute("insert into misc values ('ky_date', ?)",
                       (ky_date_str, ))
         else:
             c.execute("update misc set value = ? where key = 'ky_date'",
                       (ky_date_str, ))
         c.commit()
         return reply("设置成功")
     except (IndexError, ValueError):
         return reply("考研时间格式必须为yyyyMMdd")
コード例 #19
0
ファイル: utils.py プロジェクト: NWUCA/zaobot
def accumulate_exp(context: Context):
    c = get_db()
    now_datetime = datetime.fromtimestamp(context.time)
    now_time = now_datetime.time()
    if not 0 <= now_time.hour < 8:
        return
    user = c.execute(f'select * from xiuxian_emulator where id = {context.user_id}').fetchone()
    if user is not None:
        if user['last_speaking_timestamp'] == "" \
                or date.fromtimestamp(user['last_speaking_timestamp']) != date.fromtimestamp(context.time):
            last_speaking_datetime = now_datetime.replace(hour=0, minute=0, second=0)
        else:
            last_speaking_datetime = datetime.fromtimestamp(user['last_speaking_timestamp'])

        delta = now_datetime - last_speaking_datetime
        if delta.total_seconds() < 60:  # This may reduce database updates
            return
        if now_time.hour < 5 or (timedelta(minutes=1) <= delta < timedelta(hours=3)):
            elapsed_minute = int(delta.total_seconds() / 60)
        else:
            return
        exp = user['exp'] + elapsed_minute
        level = user['level']
        while exp > xiuxian_level[level][1]:
            if xiuxian_level[level][0] == '渡劫':
                send(context, '温馨提示: 渡劫需遵守渡劫基本法, 文明渡劫, 从我做起.')
                send(context, f'恭喜[CQ:at,qq={context.user_id}]道友渡劫成功, 飞升成仙!')
            else:
                send(context, f'[CQ:at,qq={context.user_id}],'
                              f'你已经成功突破了{xiuxian_level[level][0]}期,进入{xiuxian_level[level + 1][0]}期。')
            level += 1
        c.execute('update xiuxian_emulator '
                  'set level=?, exp=?, last_speaking_timestamp=?, last_speaking_time=? where id=?',
                  (level, exp, now_datetime.timestamp(), now_datetime.isoformat(), user['id']))
        if context.name != user['nickname']:
            c.execute('update xiuxian_emulator set nickname=? where id=?', (context.name, user['id']))
        c.commit()
コード例 #20
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
    def wan(self):
        """睡觉"""
        c = get_db()
        start_xiuxian(self.context)
        current_user = c.execute(
            f'select wake_timestamp from rest_record '
            f'where id ={self.context.user_id} ORDER BY wake_timestamp DESC LIMIT 1'
        ).fetchone()
        current_time = datetime.fromtimestamp(self.context.time)
        if current_user is None \
                or current_time - datetime.fromtimestamp(current_user['wake_timestamp']) > timedelta(hours=24):
            return reply('Pia!<(=o ‵-′)ノ☆ 不起床就睡,睡死你好了~')

        wake_time = datetime.fromtimestamp(current_user['wake_timestamp'])
        duration = current_time - wake_time
        if duration < timedelta(minutes=30):
            return reply("你不是才起床吗?")
        else:
            msg = ""
            try:
                delay_minute = int(self.context.args[0])
                sleep_time = current_time + timedelta(minutes=delay_minute)
                duration += timedelta(minutes=delay_minute)
                msg += f"将在{delay_minute}分钟后睡觉。\n"
            except (IndexError, ValueError):
                sleep_time = current_time

            c.execute(
                "update rest_record set sleep_timestamp = ?, sleep_time = ? "
                "where id = ? and wake_timestamp = ?",
                (sleep_time.timestamp(), sleep_time, self.context.user_id,
                 current_user['wake_timestamp']))
            c.commit()
            msg += '今日共清醒{}秒,辛苦了'.format(
                str(duration).replace(':', '小时', 1).replace(':', '分', 1))
            return reply(msg)
コード例 #21
0
ファイル: directive.py プロジェクト: NWUCA/zaobot
    def zao(self):
        """起床"""
        c = get_db()

        today = date.fromtimestamp(self.context.time)

        current_user = c.execute(
            'select * from rest_record where id = ? and wake_time like ?',
            (self.context.user_id, str(today) + "%")).fetchone()
        if current_user is None or date.fromtimestamp(
                current_user['wake_timestamp']) != today:
            last_user = c.execute(
                "SELECT wake_timestamp, waken_num FROM rest_record ORDER BY wake_timestamp DESC LIMIT 1"
            ).fetchone()
            if last_user is None or date.fromtimestamp(
                    last_user['wake_timestamp']) != today:
                # 新的一天
                waken_num = 1
            else:
                waken_num = last_user['waken_num'] + 1
            wake_timestamp = self.context.time
            wake_time = datetime.fromtimestamp(self.context.time)
            inserted_data = (self.context.user_id, wake_timestamp, wake_time,
                             self.context.name, waken_num, '', '')  # 注意顺序
            c.execute("insert into rest_record values (?,?,?,?,?,?,?)",
                      inserted_data)
            c.commit()
            try:
                greeting = self.context.args[0]
            except IndexError:
                greeting = '少年'
            return reply(f"你是第{waken_num:d}起床的{greeting}。")
        elif current_user['sleep_timestamp'] != '':
            return reply("你不是睡了吗?")
        else:
            return reply("你不是起床过了吗?")
コード例 #22
0
def test_zao_db(app):
    with app.app_context():
        c = get_db()
        res = c.execute("select * from rest_record").fetchone()
        print(tuple(res))
        assert 1