def suggestion(args_text, ctx_msg, argv: list = None, allow_interactive=True): source = get_source(ctx_msg) if allow_interactive and (len(argv) < 1 or not argv[0].startswith('CN') or has_session(source, _cmd_suggestion)): # Be interactive return _do_interactively(_cmd_suggestion, suggestion, args_text.strip(), ctx_msg, source) city_id = argv[0] text = '' data = _get_weather(city_id) if data: data = data['suggestion'] text += '生活指数:\n\n' \ '舒适度:%s\n\n' \ '洗车指数:%s\n\n' \ '穿衣指数:%s\n\n' \ '感冒指数:%s\n\n' \ '运动指数:%s\n\n' \ '旅游指数:%s\n\n' \ '紫外线指数:%s' \ % tuple([data[k]['txt'] for k in ('comf', 'cw', 'drsg', 'flu', 'sport', 'trav', 'uv')]) if text: core.echo(text, ctx_msg) else: core.echo('查询失败了,请稍后再试哦~', ctx_msg)
def take(args_text, ctx_msg, allow_interactive=True): source = get_source(ctx_msg) if allow_interactive and (not args_text or has_session(source, _cmd_take)): # Be interactive return _take_interactively(args_text, ctx_msg, source) conn = _open_db_conn() dt_unix = int(datetime.now(tz=pytz.utc).timestamp()) target = get_target(ctx_msg) conn.execute('INSERT INTO cmd_note (content, dt, target) VALUES (?, ?, ?)', (args_text, dt_unix, target)) conn.commit() conn.close() core.echo('好的,记下了~', ctx_msg)
def subscribe(args_text, ctx_msg, argv=None, internal=False, allow_interactive=True): source = get_source(ctx_msg) if not internal and allow_interactive and has_session( source, _cmd_subscribe): # Already in a session, no need to pass in data, # because the interactive version of this command will take care of it return _subscribe_interactively(args_text, ctx_msg, source, None) data = {} if argv: m = re.match('([0-1]\d|[2][0-3])(?::|:)?([0-5]\d)', argv[0]) if not m: # Got command but no time data['command'] = args_text else: # Got time data['hour'], data['minute'] = m.group(1), m.group(2) if len(argv) == 2: # Got command data['command'] = argv[1] if not internal and allow_interactive: if data.keys() != {'command', 'hour', 'minute'}: # First visit and data is not enough return _subscribe_interactively(args_text, ctx_msg, source, data) # Got both time and command, do the job! hour, minute = data['hour'], data['minute'] command = data['command'] job = scheduler.add_job('-H %s -M %s --multi %s %s' % (hour, minute, _scheduler_job_id_prefix + str(int(datetime.now().timestamp())), command), ctx_msg, internal=True) if internal: return job if job: # Succeeded to add a job reply = '订阅成功,我会在每天 %s 推送哦~' % ':'.join((hour, minute)) else: reply = '订阅失败,可能后台出了点小问题~' core.echo(reply, ctx_msg, internal)
def weather(args_text, ctx_msg, argv: list = None, allow_interactive=True): source = get_source(ctx_msg) if allow_interactive and (not argv or not argv[0].startswith('CN') or has_session(source, _cmd_weather)): # Be interactive return _do_interactively(_cmd_weather, weather, args_text.strip(), ctx_msg, source) city_id = argv[0] text = '' data = _get_weather(city_id) if data: text += '%s天气\n更新时间:%s' % (data['basic']['city'], data['basic']['update']['loc']) now = data['now'] aqi = data['aqi']['city'] text += '\n\n实时:\n\n%s,气温%s°C,体感温度%s°C,%s%s级,' \ '能见度%skm,空气质量指数:%s,%s,PM2.5:%s,PM10:%s' \ % (now['cond']['txt'], now['tmp'], now['fl'], now['wind']['dir'], now['wind']['sc'], now['vis'], aqi['aqi'], aqi['qlty'], aqi['pm25'], aqi['pm10']) daily_forecast = data['daily_forecast'] text += '\n\n预报:\n\n' for forecast in daily_forecast: d = datetime.strptime(forecast['date'], '%Y-%m-%d') text += '%d月%d日%s,' % (d.month, d.day, _weekday_string[d.weekday()]) cond_d = forecast['cond']['txt_d'] cond_n = forecast['cond']['txt_n'] text += cond_d + ('转' + cond_n if cond_d != cond_n else '') + ',' text += forecast['tmp']['min'] + '~' + forecast['tmp'][ 'max'] + '°C,' text += forecast['wind']['dir'] + forecast['wind']['sc'] + '级,' text += '降雨概率%s%%' % forecast['pop'] text += '\n\n' text = text.rstrip() if text: core.echo(text, ctx_msg) else: core.echo('查询失败了,请稍后再试哦~', ctx_msg)
def subscribe(args_text, ctx_msg, allow_interactive=True): arg = args_text.strip() source = get_source(ctx_msg) if allow_interactive and (not arg or has_session(source, _cmd_subscribe)): # Be interactive return _subscribe_interactively(args_text, ctx_msg, source) force = False if arg.startswith('-f '): force = True arg = arg.split(' ', 1)[1].strip() reply = None try: m = re.match('([0-1]\d|[2][0-3])(?::|:)?([0-5]\d)', arg) if m: job = scheduler.get_job(_scheduler_job_id, ctx_msg, internal=True) if job and not force: reply = '已经订阅过了哦~\n' \ + '下次推送时间:\n' \ + job.next_run_time.strftime('%Y-%m-%d %H:%M') + '\n' \ + '如果需要更改推送时间,请先取消订阅再重新订阅,' \ + '或在订阅命令的时间参数前面加 -f 来强制更新推送时间' raise SkipException job = scheduler.add_job( '-M %s -H %s %s zhihu.zhihu-daily' % (m.group(2), m.group(1), _scheduler_job_id), ctx_msg, internal=True ) if job: # Succeeded to add a job reply = '订阅成功,我会在每天 %s 推送哦~' % ':'.join((m.group(1), m.group(2))) else: reply = '订阅失败,可能后台出了点问题呢~' else: reply = '命令格式错误,正确的命令格式:\n' \ '/zhihu.subscribe\n' \ '或\n' \ '/zhihu.subscribe [-f] 20:30\n' except SkipException: reply = reply if reply else '发生了未知错误……' core.echo(reply, ctx_msg)
def _filter(ctx_msg): if ctx_msg.get('format') == 'media' and ctx_msg['raw_ctx'].get( 'media_type') == 'voice': m = re.match('\[语音\]\(([/_A-Za-z0-9]+\.mp3)\)', ctx_msg.get('content')) if m: core.echo('正在识别语音内容,请稍等……', ctx_msg) mp3_path = m.group(1) wav_path = os.path.splitext(mp3_path)[0] + '.wav' voice = AudioSegment.from_mp3(mp3_path) voice.export(wav_path, format='wav') service = os.environ.get('SPEECH_RECOGNITION_SERVICE', '').lower() text = None service_full_name = None if service == 'baidu': service_full_name = '百度语音识别' text = _recognize_baidu( wav_path, get_source(ctx_msg), os.environ.get('BAIDU_SPEECH_API_KEY'), os.environ.get('BAIDU_SPEECH_SECRET_KEY'), language='zh') elif service == 'bing': service_full_name = '必应语音识别' text = _recognize_bing(wav_path, os.environ.get('BING_SPEECH_API_KEY'), language='zh-CN') else: print('Unknown speech recognition service name.', file=sys.stderr) if text: reply = '识别结果(' + service_full_name + '):\n%s\n\n下面将把识别到的内容作为文字消息处理……' % text ctx_msg['text'] = text ctx_msg['from_voice'] = True else: reply = '抱歉哦,没有识别出你说的是什么' core.echo(reply, ctx_msg) os.remove(wav_path)
def tuling123(args_text, ctx_msg, internal=False): url = 'http://www.tuling123.com/openapi/api' data = { 'key': os.environ.get('TURING123_API_KEY'), 'info': args_text, 'userid': get_source(ctx_msg) } resp = requests.post(url, data=data) if resp.status_code == 200: json = resp.json() if internal: return json if int(json.get('code', 0)) == 100000: reply = json.get('text', '') else: # Is not text type reply = '腊鸡图灵机器人返回了一堆奇怪的东西,就不发出来了' else: if internal: return None reply = '腊鸡图灵机器人出问题了,先不管他,过会儿再玩他' core.echo(reply, ctx_msg)
def remove(args_text, ctx_msg, allow_interactive=True): source = get_source(ctx_msg) if allow_interactive and (not args_text or has_session(source, _cmd_remove)): # Be interactive return _remove_interactively(args_text, ctx_msg, source) try: note_id = int(args_text) except ValueError: # Failed to cast core.echo('你输入的 ID 格式不正确哦~应该是个数字才对~', ctx_msg) return conn = _open_db_conn() target = get_target(ctx_msg) cursor = conn.cursor() cursor.execute('DELETE FROM cmd_note WHERE target = ? AND id = ?', (target, note_id)) if cursor.rowcount > 0: core.echo('删除成功了~', ctx_msg) else: core.echo('没找到这个 ID 的笔记哦~', ctx_msg) conn.commit() conn.close()