async def en_secondary_operation(bot: Bot, event: GroupMessageEvent, state: T_State): logger.debug(f'Handle brach with {state["operation"]}') gid = str(event.group_id) if gid not in exitremind_settings: exitremind_settings[gid] = DEFAULT_REMIND settings = exitremind_settings[gid] if state['operation'] == 'add_leave': settings['leave'].append(event.raw_message) msg = '好的,已经添加一个主动退群提醒语句' elif state['operation'] == 'add_kick': settings['kick'].append(event.raw_message) msg = '好的,已经添加一个管理踢人提醒语句' elif state['operation'] == 'delete': if event.raw_message.isdigit(): index = int(event.raw_message) if index > 0 and index <= len(settings['leave']) + len(settings['kick']): if index <= len(settings['leave']): del settings['leave'][index - 1] msg = f'已删除序号为{index}的退群提醒语句' else: index -= len(settings['leave']) del settings['kick'][index - 1] msg = f'已删除序号为{index}的管理踢人提醒语句' else: await remind_editor.finish('输入的参数不在列表内,请检查序号') else: await remind_editor.finish('只支持纯数字参数,请重新开启此对话进行操作') else: logger.error(f"Unkown session with operation: {state['operation']}") await remind_editor.finish('未知的对话进度,请联系维护组进行排查') save_en_settings() await remind_editor.finish(msg)
async def send_notice(bot: Bot, event: MessageEvent, state: T_State): args = event.message.extract_plain_text() if args in CANCEL_EXPRESSION: await broadcast.finish('已取消发送广播') if not args: await broadcast.reject('输入不能为空,请重新输入,输入[退出]取消发送') grps = args.replace(',', ',').split(',') gid_ls = state["gid_ls"] target_grps = [] for g in grps: if not g.strip().isdigit(): await broadcast.reject('非数字参数,请重新输入,输入[退出]取消发送') break gid = int(g.strip()) if gid < 0 or gid > len(gid_ls): await broadcast.reject('序号超出范围,请重新输入,输入[退出]取消发送') break target_grps.append(gid) else: try: for i in target_grps: await bot.send_group_msg(group_id=gid_ls[i], message=state["msg"]) except AdapterException as err: logger.error(f'Faild to send broadcast with error: {err}') await broadcast.finish(f'广播投递失败') await broadcast.finish(f'已将广播发送给{len(target_grps)}个群')
async def search_qm(keyword, result_num: int = 3): """ 搜索音乐 """ number = result_num song_list = [] params = {"w": keyword, "format": "json", "p": 0, "n": number} headers = {"referer": "http://m.y.qq.com", "User-Agent": USER_AGENT} try: async with httpx.AsyncClient() as client: resp = await client.get( url="http://c.y.qq.com/soso/fcgi-bin/search_for_qq_cp", params=params, headers=headers, timeout=3) res_data = resp.json() except Exception as e: logger.error(f'Request QQ Music Timeout {e}') return None try: for item in res_data['data']['song']['list'][:result_num]: song_list.append({ 'name': item['songname'], 'id': item['songid'], 'artists': ' '.join(artist['name'] for artist in item['singer']), 'type': 'qq' }) return song_list except KeyError as e: logger.warning(f'No Result: {e}') return []
async def wl_secondary_operation(bot: Bot, event: GroupMessageEvent, state: T_State): gid = str(event.group_id) if gid not in welcome_settings: welcome_settings[gid] = DEFAULT_SPEECH settings = welcome_settings[gid] # if state['operation'] == 'add_approve': if state['operation'] == 'add': settings['approve'].append(event.raw_message) msg = '好的,已经添加一个迎新语句' # elif state['operation'] == 'add_invite': # settings['invite'].append(event.raw_message) # msg = '好的,已经添加一个被邀请入群欢迎语句' elif state['operation'] == 'delete': if event.raw_message.isdigit(): index = int(event.raw_message) # if index > 0 and index <= len(settings['approve']) + len(settings['invite']): if index > 0 and index <= len(settings['approve']): # if index <= len(settings['approve']): # del settings['approve'][index - 1] # msg = f'已删除序号为{index}的入群欢迎语句' # else: # index -= len(settings['approve']) # del settings['invite'][index - 1] # msg = f'已删除序号为{index}的被邀请群欢迎语句' del settings['approve'][index - 1] msg = f'已删除序号为{index}的迎新语句' else: await speech_editor.finish('输入的参数不在列表内,请检查序号') else: await speech_editor.finish('只支持纯数字参数,请重新开启此对话进行操作') else: logger.error(f"Unkown session with operation: {state['operation']}") await speech_editor.finish('未知的对话进度,请联系维护组进行排查') save_wl_settings() await speech_editor.finish(msg)
def query_fortune(uid: int) -> Optional[str]: with QbotDB() as qb: cmd = 'SELECT 运势 FROM calltimes WHERE qq_number=%s' result = qb.queryone(cmd, (uid,)) if not result: logger.error(f'Failed to get calltimes info of user:{uid}') return None return result[0]
def test_database_01(): project_id = '224472' db = Database() try: url = db.get_project_url(project_id) logger.info('The url for project {} was {}'.format(project_id, url)) except ProjectNotFoundException: logger.error('The project {} was not in database.'.format(project_id)) pass
async def three_clock(): logger.info('Time to drink tea!!') for strid, bot in get_bots().items(): groups: list = await bot.get_group_list() gids = [ g['group_id'] for g in groups if Enable_Group(g['group_id']).check_enable() and Group_Blocker(g['group_id']).check_block() # 未阻塞 and plugin_name not in group_func_off[str(g['group_id'])] ] # 未关闭功能 shuffle(gids) logger.info(f'Will Send {len(gids)} group(s): {str(gids)}') try: for g in gids: for msg in TEATIME_NOTICE: await bot.send_group_msg(group_id=g, message=msg) await asyncio.sleep(1.5) # 防止消息发送间隔过短导致顺序错乱 await bot.send_group_msg(group_id=g, message=choice(TEATIME_ATTACH)) asyncio.sleep(15) # 结束上一个群的发送开始发送下一个群的间隔 except ActionFailed as err: logger.error( f'Maybe too intensive to send msg, cause error: {err}') # 由用户自定义提醒功能时会需要这个添加、删除定时器的方式 # def sv_teatime(bot: Bot, event: GroupMessageEvent, state): # logger.debug(f'Got command {event.get_message().extract_plain_text().strip()}') # if event.get_message().extract_plain_text().strip() == plugin_name and\ # isinstance(event, GroupMessageEvent) and event.sender.role in ('owner', 'admin'): # return True # teatime_switch = MatcherGroup(type='message') # teatime_on = teatime_switch.on_command('开启', rule=comman_rule(GroupMessageEvent)) # teatime_off = teatime_switch.on_command('关闭', rule=comman_rule(GroupMessageEvent)) # @teatime_on.handle() # async def turn_tt_on(bot: Bot, event: GroupMessageEvent): # scheduler.add_job(test, 'cron', second='*/30', id='3clock', jitter=10) # logger.info(f'{event.group_id} turn the job 3clock On !') # @teatime_off.handle() # async def turn_tt_off(bot: Bot, event: GroupMessageEvent): # scheduler.remove_job('3clock') # logger.info(f'{event.group_id} turn the job 3clock Off !') # tsttea = teatime_switch.on_command('饮茶') # @tsttea.handle() # async def tsteee(bot): # msg = choice(TEATIME_ATTACH) # logger.debug(str(msg)) # await tsttea.finish(msg)
def chat_checker(bot: Bot, event: MessageEvent, state: T_State): """闲聊触发率规则 优先级规则内,to_me时必定触发 否则真实触发率为 群设置聊天触发率 * 返回信息的可信度 """ msg = event.message.extract_plain_text() if not msg or len(msg) > 50 or event.raw_message in BAN_MESSAGE or\ event.raw_message == '钓鱼': return False # 回复别人的对话不会触发 for seg in event.message: if seg.type == 'at' and seg.data["qq"] not in ( str(event.self_id), 'all' ) or event.reply and event.reply.sender.user_id != event.self_id: return False if event.message_type == 'group' and not event.is_tome(): nothing_to_bot = True # 对话中带有bot名字,归到到下面一起判断 for name in BOTNAMES: if name in msg: person = '你' if msg.endswith( BOTNAME) else '' # 名称在中间的时候替换成第二人称,名称在末尾时直接去掉 msg = msg.replace(name, person) nothing_to_bot = False break gid = str(event.group_id) prob = prob_settings[gid] if gid in prob_settings else 0.05 # 默认触发率5% if nothing_to_bot and random() > prob: return False else: ai_reply = ai_chat(msg) if ai_reply is None: logger.error( f'Failed to get tencent AI chat!') # 内部错误时返回的的是None return False else: reply, confidence = ai_chat(msg) if reply in BAN_EXPRESSION or len(reply) > 50: return False logger.debug(f'{msg} 获得触发率 {confidence:.5f}') if random() > confidence: return False else: state["reply"] = reply return True
def main(): parser = argparse.ArgumentParser() parser.description = 'Download mod files from curseforge by manifest JSON file.' parser.add_argument('manifest', help='The manifest JSON file.') parser.add_argument( 'mod_folder', help='The folder which used to save the downloaded files.') args = parser.parse_args() manifest_filepath = args.manifest mod_folder = args.mod_folder finished = False while not finished: try: download_mods(manifest_filepath, mod_folder) finished = True except Exception as e: logger.error(e)
async def prob_handle(bot: Bot, event: GroupMessageEvent, state: T_State): prob = state[ "prob"] if "prob" in state else event.message.extract_plain_text( ).strip() if not prob.isdigit(): await set_prob.finish(reply_header(event, '仅支持数字参数~')) prob = int(prob) if prob < 0 or prob > 50: await set_prob.finish(reply_header(event, '范围错误,聊天触发率仅支持设置为0-50内')) try: record_settings(str(event.group_id), prob / 100) if prob > 0: msg = f'好的,{BOTNAME}最多只有{prob}%的几率插嘴啦~' else: msg = f'好的,{BOTNAME}不会插嘴啦~' await set_prob.finish(reply_header(event, msg)) except IOError as err: logger.error(f'Record ai chat probability error: {err}') await set_prob.finish( reply_header(event, f'{BOTNAME}突然遭遇了不明袭击,没有记录下来,请尽快联系维护组修好我T_T'))
async def sx_rev(bot: Bot, event: MessageEvent, state: T_State): logger.debug(f'Match sx {state["_matched_groups"]}') abbr = state["_matched_groups"][0] try: data = await get_sx(abbr) except aiohttp.ClientError as err: logger.error(f'query sx {abbr} error: {err}') await sx.finish("查询出错了,要不要稍后再试试?") try: name = data[0]['name'] logger.debug(f'查询缩写:{name}') content = data[0]['trans'] logger.debug(f'查找到的缩写:{content}') if len(content) == 0: await sx.finish(f'没有找到缩写可能为{name}的内容') msg = f'{name} 的意思可能为:' if len(content) > 1: msg += '\n' await sx.send(msg + "、".join(content)) except: await sx.finish(f'没有找到缩写可能为{abbr}的内容')
async def search_163(keyword: str, result_num: int = 5): n = NetEase() song_list = [] data = await n.search(keyword, num=result_num) if data and data.status_code == httpx.codes.OK: try: for item in data.json()['result']['songs'][:result_num]: song_list.append({ 'name': item['name'], 'id': item['id'], 'artists': ' '.join([artist['name'] for artist in item['artists']]), 'type': '163' }) return song_list except Exception as e: logger.error(f'获取网易云歌曲失败, 返回数据data={data}, 错误信息error={e}') return [] return song_list
async def get_setu(bot: Bot, event: MessageEvent, state: T_State): msg: Message = Message(state["setu"]) try: for seg in msg: if seg.type == "image": url = seg.data["url"] # 图片链接 break else: await setu.finish(reply_header(event, "这也不是图啊!")) await bot.send(event=event, message="让我搜一搜...") result = MessageSegment.text('————>SauceNao<————') async for msg in get_des(url, 'sau'): if not msg: await setu.send('未从saucenao检索到高相似度图片,将运行ascii2d检索') break result += msg + '────────────\n' else: result = Message(str(result).rstrip('────────────\n')) await setu.finish(result) result = MessageSegment.text('————>ascii2d<————') async for msg in get_des(url, 'ascii2d'): if not msg: await setu.finish('未从ascii2d检索到高相似度图片,请等待加入更多检索方式') break result += msg + '────────────\n' else: result = Message(str(result).rstrip('────────────\n')) await setu.finish(result) except (IndexError, ClientError): logger.exception(traceback.format_exc()) await setu.finish("遇到未知打击,中断了搜索") except ActionFailed as e: logger.error(f'Send result failed: {e}') await setu.finish('虽然搜到了,但是发送结果途中遭遇拦截,可稍后再试一试')
async def operate_list(bot: Bot, event: MessageEvent, state: T_State): music_list = state['music_list'] music_page = state['music_page'] turning_page = '{main_list}\n────────────\n{pgbar}' + '\n输入"上一页""下一页"翻页查看列表,输入[序号]播放' #在翻页时展示的列表 operation = event.message.extract_plain_text().strip() if operation in CANCEL_EXPRESSION: await music.finish('已结束当前会话') if operation == '上一页': if state['crtpg'] == 1: await music.reject('当前已经是首页了哦~') else: state['crtpg'] -= 1 state['pgbar'].pgup() await music.reject( turning_page.format( main_list=music_page[f'page{state["crtpg"]}'], pgbar=state['pgbar'].bar)) if operation == '下一页': if state['crtpg'] == len(music_page): await music.reject('已经是最后页了~') else: state['crtpg'] += 1 state['pgbar'].pgdn() await music.reject( turning_page.format( main_list=music_page[f'page{state["crtpg"]}'], pgbar=state['pgbar'].bar)) try: index = cn2an(numrex.search(operation).group(1), 'smart') except: state['error_time'] += 1 if state['error_time'] < 4: await music.reject( '请发送正确的格式,如"第一首"、"第1首"或仅仅输入序号"1"等带有数字提示的语句\n若要进行其他对话请先发送[退出]结束本次点歌' ) else: await music.finish('输入错误次数太多了,请重新开启本对话吧~') if index > 0 and index <= len(music_list): music_ = music_list[index - 1] if music_['type'] == '163': msc = MessageSegment.music('163', music_['id']) elif music_['type'] == 'custom': msc = MessageSegment(type='music', data=music_) else: msc = MessageSegment.music('qq', music_['id']) # data={ # 'id': music_['id'], # 'type': 'qq', # 'content': music_['artists'] # } # ) try: await music.send(msc) return 'completed' # 点歌成功 except ActionFailed as e: await music.finish('好像歌曲坏了呢') logger.error("%s - %s 发送失败" % (music['type'], music['id'])) else: await music.reject(f'序号{index}不在列表中呢~')