async def daily_movie(self, cam: Cam): day = datetime.datetime.now() - datetime.timedelta(days=1) day = day.strftime('%d_%m_%Y') loop = asyncio.get_event_loop() with concurrent.futures.ThreadPoolExecutor() as pool: try: clip = await loop.run_in_executor(pool, lambda: make_movie(cam, day)) except FileNotFoundError as exc: logger.exception(exc) await self.notify_admins( f'File {exc.filename} not found for daily movie {cam.name}: {day}' ) return except Exception as exc: logger.exception(exc) await self.notify_admins( f'Error during making daily movie for {cam.name}: {day}') return if cam.update_channel: async with db_in_thread(): channels = db.query(Channel).filter( Channel.cam == cam.name).all() for channel in channels: await send_video(Chat(self._bot, channel.chat_id), clip) await self.notify_admins(f'Daily movie for {cam.name}: {day} ready!') for chat in await self.admin_chats(): await send_video(Chat(self._bot, chat.chat_id), clip)
async def posheldfind(chat: Chat, match): async with bot._db_conn.acquire() as conn: query = """ SELECT position.name as position, first_name as fname, last_name as lname, middle_name as mname, time_from, time_to, cabinet.name as cabinet FROM posheld JOIN position ON position.id=posheld.position_id JOIN employee on employee.id=posheld.employee_id JOIN schedule on schedule.employee_id=posheld.employee_id JOIN cabinet on cabinet.id=schedule.cabinet_id WHERE position.name LIKE '%{}%' LIMIT 10; """.format(match.group(1)) result = await (await conn.execute(query)).fetchall() log.debug(result) if result and len(result) == 1: ans = result[0] efio = "{} {} {}".format(ans.lname, ans.fname, ans.mname) return chat.reply('{} {} сейчас в {}'.format( ans.position, efio, ans.cabinet)) return chat.reply('Уточните ваш запрос') return chat.reply('Извините, по вашему запросу ничего не найдено')
def echo(chat: Chat, match): date = datetime.date.today() day_x = datetime.date(year=2019, month=3, day=14,) if date == day_x: return chat.reply("NO, YOU CAN'T TODAY!") else: return chat.reply("Yes, ofcourse, if tests are good and you want to.")
def test_chat_methods(): bot = MockBot() chat_id = 42 chat = Chat(bot, chat_id) chat.send_text("hello") assert "sendMessage" in bot.calls assert bot.calls["sendMessage"]["text"] == "hello"
async def create_new_app(chat: Chat, match): private_id = chat.sender["id"] app_name = str(match.group(1)) print(str(private_id) + " " + str(app_name)) if UserData.select().where(UserData.app_name == app_name): return chat.reply("App with this name already exists") else: UserData.create(app_name=app_name, private_id=private_id).save() return chat.reply("App " + str(app_name) + " successfully create")
async def get_proff(chat: Chat, match): async with bot._db_conn.acquire() as conn: query = """ SELECT * FROM employee WHERE CONCAT(last_name,' ',first_name,' ',middle_name,' ') LIKE '%{0}%' LIMIT 10; """.format(match.group(1)) result = await (await conn.execute(query)).fetchall() log.debug(result) if result and len(result) == 1: employee = result[0] schedule_query = """ SELECT cabinet.name, schedule.time_from, schedule.time_to FROM schedule JOIN cabinet ON schedule.cabinet_id=cabinet.id WHERE (curtime() between time_from and time_to) and (weekday(curdate())=weekday) and (employee_id='{}'); """.format(employee.id) schedule = await (await conn.execute(schedule_query)).fetchone() log.debug(schedule) efio = "{} {} {}".format(employee.last_name, employee.first_name, employee.middle_name) if schedule: time_from = str(schedule.time_from)[:-3] time_to = str(schedule.time_to)[:-3] return chat.reply("{} сейчас({}-{}) в {}".format( efio, time_from, time_to, schedule.name)) return chat.reply("Я не знаю, где сейчас {}".format(efio)) if result and len(result) > 1: kb = { 'type': 'InlineKeyboardMarkup', "inline_keyboard": list([[{ 'type': 'InlineKeyboardButton', "text": "{} {} {}".format(i.last_name, i.first_name, i.middle_name), "callback_data": "proff-{}".format(i.id) }] for i in result]) } log.debug(kb) return chat.send_text('Уточните запрос', reply_markup=json.dumps(kb)) return chat.reply("По вашему запросу ничего не найдено")
def test_edit_message(): bot = MockBot() chat_id = 42 message_id = 1337 chat = Chat(bot, chat_id) chat.edit_text(message_id, "bye") assert "editMessageText" in bot.calls assert bot.calls["editMessageText"]["text"] == "bye" assert bot.calls["editMessageText"]["message_id"] == message_id
def test_edit_reply_markup(): bot = MockBot() chat_id = 42 message_id = 1337 chat = Chat(bot, chat_id) chat.edit_reply_markup(message_id, {'inline_keyboard': [['ok', 'cancel']]}) assert "editMessageReplyMarkup" in bot.calls call = bot.calls["editMessageReplyMarkup"] assert call["reply_markup"] == '{"inline_keyboard": [["ok", "cancel"]]}' assert call["message_id"] == message_id
def test_edit_reply_markup(): bot = MockBot() chat_id = 42 message_id = 1337 chat = Chat(bot, chat_id) chat.edit_reply_markup(message_id, {"inline_keyboard": [["ok", "cancel"]]}) assert "editMessageReplyMarkup" in bot.calls call = bot.calls["editMessageReplyMarkup"] assert call["reply_markup"] == '{"inline_keyboard": [["ok", "cancel"]]}' assert call["message_id"] == message_id
async def get_tags(chat: aiotg.Chat, match): parser = get_get_tags_parser() args = parse_match(match.group(1), parser) if not args: chat.send_text(parser.format_help()) return tags = await bot.clients[chat.id].get_tags() tags_yml = yaml.dump(tags, default_flow_style=False) if tags: return chat.send_text(tags_yml) return
def test_chat_methods(): bot = MockBot() chat_id = 42 chat = Chat(bot, chat_id) chat.send_text("hello") assert "sendMessage" in bot.calls assert bot.calls["sendMessage"]["text"] == "hello" # Just test a single wrapper, the rest are same chat.send_photo() assert "sendPhoto" in bot.calls assert isinstance(bot.calls["sendPhoto"]["chat_id"], str)
async def get_tasks(chat: aiotg.Chat, match): parser = get_get_tasks_parser() args = parse_match(match.group(1), parser) if not args: chat.send_text(parser.format_help()) return _filter = None if args: _filter = args.filter tasks = await bot.clients[chat.id].get_tasks(_filter) tasks_markdown = beauty_tasks(tasks) if tasks: return chat.send_text(tasks_markdown, parse_mode='Markdown') return
async def callback_delete_task(chat: aiotg.Chat, cb: aiotg.CallbackQuery, match: re.Match): task: Task = await Task.get(int(match.group(1))) if not task: text = f"Странно, но такой задачи у меня нет (ИД={task.id})" return await cb.answer(text=text, show_alert=True) await task.delete() text = f'Задача удалена' markup = await make_menu_markup(chat) await asyncio.gather( chat.edit_reply_markup(chat.message['message_id'], markup=markup), cb.answer(text=text, show_alert=True), chat.send_text(text, reply_to_message_id=task.message_id) )
async def login(chat: aiotg.Chat, match): parser = argparse.ArgumentParser(prog='login', description='login command') required_group_parser = parser.add_argument_group('required arguments') required_group_parser.add_argument('-u', '--username', required=True) required_group_parser.add_argument('-p', '--password', required=True) args = parse_match(match.group(1), parser) if not args: chat.send_text(parser.format_help()) return telegram_id = chat.id user = args.username password = args.password try: tortoise_client = await TortoiseClient.create(user, password) bot.clients.update({telegram_id: tortoise_client}) chat.send_text('Successfully login!') except GetTokenError as error: chat.send_text('Login failed!') response = get_response_from_error(error) response_body = await response.read() chat.send_text('Error: \n' + response_body.decode('utf-8')) return
async def start(chat: Chat, _) -> None: lang = localizations.get_lang(chat.message['from'].get('language_code')) await chat.send_text(lang['help_message']) await chat.send_text(lang['help_message_transformers_list']) for processor in text_processors.all_processors: help_message_key = 'help_' + processor.snake_case_name localized_help_message = lang[help_message_key] # skip empty and undefined help messages if len(localized_help_message.strip() ) == 0 or localized_help_message == help_message_key: continue localized_processor_name = resolve_text_processor_name(processor, lang) answer = f"*{localized_processor_name}*\n\n{localized_help_message}" await chat.send_text(answer, parse_mode="Markdown") chat.send_text(lang['help_send_suggestion'], parse_mode="Markdown")
async def audio(chat: Chat, match): log(chat) surah = int(match.group(1)) if not (1 <= surah <= 114): return chat.send_text("Surah does not exist!") await chat.send_chat_action("upload_audio") directory = "Mahmoud_Khalil_Al-Hussary_(Updated2)(MP3_Quran)/" multiple = { # surahs in multiple audio tracks 2: 4, 3: 3, 4: 3, 5: 2, 6: 2, 7: 2, 9: 2, 10: 2, 11: 2, 12: 2, 16: 2 } if surah in multiple: filenames = [ directory + str(surah).zfill(3) + "_" + str(i) + ".mp3" for i in range(1, multiple[surah] + 1) ] multi = True else: filenames = [directory + str(surah).zfill(3) + ".mp3"] multi = False performer = "Shaykh Mahmoud Khalil al-Husary" title = "Quran {} {}".format(surah, Quran.get_surah_name(surah)) for (i, filename) in enumerate(filenames): if multi: title = "Quran {} {} (part {}/{})".format( surah, Quran.get_surah_name(surah), i + 1, len(filenames)) file_id = await get_file(filename) if file_id: try: response = await chat.send_audio(file_id, performer=performer, title=title) except Exception as e: if "file_id" in str(e) or "file identifier" in str(e): with open(filename, "rb") as f: response = await chat.send_audio(f, performer=performer, title=title) else: raise (e) else: with open(filename, "rb") as f: response = await chat.send_audio(f, performer=performer, title=title) file_id = response["result"]["audio"]["file_id"] await save_file(filename, file_id)
async def help_handler(self, chat: Chat, math): """Help command handler""" self.logger.info("Recieved help request") help_msg = ("*Message forward bot*\n" "*/token* -- get your API token\n\n" "Please readme [Manual]({url})").format(url=self._api_url) return chat.reply(help_msg, parse_mode="Markdown")
async def token_handler(self, chat: Chat, math): """Telegram id to API token handler""" self.logger.info("Recieved convert to token request") self.logger.debug("Raw: %s", chat.sender.items()) token = self.token.to_token(tid=chat.sender["id"]) self.logger.debug("Cache info: %s", self.token.to_token.cache_info()) return chat.reply(token)
def test_chat_reply(): bot = MockBot() msg = text_msg("Reply!") chat = Chat.from_message(bot, msg) chat.reply("Hi " + repr(chat.sender)) assert "sendMessage" in bot.calls assert bot.calls["sendMessage"]["text"] == "Hi John"
async def subscriptions(chat: Chat, match): subs = await self.subscribers.get_subscriptions(chat.id) # print("(telegram)", subs) if not subs: return chat.send_text("You dont have subscriptions") queue = Queue() rnd_name = str(uuid4()) hook = get_hook(queue) bot.add_callback(rnd_name + "-(.*)", hook) markup = get_subscriptions_markup(subs, rnd_name) sended_msg = await chat.send_text("Subscriptions:", reply_markup=json.dumps(markup)) sended_message_id = sended_msg['result']['message_id'] nmatch = await queue.get() choosed_id = int(nmatch.group(1)) removed_sub = await self.subscribers.remove(chat.id, choosed_id) msg = "Unsubscribed from '%s'" % removed_sub return chat.edit_text(sended_message_id, msg)
async def _post_photo(self, cam: Cam, photo: Path): async with db_in_thread(): channels = db.query(PhotoChannel).filter( PhotoChannel.cam == cam.name).all() for channel in channels: chat = Chat(self._bot, channel.chat_id) with open(photo, 'rb') as ph: await chat.send_photo(ph)
async def square_command(chat: Chat, match): val = match.group(1) try: val = float(val) square = await get_square.call(val) resp = f"Square for {val} is {square}" except Exception(): resp = "Invalid number" return chat.reply(resp)
async def square_command(chat: Chat, match): val = match.group(1) try: val = float(val) square = await get_square.call(val) resp = f'Square for {val} is {square}' except: resp = 'Invalid number' return chat.reply(resp)
def about(chat: Chat, match): log(chat) text = ( "The recitation is by " "<a href=\"https://en.wikipedia.org/wiki/Mahmoud_Khalil_Al-Hussary\">Shaykh Mahmoud Khalil al-Husary</a> " "from <a href=\"http://torrent.mp3quran.net/details.php?id=3f2404b9cc6dfb5ccf70580a149fd8b87de0d8f1\">mp3quran.net</a>. " "This bot is free software, the source code is available at: https://github.com/rahiel/AudioQuranBot." ) return chat.send_text(text, parse_mode="HTML")
async def print_help(chat: aiotg.Chat, match): help_message = 'Commands: \n' help_message += '/login \n' help_message += '/help \n' help_message += '/tags add \n' help_message += '/tags get \n' help_message += '/tasks add \n' help_message += '/tasks get \n' return chat.send_text(help_message)
def usage(chat: Chat, match): demo_date = datetime.date.today() + datetime.timedelta(days=30) logger.info('Start request: {}'.format(match)) text = """ Привет! Я умею искать билеты на поезд. Как спросить у меня список билетов: /search москва, спб, 4.{month:02d} 20:00 - 5.{month} 03:00 """.format(month=demo_date.month) return chat.send_text(text)
def start(chat: Chat, match): keyboard = { "keyboard": [['Два чая, этому господину']], "resize_keyboard": True } return chat.send_text("В основе меня лежат цепи маркова, а обучен я на фанфиках, книгах по " "программированию и ветхом завете. \n" "Можешь попробовать поговорить со мной.\n" "На любую вашу фразу я отвечу каким-то бредом.", reply_markup=json.dumps(keyboard))
def usage(chat: Chat, match): log(chat) text = ( "﷽\n" "Send the number of a surah and I'll send you its audio recitation by " "Shaykh Mahmoud Khalil al-Husary. For example send <b>36</b> and you'll " "receive the recitation of surah Yasin. Send /index to see a list of available surahs.\n\n" "Talk to @BismillahBot for an English translation, tafsir and Arabic of individual verses." ) return chat.send_text(text, parse_mode="HTML")
async def message(chat: aiotg.Chat, match): db_chat: Chat = await Chat.get(str(chat.id)) if not db_chat: db_chat: Chat = await create_chat_in_db(chat) if chat.message['chat']['type'] == 'group': pass if db_chat.chat_state == ChatState.EXPECT_TIME_WHEN_SEND_NOTIFY: try: hours, minutes = map(int, chat.message['text'].split(':')) from datetime import time time = time(hours, minutes, 0) except Exception: return chat.reply('Что-то не очень похоже на время. что то типа "12:22" я бы понял.') await db_chat.update( chat_state=ChatState.NORMAL, notify_next_date_time=datetime.combine( db_chat.notify_next_date_time.date(), time ), editing_task_id=None ).apply() return chat.reply(f'Устновлено время уведомления - {time:%H:%M}') elif db_chat.chat_state == ChatState.EXPECT_TASK: editing_task = await Task.create( content=chat.message['text'], message_id=str(chat.message['message_id']), chat_id=str(chat.id) ) await db_chat.update( chat_state=ChatState.EXPECT_PERIOD, editing_task_id=editing_task.id ).apply() return chat.reply('Теперь введите периодичность в днях (просто целое число!)') elif db_chat.chat_state == ChatState.EXPECT_PERIOD and db_chat.editing_task_id: try: period = int(chat.message['text']) except Exception: return chat.reply('Что-то не очень похоже на число. что то типа "5" я бы понял, но не это.') task: Task = await Task.get(db_chat.editing_task_id) await db_chat.update(chat_state=ChatState.NORMAL, editing_task_id=None).apply() if not task: chat.reply(f"Уже такой задачи нет. ({db_chat.editing_task_id})") await task.update(period_days=period).apply() return chat.send_text( f'Устанавливлен период {period} {plural_days(period)}.', reply_to_message_id=task.message_id ) return chat.reply('не ожидал что ты что-то мне ' 'тут напишешь без предупреждения ' '(без запроса). Или я что-то не понял.')
async def echo(chat: Chat, match): help_text = """ /help - для получения справки /proff ФИО - для получения текущего местоположения интересующей вас личности ха-ха-ха рефакторнуть еще можно написать "Где Гапанюк" и узнать /find откуда куда - для получения карты сокровищ ха-ха-ха рефакторнуть еще можно написать "как пройти от до" /where номер помещения - показать на карте нужный кабинет /all - общий план помещения eще можно написать "план" """.strip() return chat.send_text(help_text)
async def callback_set_new_perio(chat: aiotg.Chat, cb: aiotg.CallbackQuery, match: re.Match): task: Task = await Task.get(int(match.group(1))) db_chat: Chat = await Chat.get(str(chat.id)) if not task: text = f"Странно, но такой задачи у меня нет (ИД={task.id})" return await cb.answer(text=text, show_alert=True) await db_chat.update( chat_state=ChatState.EXPECT_PERIOD, editing_task_id=task.id ).apply() text = f"Теперь введите периодичность в днях (просто целое число!) для задачи \"{task.content}\"" await asyncio.gather(chat.send_text(text), cb.answer(text=text, show_alert=False))
async def find_path(chat: Chat, match): async with bot._db_conn.acquire() as conn: query = """ SELECT * FROM cabinet WHERE cabinet.name='{}' AND cabinet.auditoria='1' LIMIT 1; """.format(match.group(1)) start = await (await conn.execute(query)).fetchone() query = """ SELECT * FROM cabinet WHERE cabinet.name='{}' AND cabinet.auditoria='1' LIMIT 1; """.format(match.group(2)) end = await (await conn.execute(query)).fetchone() if not start: return chat.reply('Увы, я не знаю где находится {}'.format( match.group(1))) if not end: return chat.reply('Увы, я не знаю где находится {}'.format( match.group(2))) filename = 'bmstuplan_{}_to_{}'.format(start.id, end.id) command = 'python "bmstumap_admin/manage.py" createpath {} {}'.format( start.id, end.id) foutput = _check(filename, command) log.debug('sending file {}'.format(foutput)) with open(foutput, 'rb') as file: await chat.send_photo(file) await asyncio.wait(0)
def test_send_methods(): bot = MockBot() chat_id = 42 chat = Chat(bot, chat_id) chat.send_audio(b"foo") assert "sendAudio" in bot.calls chat.send_voice(b"foo") assert "sendVoice" in bot.calls chat.send_photo(b"foo") assert "sendPhoto" in bot.calls chat.send_video(b"foo") assert "sendVideo" in bot.calls chat.send_document(b"foo") assert "sendDocument" in bot.calls chat.send_location(13.0, 37.0) assert "sendLocation" in bot.calls chat.send_venue(13.0, 37.0, b"foo", b"foo") assert "sendVenue" in bot.calls chat.send_contact("+79260000000", b"foo") assert "sendContact" in bot.calls chat.send_chat_action("typing") assert "sendChatAction" in bot.calls