import vk_api import gspread import schedule import threading import random import time import configparser import os import itertools import requests import logging import pymorphy2 import json import apiai from datetime import datetime, timedelta from pytz import timezone from tzlocal import get_localzone from oauth2client.service_account import ServiceAccountCredentials from vk_api.bot_longpoll import VkBotEventType, VkBotLongPoll try: os.remove('vk_bot.log') except: pass logging.basicConfig(format=u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s', level=logging.DEBUG, filename=u'vk_bot.log') try: from botnotifications import BotNotifications except Exception as e: logging.exception('Обнаружена ошибка в ходе импортирования модуля botnotifications: ' + str(e)) bn = BotNotifications() morph = pymorphy2.MorphAnalyzer() vk_session = vk_api.VkApi(token='7831e0ef06ed36e2b693a20fa627ca396c90f792e89a8210379336df4b90c9e64e8c16ac3978ca0060175') vk_session._auth_token() vk = vk_session.get_api() game_status_list = ['+', '?', '-', '~'] me_status_list = ['+', '?', '-'] withme_people_count_list = list(map(str, [count for count in range(10)])) class MyVkBotLongPoll(VkBotLongPoll): def listen(self): while True: try: for event in self.check(): yield event except Exception as e: logging.exception('Обнаружена ошибка: ' + str(e)) def createConfig(path): config = configparser.ConfigParser() if path == 'options.ini': config.add_section('General Options') config.add_section('Members Info') config.add_section('Registration Data') bot_name = vk.groups.getById(group_id=180404014)[0]['name'] bot_gender = morph.parse(bot_name)[0].tag.gender config.set('General Options', 'bot_name', bot_name) config.set('General Options', 'bot_gender', str(bot_gender)) config.set('General Options', 'timezone', '0') config.set('General Options', 'timesleep', '50') response = requests.get('https://quizplease.ru/api/game?city_id=6') json_response = json.loads(response.content.decode('utf-8'))['data'] gameIDs = [game['id'] for game in json_response] config.set('General Options', 'last_game_id', str(max(gameIDs))) members_of_chat = list(map(str, [item['member_id'] for item in vk.messages.getConversationMembers(peer_id = 2000000003).get('items') if item['member_id'] > 0])) config.set('Members Info', 'members_of_chat', ', '.join(members_of_chat)) members_of_bot = list(map(str, vk.groups.getMembers(group_id = 180404014).get('items'))) qp_members_of_chat = list(set(members_of_chat) & set(members_of_bot)) members_of_bot_info = str() for id in members_of_bot: response = vk.users.get(user_id=int(id), fields=['bdate']) user_name = response[0]['first_name'] user_full_name = response[0]['first_name'] + ' ' + response[0]['last_name'] try: bdate = response[0]['bdate'] except: pass response = vk.users.get(user_id=int(id), name_case='gen') gen_user_full_name = response[0]['first_name'] + ' ' + response[0]['last_name'] if bdate: members_of_bot_info += id + ',' + user_full_name + ',' + user_name + ',' + gen_user_full_name + ',' + bdate + ';' else: members_of_bot_info += id + ',' + user_full_name + ',' + user_name + ',' + gen_user_full_name + ';' config.set('Members Info', 'qp_members_of_chat', ', '.join(qp_members_of_chat)) config.set('Members Info', 'members_of_bot', ', '.join(members_of_bot)) config.set('Members Info', 'prev_members_of_bot', ', '.join(members_of_bot)) config.set('Members Info', 'members_of_bot_not_chat', ', '.join(list(set(members_of_bot)-set(qp_members_of_chat)))) config.set('Members Info', 'members_of_bot_info', members_of_bot_info) config.set('Registration Data', 'teamname', 'Чудо-зверята') config.set('Registration Data', 'captainname', 'Арсений') config.set('Registration Data', 'email', 'exnin-jah@yandex.ru') config.set('Registration Data', 'phone', '+7 987 590-78-30') config.set('Registration Data', 'count', '6') with open(path, 'w') as config_file: config.write(config_file) else: config.add_section('JobControl') config.add_section('JobFireTime') config.set('JobControl', 'user_without_status_reminder', 'True') config.set('JobControl', 'not_sure_status_reminder', 'True') config.set('JobControl', 'game_status_reminder', 'True') config.set('JobControl', 'good_luck', 'True') config.set('JobControl', 'delete_game', 'True') config.set('JobControl', 'new_games_detector', 'True') config.set('JobControl', 'update_bot_info', 'True') config.set('JobControl', 'happy_birthday', 'True') config.set('JobControl', 'happy_new_year', 'True') config.set('JobControl', 'bot_birthday', 'True') config.set('JobFireTime', 'user_without_status_reminder_fire_time', '09:00') config.set('JobFireTime', 'not_sure_status_reminder_fire_time', '09:30') config.set('JobFireTime', 'game_status_reminder_fire_time', '10:00') config.set('JobFireTime', 'good_luck_fire_time', '14:00') config.set('JobFireTime', 'delete_game_fire_time', '21:00') config.set('JobFireTime', 'new_games_detector_fire_time', '19:00') config.set('JobFireTime', 'update_bot_info_fire_time', '1') config.set('JobFireTime', 'happy_birthday_fire_time', '08:30') config.set('JobFireTime', 'happy_new_year_fire_time', '00:00') config.set('JobFireTime', 'bot_birthday_fire_time', '08:00') with open(path, 'w') as config_file: config.write(config_file) def codeExecutor(code): try: vk_session.method('execute', {'code': code + 'return;'}) logging.info('Рассылка осуществлена.') except Exception as e: logging.exception('Обнаружена ошибка в ходе осуществления рассылки: %s' % str(e)) def sendMessage(message, id): code = 'var msg = API.messages.send({"peer_id":' + str(id) + ',"message":"' + message + '", "random_id":0});' return code def chatMailing(message, notify): if notify: config = configparser.ConfigParser() config.read('options.ini') qp_chat_members_notifications = ['@id' + id + ' (' + getUserInfo(id)[1] + ')' for id in config.get('Members Info', 'qp_members_of_chat').split(', ')] message = ' '.join(qp_chat_members_notifications) + ' ' + message code = 'var msg = API.messages.send({"peer_id": 2000000003, "message":"' + message + '", "random_id":0});' return code def userMailing(message, exclude_id=int()): config = configparser.ConfigParser() config.read('options.ini') user_ids = list(map(int, config.get('Members Info', 'members_of_bot').split(', '))) if exclude_id: user_ids.remove(exclude_id) code = str() for id in user_ids: code += 'var msg = API.messages.send({"peer_id":' + str(id) + ', "message":"' + message + '", "random_id":0});' return code def shiftUsers(date): config = configparser.ConfigParser() config.read('options.ini') config = configparser.ConfigParser() config.read('games.ini') dont_know_users = config.get(date, '?').split(', ') if config.get(date, '?') else [] code = str() if dont_know_users: wont_come_users = config.get(date, '-').split(', ') if config.get(date, '-') else [] config.set(date, '-', ', '.join(wont_come_users + dont_know_users)) config.set(date, '?', '') for dont_know_user in dont_know_users: user_info = getUserInfo(dont_know_user) code += 'API.messages.send({"peer_id":' + str(user_info[0]) + ', "message":"' + bn.youveBeenShift(date) + '", "random_id":0});' with open('games.ini', 'w') as config_file: config.write(config_file) return code def dateIsCorrect(date): try: date = datetime.strptime(date, '%d.%m.%Y') return True except: return False def getUserInfo(param): if isinstance(param, int): param = str(param) config = configparser.ConfigParser() config.read('options.ini') users_info = [user.split(',') for user in config.get('Members Info', 'members_of_bot_info').split(';')] for user_info in users_info: if str(param) in user_info: return user_info def getBotName(case='nomn'): config = configparser.ConfigParser() config.read('options.ini') bot_name = config.get('General Options', 'bot_name') if case == 'nomn': return bot_name else: try: inflexive_bot_name = morph.parse(bot_name)[0] inflexive_bot_name = inflexive_bot_name.inflect({case}).word return inflexive_bot_name.capitalize() except: return bot_name def getWeekday(date): if datetime.strptime(date, '%d.%m.%Y').weekday() == 0: return 'Понедельник' if datetime.strptime(date, '%d.%m.%Y').weekday() == 1: return 'Вторник' if datetime.strptime(date, '%d.%m.%Y').weekday() == 2: return 'Среда' if datetime.strptime(date, '%d.%m.%Y').weekday() == 3: return 'Четверг' if datetime.strptime(date, '%d.%m.%Y').weekday() == 4: return 'Пятница' if datetime.strptime(date, '%d.%m.%Y').weekday() == 5: return 'Суббота' if datetime.strptime(date, '%d.%m.%Y').weekday() == 6: return 'Воскресенье' def vacantPlaces(date): config = configparser.ConfigParser() config.read('games.ini') come_users = config.get(date, '+').split(', ') if config.get(date, '+') else [] come_others = [record.split(',') for record in config.get(date, 'Системное поле').split(';')] count_come_others = int() if come_others[0][0]: for record in come_others: try: count_come_others += int(record[1]) except: continue return 9 - len(come_users) - count_come_others def findComment(key_list): if len(key_list) > 3: return '<br> <br> Комментарий пользователя: ' + ' '.join(key_list[3:]) else: return '' def translateStatus(op, status): if op == 'qst' or op == 'qinfo': if status == '+': return 'Идем' elif status == '?': return 'Не уверены' elif status == '-': return 'Не идем' else: return 'Резерв' else: if status == '+': return 'Иду' elif status == '?': return 'Не знаю' else: return 'Не иду' def opHelp(file): try: path = os.path.join(os.path.dirname(__file__), 'help', file) help = open(path) except: return bn.unexpectedError() if file == 'help.txt': message = ''.join(help.readlines()).replace('\n', '').format(getBotName(), getBotName(case='gent'), getBotName(case='datv')) else: message = ''.join(help.readlines()).replace('\n', '').format(getBotName()) help.close() return message def USER_WITHOUT_STATUS_REMINDER(): logging.info('Выполнение USER_WITHOUT_STATUS_REMINDER() начато.') config = configparser.ConfigParser() config.read('games.ini') if not config.sections(): logging.info('На данный момент нет игр.') return else: game_dict = {date: config.get(date, '+').split(', ') +\ config.get(date, '?').split(', ') +\ config.get(date, '-').split(', ') for date in config.sections()} config.read('options.ini') members_of_bot = config.get('Members Info', 'members_of_bot').split(', ') qp_members_of_chat = config.get('Members Info', 'qp_members_of_chat').split(', ') for id in members_of_bot: message = str() user_info = getUserInfo(id) first_game_without_status = True for date in game_dict: if vacantPlaces(date) == 0: continue if user_info[1] not in game_dict[date]: if first_game_without_status: if id in qp_members_of_chat: message = '@id' + id + ' (' + user_info[1] + ') игры без вашего статуса: ' + date + ' (' + getWeekday(date) + ')' else: message = user_info[2] + ', игры без вашего статуса: ' + date + ' (' + getWeekday(date) + ')' first_game_without_status = False else: message += ', ' + date + ' (' + getWeekday(date) + ')' if message: if id in qp_members_of_chat: codeExecutor(chatMailing(message + '<br> Постарайтесь проставить статус в ближайшее время.', False)) else: codeExecutor(sendMessage(message + '<br> Постарайтесь проставить статус в ближайшее время.', int(id))) logging.info('Выполнение USER_WITHOUT_STATUS_REMINDER() закончено.') def NOT_SURE_STATUS_REMINDER(): logging.info('Выполнение NOT_SURE_STATUS_REMINDER() начато.') today_date = datetime.today().strftime('%d.%m.%Y') tomorrow_date = (datetime.today() + datetime.timedelta(days=1)).strftime('%d.%m.%Y') dayaftertomorrow_date = (datetime.today() + datetime.timedelta(days=2)).strftime('%d.%m.%Y') three_days_list = [today_date, tomorrow_date, dayaftertomorrow_date] notify_chat_users_str = str() code = str() config = configparser.ConfigParser() config.read('options.ini') qp_members_of_chat = config.get('Members Info', 'qp_members_of_chat').split(', ') config = configparser.ConfigParser() config.read('games.ini') for game_date in config.sections(): if game_date in three_days_list: date = str() if game_date == today_date: date = today_date reminder_message = 'Сегодня состоится очередная игра. Ваш статус - Не знаю. Примите окончательное решение как можно скорее.' elif game_date == tomorrow_date: date = tomorrow_date reminder_message = 'Завтра состоится очередная игра. Ваш статус - Не знаю. Примите окончательное решение как можно скорее.' else: date = dayaftertomorrow_date reminder_message = 'Послезавтра состоится очередная игра. Ваш статус - Не знаю. Примите окончательное решение как можно скорее.' dont_know_users = config.get(date, '?').split(', ') dont_know_users = [] if not dont_know_users[0] else dont_know_users if not dont_know_users or config.get(game_date, 'Статус') == '-': logging.info(date + ': нет пользователей со статусом <?> или статус игры <->.') else: for dont_know_user in dont_know_users: user_id = getUserInfo(dont_know_user)[0] if user_id in qp_members_of_chat: notify_chat_users_str += '@id' + user_id + ' (' + dont_know_user + ') ' else: code += 'var msg = API.messages.send({"peer_id":' + user_id + ', "message":"' + reminder_message + '", "random_id":0});' codeExecutor(chatMailing(notify_chat_users_str + reminder_message, False) + code) logging.info('Выполнение NOT_SURE_STATUS_REMINDER() закончено.') def GAME_STATUS_REMINDER(): logging.info('Выполнение GAME_STATUS_REMINDER() начато.') today_date = datetime.today().strftime('%d.%m.%Y') tomorrow_date = (datetime.today() + datetime.timedelta(days=1)).strftime('%d.%m.%Y') dayaftertomorrow_date = (datetime.today() + datetime.timedelta(days=2)).strftime('%d.%m.%Y') three_days_list = [today_date, tomorrow_date, dayaftertomorrow_date] config = configparser.ConfigParser() config.read('games.ini') for game_date in config.sections(): if game_date in three_days_list and config.get(game_date, 'Статус') == '?': if game_date == today_date: reminder_message = 'Чудо-зверята, сегодня состоится очередная игра. Но статус игры до сих пор Не уверены. Примите окончательное решение как можно скорее.' elif game_date == tomorrow_date: reminder_message = 'Чудо-зверята, завтра состоится очередная игра. Но статус игры до сих пор Не уверены. Примите окончательное решение как можно скорее.' else: reminder_message = 'Чудо-зверята, послезавтра состоится очередная игра. Но статус игры до сих пор Не уверены. Примите окончательное решение как можно скорее.' codeExecutor(chatMailing(reminder_message, False)) logging.info('Выполнение GAME_STATUS_REMINDER() законечно.') def GOOD_LUCK(): logging.info('Выполнение GOOD_LUCK() начато.') config = configparser.ConfigParser() config.read('options.ini') today_date = datetime.today().strftime('%d.%m.%Y') members_of_bot_not_chat = config.get('Members Info', 'members_of_bot_not_chat').split(', ') config = configparser.ConfigParser() config.read('games.ini') if today_date in config.sections(): if config.get(today_date, 'Статус') == '+': good_luck_message = '{}, всего через несколько часов состоится очередная игра. ' +\ 'Хотелось бы пожелать Вам удачи, интересных вопросов и верить в свои ' +\ 'силы до самого конца, несмотря ни на что! Ни пуха, ни пера!' codeExecutor(chatMailing(good_luck_message.format('Чудо-зверята'), False)) for id in members_of_bot_not_chat: user_info = getUserInfo(id) if user_info[1] in config.get(today_date, '+').split(', '): codeExecutor(sendMessage(good_luck_message.format(user_info[2]), int(id))) logging.info('Выполнение GOOD_LUCK() закончено.') else: logging.info('Выполнение GOOD_LUCK() закончено, так как статус игры отличен от <+>.') return else: logging.info('Выполнение GOOD_LUCK() закончено, так как на сегодня игра не запланирована.') return def DELETE_GAME(): logging.info('Выполнение DELETE_GAME() начато.') config = configparser.ConfigParser() config.read('options.ini') today_date = datetime.today().strftime('%d.%m.%Y') timezone = config.getint('General Options', 'timezone') time_now = (datetime.today() + timedelta(hours=timezone)).time() config = configparser.ConfigParser() config.read('games.ini') suitable_game = False for date in config.sections(): if config.get(date, 'Статус') == '-': suitable_game = True config.remove_section(date) logging.info('Удалена игра на ' + date + ', так как статус игры - <->.') elif date == today_date: suitable_game = True time_game = datetime.strptime(config.get(date, 'Время'), '%H:%M').time() if time_now > time_game: config.remove_section(date) logging.info('Удалена игра на ' + date + ', так как статус игра уже началась и, возможно, закончилась.') else: logging.info('Выполнение DELETE_GAME() закончено, так как игра на ' + date + ' еще не состоялась.') if suitable_game: with open('games.ini', 'w') as config_file: config.write(config_file) else: logging.info('Выполнение DELETE_GAME() закончено, так как на сегодня игра не запланирована и игры со статусом <-> не найдены.') def NEW_GAMES_DETECTOR(): config = configparser.ConfigParser() config.read('options.ini') last_game_id = config.getint('General Options', 'last_game_id') response = requests.get('https://quizplease.ru/api/game?expand=place&city_id=6') json_response = json.loads(response.content.decode('utf-8'))['data'] if response.status_code == 200: message = str() new_games_ids = list() for game in json_response: if game['id'] > last_game_id: date = datetime.strptime(game['datetime'].split(' ')[0], '%d.%m.%y').strftime('%d.%m.%Y') message += 'Название игры: ' + game['title'] + ' ' + game['name'] + '<br>' +\ 'Дата игры: ' + date + ' (' + getWeekday(date) + ')' + '<br>' +\ 'Время игры: ' + game['format_time'] + '<br>' +\ 'Место: ' + game['place']['title'] + '<br>' +\ 'Адрес: ' + game['place']['address'] + '<br>' +\ 'Цена: ' + game['format_price'] + '<br>' +\ 'Описание: ' + game['description'] + '<br>' if game['status']['id'] == 1: message += 'Статус: Есть места' + '<br> <br>' elif game['status']['id'] == 2: message += 'Статус: Только резерв' + '<br> <br>' else: message += 'Статус: Мест нет' + '<br> <br>' new_games_ids.append(game['id']) message += 'Для регистрации на новую игру введите команду qreg в формате qreg дд.мм.гггг. ' +\ 'Для просмотра информации по всем доступным играм введите команду qgames.' if not new_games_ids: return else: config.set('General Options', 'last_game_id', str(max(new_games_ids))) with open('options.ini', 'w') as config_file: config.write(config_file) if len(new_games_ids) == 1: codeExecutor(chatMailing('на сайте quizplease.ru появилась новая игра! <br> <br>' + message.replace('"', ''), True)) else: codeExecutor(chatMailing('на сайте quizplease.ru появились новые игры! <br> <br>' + message.replace('"', ''), True)) else: logging.error(json_response['message']) def UPDATE_BOT_INFO(): logging.info('Выполнение UPDATE_BOT_INFO() начато.') config = configparser.ConfigParser() config.read('options.ini') bot_name = vk.groups.getById(group_id=180404014)[0]['name'] if config.get('General Options', 'bot_name') != bot_name: bot_gender = morph.parse(bot_name)[0].tag.gender config.set('General Options', 'bot_name', bot_name) config.set('General Options', 'bot_gender', str(bot_gender)) with open('options.ini', 'w') as config_file: config.write(config_file) members_of_chat = list(map(str, [item['member_id'] for item in vk.messages.getConversationMembers(peer_id = 2000000003).get('items') if item['member_id'] > 0])) members_of_bot = list(map(str, vk.groups.getMembers(group_id = 180404014).get('items'))) if config.get('Members Info', 'prev_members_of_bot') == ', '.join(list(map(str, members_of_bot))): logging.info('Выполнение UPDATE_BOT_INFO() законечно, так как изменений в составе группы бота не найдено.') return qp_members_of_chat = list(set(members_of_chat) & set(members_of_bot)) members_of_bot_info = str() for id in members_of_bot: response = vk.users.get(user_id=int(id), fields='bdate') user_name = response[0]['first_name'] user_full_name = response[0]['first_name'] + ' ' + response[0]['last_name'] try: bdate = response[0]['bdate'] except: bdate = str() response = vk.users.get(user_id=int(id), name_case='gen') gen_user_full_name = response[0]['first_name'] + ' ' + response[0]['last_name'] if bdate: members_of_bot_info += id + ',' + user_full_name + ',' + user_name + ',' + gen_user_full_name + ',' + bdate + ';' else: members_of_bot_info += id + ',' + user_full_name + ',' + user_name + ',' + gen_user_full_name + ';' config.set('Members Info', 'members_of_bot_info', members_of_bot_info) config.set('Members Info', 'members_of_bot', ', '.join(members_of_bot)) config.set('Members Info', 'prev_members_of_bot', ', '.join(members_of_bot)) config.set('Members Info', 'qp_members_of_chat', ', '.join(qp_members_of_chat)) config.set('Members Info', 'members_of_bot_not_chat', ', '.join(list(set(members_of_bot)-set(qp_members_of_chat)))) with open('options.ini', 'w') as config_file: config.write(config_file) logging.info('Выполнение UPDATE_BOT_INFO() законечно.') def HAPPY_BIRTHDAY(): logging.info('Выполнение HAPPY_BIRTHDAY() начато.') config = configparser.ConfigParser() config.read('options.ini') members_of_bot = config.get('Members Info', 'members_of_bot').split(', ') qp_members_of_chat = config.get('Members Info', 'qp_members_of_chat').split(', ') for id in members_of_bot: user_info = getUserInfo(id) user_full_name = user_info[1] user_name = user_info[2] try: bdate = user_info[5].split('.') except: continue if int(bdate[0]) == datetime.now().day and int(bdate[1]) == datetime.now().month: message = 'с днем рождения! Желаю вам всего наилучшего! :)' if id in qp_members_of_chat: codeExecutor(chatMailing('@id' + str(id) + ' (' + user_full_name + ') ' + message, False)) else: codeExecutor(sendMessage(user_name + ', ' + message, int(id))) else: continue logging.info('Выполнение HAPPY_BIRTHDAY() закончено.') def HAPPY_NEW_YEAR(): logging.info('Выполнение HAPPY_NEW_YEAR() начато.') if datetime.now().day == 1 and datetime.now().month == 1: config = configparser.ConfigParser() config.read('options.ini') members_of_bot_not_chat = config.get('Members Info', 'members_of_bot_not_chat').split(', ') message = '{}, с Новым ' + str(datetime.now().year) + ' годом!' codeExecutor(chatMailing(message.format('Чудо-зверята'), False)) for id in members_of_bot_not_chat: user_name = getUserInfo(id)[2] codeExecutor(sendMessage(message.format(user_name), int(id))) logging.info('Выполнение HAPPY_NEW_YEAR() закончено.') def BOT_BIRTHDAY(): logging.info('Выполнение BOT_BIRTHDAY() начато.') if datetime.now().day == 30 and datetime.now().month == 3: config = configparser.ConfigParser() config.read('options.ini') members_of_bot_not_chat = config.get('Members Info', 'members_of_bot_not_chat').split(', ') message = '{}, ровно ' + str(datetime.now().year - 2019) + ' год назад я родилась!' codeExecutor(chatMailing(message.format('Чудо-зверята'), False)) for id in members_of_bot_not_chat: user_name = getUserInfo(id)[2] codeExecutor(sendMessage(message.format(user_name), int(id))) logging.info('Выполнение BOT_BIRTHDAY() закончено.') def do_jobs(): config = configparser.ConfigParser() config.read('jobconfig.ini') last_mtime = 0 keep_going = True while keep_going: current_mtime = os.path.getmtime('jobconfig.ini') if current_mtime > last_mtime: jobs_info = 'Предыдущее состояние schedule:' + '\n' for job in schedule.jobs: jobs_info += str(job) + '\n' logging.info(jobs_info) schedule.clear() config = configparser.ConfigParser() config.read('jobconfig.ini') user_without_status_reminder_fire_time = config.get('JobFireTime', 'user_without_status_reminder_fire_time') not_sure_status_reminder_fire_time = config.get('JobFireTime', 'not_sure_status_reminder_fire_time') game_status_reminder_fire_time = config.get('JobFireTime', 'game_status_reminder_fire_time') good_luck_fire_time = config.get('JobFireTime', 'good_luck_fire_time') delete_game_fire_time = config.get('JobFireTime', 'delete_game_fire_time') new_games_detector_fire_time = config.get('JobFireTime', 'new_games_detector_fire_time') update_bot_info_fire_time = config.getint('JobFireTime', 'update_bot_info_fire_time') happy_birthday_fire_time = config.get('JobFireTime', 'happy_birthday_fire_time') happy_new_year_fire_time = config.get('JobFireTime', 'happy_new_year_fire_time') bot_birthday_fire_time = config.get('JobFireTime', 'bot_birthday_fire_time') user_without_status_reminder_should_fire = config.getboolean('JobControl', 'user_without_status_reminder') not_sure_status_reminder_should_fire = config.getboolean('JobControl', 'not_sure_status_reminder') game_status_reminder_should_fire = config.getboolean('JobControl', 'game_status_reminder') good_luck_should_fire = config.getboolean('JobControl', 'good_luck') delete_game_should_fire = config.getboolean('JobControl', 'delete_game') new_games_detector_should_fire = config.getboolean('JobControl', 'new_games_detector') update_bot_info_should_fire = config.getboolean('JobControl', 'update_bot_info') happy_birthday_should_fire = config.getboolean('JobControl', 'happy_birthday') happy_new_year_should_fire = config.getboolean('JobControl', 'happy_new_year') bot_birthday_should_fire = config.getboolean('JobControl', 'bot_birthday') if user_without_status_reminder_should_fire: schedule.every().day.at(user_without_status_reminder_fire_time).do(USER_WITHOUT_STATUS_REMINDER) if not_sure_status_reminder_should_fire: schedule.every().day.at(not_sure_status_reminder_fire_time).do(NOT_SURE_STATUS_REMINDER) if game_status_reminder_should_fire: schedule.every().day.at(game_status_reminder_fire_time).do(GAME_STATUS_REMINDER) if good_luck_should_fire: schedule.every().day.at(good_luck_fire_time).do(GOOD_LUCK) if delete_game_should_fire: schedule.every().day.at(delete_game_fire_time).do(DELETE_GAME) if new_games_detector_should_fire: schedule.every().day.at(new_games_detector_fire_time).do(NEW_GAMES_DETECTOR) if update_bot_info_should_fire: schedule.every(update_bot_info_fire_time).minutes.do(UPDATE_BOT_INFO) if happy_birthday_should_fire: schedule.every().day.at(happy_birthday_fire_time).do(HAPPY_BIRTHDAY) if happy_new_year_should_fire: schedule.every().day.at(happy_new_year_fire_time).do(HAPPY_NEW_YEAR) if bot_birthday_should_fire: schedule.every().day.at(bot_birthday_fire_time).do(BOT_BIRTHDAY) jobs_info = 'Текущее состояние schedule:' + '\n' for job in schedule.jobs: jobs_info += str(job) + '\n' logging.info(jobs_info) last_mtime = current_mtime config = configparser.ConfigParser() config.read('options.ini') timesleep = config.getint('General Options', 'timesleep') try: schedule.run_pending() time.sleep(timesleep) except Exception as e: keep_going = False logging.exception('В потоке джобов обнаружена ошибка: ' + str(e)) codeExecutor(sendMessage('В потоке джобов обнаружена ошибка: ' + str(e), 60569725)) def listen_server(): for event in MyVkBotLongPoll(vk_session, 180404014).listen(): if event.type == VkBotEventType.MESSAGE_NEW and event.object.text: peer_id = event.object.peer_id from_id = event.object.from_id if peer_id != from_id: if not event.object.text.startswith('[club180404014|'): continue else: config = configparser.ConfigParser() config.read('options.ini') if from_id not in list(map(int, config.get('Members Info', 'members_of_bot').split(', '))): codeExecutor(sendMessage(bn.accessDenied()), peer_id) continue new_message = event.object.text.replace('[club180404014|@club180404014], ', '') new_message = event.object.text.replace('[club180404014|' + getBotName() + '] ', '') else: new_message = event.object.text logging.info('Новое сообщение от ' + getUserInfo(from_id)[3] + ': ' + new_message) new_message_list = new_message.split(' ') logging.info('Список ключей сообщения: ' + str(new_message_list)) '''-------------------------------------------------------------------HELP ВЫЗОВ СПРАВКИ ПО ИСПОЛЬЗОВАНИЮ БОТА-----------------------------------------------------------------''' if new_message_list[0].lower() == 'help' and len(new_message_list) == 1: codeExecutor(sendMessage(opHelp('help.txt'), peer_id)) '''---------------------------------------------------------------NEWS РАССЫЛКА НОВОСТЕЙ ПОЛЬЗОВАТЕЛЯМ БОТА-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'news' and len(new_message_list) > 1 and peer_id == from_id: if from_id != 60569725: codeExecutor(sendMessage(bn.accessDenied(), peer_id)) continue message_to_users = ' '.join(new_message_list[1:]).replace('\n', '<br>') codeExecutor(userMailing(message_to_users, from_id) +\ sendMessage(bn.newsPublished(), 60569725)) '''-----------------------------------------------------IWISH РЕГИСТРАЦИЯ ПОЖЕЛАНИЙ ПОЛЬЗОВАТЕЛЕЙ БОТА ПО ЕГО УЛУЧШЕНИЮ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'iwish': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) > 1: wish_message = ' '.join(new_message_list[1:]) user_name = getUserInfo(from_id)[1] date = datetime.today().strftime('%d.%m.%Y') task_num = str() config = configparser.ConfigParser() config.read('tasks.ini') if config.sections(): task_num = str(int(config.sections()[-1]) + 1) if len(task_num) == 3: task_num = '0' + task_num if len(task_num) == 2: task_num = '00' + task_num if len(task_num) == 1: task_num = '000' + task_num else: task_num = '0001' config.add_section(task_num) config.set(task_num, 'Описание', wish_message) config.set(task_num, 'Автор', user_name) config.set(task_num, 'Дата создания', date) with open('tasks.ini', 'w') as config_file: config.write(config_file) code = str() if from_id != 60569725: code = sendMessage(bn.newRequest(task_num, user_name), 60569725) code += sendMessage(bn.requestRegistered(task_num), peer_id) codeExecutor(code) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''-----------------------------------------------------MYTASKS ВОЗВРАЩАЕТ ВСЕ ТЕКУЩИЕ ЗАЯВКИ ПО УЛУЧШЕНИЮ БОТА-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'mytasks' and len(new_message_list) == 1: if from_id != 60569725: codeExecutor(sendMessage(bn.accessDenied(), peer_id)) continue config = configparser.ConfigParser() config.read('tasks.ini') if not config.sections(): codeExecutor(sendMessage(bn.noRequests(), 60569725)) continue message = str() for task_num in config.sections(): message += 'Номер заявки: ' + task_num + '<br>' +\ 'Описание: ' + config.get(task_num, 'Описание') + '<br>' +\ 'Автор: ' + config.get(task_num, 'Автор') + '<br>' +\ 'Дата создания: ' + config.get(task_num, 'Дата создания') + '<br>' + '<br>' codeExecutor(sendMessage(message, 60569725)) '''---------------------------------------------------------------EDITASK РЕДАКТИРУЕТ ЗАЯВКУ ПО ЕЁ НОМЕРУ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'editask' and len(new_message_list) > 2: if from_id != 60569725: codeExecutor(sendMessage(bn.accessDenied(), peer_id)) continue config = configparser.ConfigParser() config.read('tasks.ini') task_num = new_message_list[1] if task_num not in config.sections(): codeExecutor(sendMessage(bn.noSuchRequest(), 60569725)) continue config.set(task_num, 'Описание', ' '.join(new_message_list[2:])) with open('tasks.ini', 'w') as config_file: config.write(config_file) codeExecutor(sendMessage(bn.requestEdited(), 60569725)) '''---------------------------------------------------------------DELTASK УДАЛЯЕТ ЗАЯВКУ ПО ЕЁ НОМЕРУ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'deltask' and len(new_message_list) == 2: if from_id != 60569725: codeExecutor(sendMessage(bn.accessDenied(), peer_id)) continue config = configparser.ConfigParser() config.read('tasks.ini') task_num = new_message_list[1] if task_num not in config.sections(): codeExecutor(sendMessage(bn.noSuchRequest(), 60569725)) continue config.remove_section(task_num) with open('tasks.ini', 'w') as config_file: config.write(config_file) codeExecutor(sendMessage(bn.requestDeleted(), 60569725)) '''---------------------------------------------------------TASK ВОЗВРАЩАЕТ ИНФОРМАЦИЮ О ЗАЯВКЕ ПО ЕЁ НОМЕРУ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'task' and len(new_message_list) == 2: if from_id != 60569725: codeExecutor(sendMessage(bn.accessDenied(), peer_id)) continue config = configparser.ConfigParser() config.read('tasks.ini') task_num = new_message_list[1] if task_num not in config.sections(): codeExecutor(sendMessage(bn.noSuchRequest(), 60569725)) continue message = 'Номер заявки: ' + task_num + '<br>' +\ 'Описание: ' + config.get(task_num, 'Описание') + '<br>' +\ 'Автор: ' + config.get(task_num, 'Автор') + '<br>' +\ 'Дата создания: ' + config.get(task_num, 'Дата создания') + '<br>' + '<br>' codeExecutor(sendMessage(message, 60569725)) '''--------------------------------------------QUPDI QUPDP QUPDT ОБНОВЛЯЮТ ДОПОЛНИТЕЛЬНУЮ ИНФОРМАЦИЮ ПО ИГРЕ, МЕСТО ИГРЫ, ВРЕМЯ ИГРЫ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'qupdi' or new_message_list[0].lower() == 'qupdp' or new_message_list[0].lower() == 'qupdt': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) >= 3: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date not in config.sections(): codeExecutor(sendMessage(bn.noGame(), peer_id)) continue if config.get(date, 'Статус') == '-': codeExecutor(sendMessage(bn.cantEdit(), peer_id)) continue info = ' '.join(new_message_list[2:]) user_info = getUserInfo(from_id) operation = new_message_list[0].lower() if operation == 'qupdi': config.set(date, 'Дополнительная информация', info) message = bn.addinfoUpdated(date, info) elif operation == 'qupdp': config.set(date, 'Место', info) message = bn.placeUpdated(date, info) else: config.set(date, 'Время', info) message = bn.timeUpdated(date, info) with open('games.ini', 'w') as config_file: config.write(config_file) codeExecutor(userMailing(message, from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''--------------------------------------------------------------QDATES ВОЗВРАЩАЕТ ДАТЫ ЗАПЛАНИРОВАННЫХ ИГР-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'qdates': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 1: config = configparser.ConfigParser() config.read('games.ini') if not config.sections(): codeExecutor(sendMessage(bn.noGames(), peer_id)) continue game_dates = str() for date in config.sections(): game_dates += date + ' (' + getWeekday(date) + ')' + '<br>' codeExecutor(sendMessage(game_dates, peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''---------------------------------------------------------QINFO ВОЗВРАЩАЕТ СВЕДЕНИЯ О КОНКРЕТНОЙ ИГРЕ ПО ЕЁ ИГРЫ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'qinfo': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date not in config.sections(): codeExecutor(sendMessage(bn.noGame(), peer_id)) continue withme_list = [sublist.split(',') for sublist in config.get(date, 'Системное поле').split(';')] game_info = 'Место: ' + config.get(date, 'Место') + '<br>' +\ 'Время: ' + config.get(date, 'Время') + '<br>' +\ 'Доп. инфо по игре: ' + config.get(date, 'Дополнительная информация') + '<br>' +\ 'Идут: ' + config.get(date, '+') for element in withme_list[:-1]: if game_info.endswith('Идут: '): game_info += element[1] + ' человек(а) от ' + getUserInfo(int(element[0]))[3] else: game_info += ', ещё ' + element[1] + ' человек(а) от ' + getUserInfo(int(element[0]))[3] game_info += '<br> Не уверены: ' + config.get(date, '?') + '<br>' +\ 'Не идут: ' + config.get(date, '-') + '<br>' +\ 'Статус: ' + translateStatus('qinfo', config.get(date, 'Статус')) + '<br>' +\ 'Количество свободных мест: ' + str(vacantPlaces(date)) + ' из 9' codeExecutor(sendMessage(game_info, peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''------------------------------------------------------------QST УСТАНАВЛИВАЕТ СТАТУС ИГРЫ ПО ЕЁ ДАТЕ----------------------------------------------------------''' elif new_message_list[0].lower() == 'qst': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) > 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue status = new_message_list[2] if status not in game_status_list: codeExecutor(sendMessage(bn.gameIncorrectStatus(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date not in config.sections(): codeExecutor(sendMessage(bn.noGame(), peer_id)) continue if status == config.get(date, 'Статус'): codeExecutor(sendMessage(bn.sameGameStatus(), peer_id)) continue config.set(date, 'Статус', status) with open('games.ini', 'w') as config_file: config.write(config_file) codeExecutor(userMailing(bn.statusUpdated(date, translateStatus('qst', status)) + findComment(new_message_list), from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''-----------------------------------------------------------------QDEL УДАЛЯЕТ ИГРУ ПО ЕЁ ДАТЕ----------------------------------------------------------''' elif new_message_list[0].lower() == 'qdel': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date not in config.sections(): codeExecutor(sendMessage(bn.noGame(), peer_id)) continue config.remove_section(date) with open('games.ini', 'w') as config_file: config.write(config_file) codeExecutor(userMailing(bn.gameRemoved(date), from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''-----------------------------------------------------------QNEW СОЗДАЁТ НОВУЮ ИГРУ С УКАЗАНИЕМ ЕЁ ДАТЫ----------------------------------------------------------''' elif new_message_list[0].lower() == 'qnew': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date in config.sections(): codeExecutor(sendMessage(bn.gameExists(), peer_id)) continue config.add_section(date) config.set(date, 'Место', 'Дорогая, я перезвоню') if getWeekday(date) == 'Суббота' or getWeekday(date) == 'Воскресенье': config.set(date, 'Время', '18:00') else: config.set(date, 'Время', '19:30') config.set(date, 'Дополнительная информация', '') config.set(date, '+', '') config.set(date, '?', '') config.set(date, '-', '') config.set(date, 'Статус', '?') config.set(date, 'Системное поле', '') with open('games.ini', 'w') as config_file: config.write(config_file) codeExecutor(userMailing(bn.gameAdded(date), from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''---------------------------------------------------------------QME УСТАНАВЛИВАЕТ СТАТУС ПО ЧЕЛОВЕКУ----------------------------------------------------------''' elif new_message_list[0].lower() == 'qme': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) > 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date not in config.sections(): codeExecutor(sendMessage(bn.noGame(), peer_id)) continue if config.get(date, 'Статус') == '-': codeExecutor(sendMessage(bn.cantEdit(), peer_id)) continue decision = new_message_list[2] if decision not in me_status_list: codeExecutor(sendMessage(bn.meIncorrectStatus(), peer_id)) continue full_name = getUserInfo(from_id)[1] me_dict = dict() for status in me_status_list: status_list = config.get(date, status).split(', ') if config.get(date, status) else [] for user in status_list: me_dict.update({user: status}) no_more_place = False if full_name in me_dict: if decision == me_dict[full_name]: codeExecutor(sendMessage(bn.decisionMade(), peer_id)) continue if decision == '?' and me_dict[full_name] == '-' and vacantPlaces(date) == 0: codeExecutor(sendMessage(bn.noVacantPlaces(), peer_id)) continue if decision == '+' and vacantPlaces(date) == 0: codeExecutor(sendMessage(bn.noVacantPlaces(), peer_id)) continue if decision == '+' and vacantPlaces(date) == 1: no_more_place = True me_dict.update({full_name: decision}) willgo_list, notsure_list, wontgo_list = list(), list(), list() for user_name, status in me_dict.items(): if status == '+': willgo_list.append(user_name) elif status == '?': notsure_list.append(user_name) else: wontgo_list.append(user_name) config.set(date, '+', ', '.join(willgo_list)) if willgo_list else config.set(date, '+', '') config.set(date, '?', ', '.join(notsure_list)) if notsure_list else config.set(date, '?', '') config.set(date, '-', ', '.join(wontgo_list)) if wontgo_list else config.set(date, '-', '') with open('games.ini', 'w') as config_file: config.write(config_file) if no_more_place: codeExecutor(userMailing(bn.meUpdated(date, translateStatus('qme', decision), full_name) + findComment(new_message_list), from_id) +\ shiftUsers(date) + sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(userMailing(bn.meUpdated(date, translateStatus('qme', decision), full_name) + findComment(new_message_list), from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''--------------------------------------------------WITHME ЗАПИСЫВАЕТ КОЛИЧЕСТВО ЧЕЛОВЕК, ИДУЩИХ С ТОБОЙ НА ИГРУ С УКАЗАНИЕМ ЕЁ ДАТЫ-------------------------------------------------------------------''' elif new_message_list[0].lower() == 'withme': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) > 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date not in config.sections(): codeExecutor(sendMessage(bn.noGame(), peer_id)) continue if config.get(date, 'Статус') == '-': codeExecutor(sendMessage(bn.cantEdit(), peer_id)) continue full_name = getUserInfo(from_id)[1] me_list = config.get(date, '+').split(', ') +\ config.get(date, '?').split(', ') +\ config.get(date, '-').split(', ') if full_name not in me_list: codeExecutor(sendMessage(bn.withoutStatus(), peer_id)) continue people_count = new_message_list[2] if people_count not in withme_people_count_list: codeExecutor(sendMessage(bn.incorrectCount(), peer_id)) continue withme_dict = dict() for record in config.get(date, 'Системное поле').split(';'): if record: withme_dict.update({record.split(',')[0]: record.split(',')[1]}) no_more_place = False if not withme_dict or str(from_id) not in withme_dict: if people_count == '0': codeExecutor(sendMessage(bn.nullNotAllowed(), peer_id)) continue else: if vacantPlaces(date) == 0: codeExecutor(sendMessage(bn.noVacantPlaces(), peer_id)) continue if int(people_count) > vacantPlaces(date): codeExecutor(sendMessage(bn.fewVacantPlaces(str(vacantPlaces(date))), peer_id)) continue if int(people_count) == vacantPlaces(date): no_more_place = True withme_dict.update({str(from_id): people_count}) else: if people_count == '0': if str(from_id) in withme_dict: withme_dict.pop(str(from_id)) else: codeExecutor(sendMessage(bn.nullNotAllowed(), peer_id)) continue else: if people_count == withme_dict[str(from_id)]: codeExecutor(sendMessage(bn.recordExists(), peer_id)) continue if vacantPlaces(date) == 0 and int(people_count) > int(withme_dict[str(from_id)]): codeExecutor(sendMessage(bn.noVacantPlaces(), peer_id)) continue if int(people_count) > vacantPlaces(date) + int(withme_dict[str(from_id)]): codeExecutor(sendMessage(bn.fewVacantPlaces(str(vacantPlaces(date))), peer_id)) continue if int(people_count) == vacantPlaces(date) + int(withme_dict[str(from_id)]): no_more_place = True withme_dict.pop(str(from_id)) withme_dict.update({str(from_id): people_count}) withme_updated_string = str() for id, count in withme_dict.items(): withme_updated_string += id + ',' + count + ';' config.set(date, 'Системное поле', withme_updated_string) with open('games.ini', 'w') as config_file: config.write(config_file) if no_more_place: codeExecutor(userMailing(bn.withmeUpdated(date, full_name, people_count) + findComment(new_message_list), from_id) +\ shiftUsers(date) + sendMessage(bn.infoUpdated(), peer_id)) else: if people_count == '0': codeExecutor(userMailing(bn.withmeDeleted(date, full_name) + findComment(new_message_list), from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(userMailing(bn.withmeUpdated(date, full_name, people_count) + findComment(new_message_list), from_id) +\ sendMessage(bn.infoUpdated(), peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''---------------------------------------------------------------QGAMES возвращает информацию по всем имеющимся играм с сайта quizplease.ru----------------------------------------------------------------''' elif new_message_list[0].lower() == 'qgames': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 1: config = configparser.ConfigParser() config.read('games.ini') response = requests.get('https://quizplease.ru/api/game?expand=place&city_id=6') json_response = json.loads(response.content.decode('utf-8'))['data'] if response.status_code == 200: message = str() for game in json_response: date = datetime.strptime(game['datetime'].split(' ')[0], '%d.%m.%y').strftime('%d.%m.%Y') message += 'Название игры: ' + game['title'] + ' ' + game['name'] + '<br>' +\ 'Дата игры: ' + date + ' (' + getWeekday(date) + ') <br>' +\ 'Время игры: ' + game['format_time'] + '<br>' +\ 'Место: ' + game['place']['title'] + '<br>' +\ 'Адрес: ' + game['place']['address'] + '<br>' +\ 'Цена: ' + game['format_price'] + '<br>' +\ 'Описание: ' + game['description'] + '<br>' if str(game['status']['id']) == '1': message += 'Статус: Есть места <br>' elif str(game['status']['id']) == '2': message += 'Статус: Только резерв <br>' else: message += 'Статус: Мест нет' + '<br>' if date in config.sections(): message += 'Чудо-зверята: Зарегистрированы <br> <br>' else: message += 'Чудо-зверята: Не зарегистрированы <br> <br>' if message: message += 'Для регистрации на новую игру введите команду qreg в формате qreg дд.мм.гггг.' codeExecutor(sendMessage(message.replace('"', ''), peer_id)) else: codeExecutor(sendMessage(bn.noQpGames(), peer_id)) else: codeExecutor(sendMessage(json_response['message'], peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''----------------------------------------------------------------QREG регистрирует нас на игру с указанием даты игры в формате ДД.ММ.ГГГГ-----------------------------------------------------------------''' elif new_message_list[0].lower() == 'qreg': if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') if date in config.sections(): codeExecutor(sendMessage(bn.gameExists(), peer_id)) continue response = requests.get('https://quizplease.ru/api/game?expand=place&city_id=6') json_response = json.loads(response.content.decode('utf-8'))['data'] if response.status_code == 200: game_is_found = False for game in json_response: game_date = datetime.strptime(game['datetime'].split(' ')[0], '%d.%m.%y').strftime('%d.%m.%Y') if game_date == date: game_is_found = True config = configparser.ConfigParser() config.read('options.ini') params = {'QpRecord[teamName]': config.get('Registration Data', 'teamname'), 'QpRecord[captainName]': config.get('Registration Data', 'captainname'), 'QpRecord[email]': config.get('Registration Data', 'email'), 'QpRecord[phone]': config.get('Registration Data', 'phone'), 'QpRecord[count]': config.get('Registration Data', 'count'), 'QpRecord[game_id]': game['id']} headers = {'Content-Type': 'application/x-www-form-urlencoded'} response = requests.post('https://quizplease.ru/ajax/save-record', params, headers) message_from_qp = json.loads(response.content.decode('utf-8')) message = str() if message_from_qp['success']: if 'sameTeam' not in message_from_qp: config = configparser.ConfigParser() config.read('games.ini') config.add_section(date) config.set(date, 'Место', game['place']['title'] + ' (' + game['place']['address'] + ')') config.set(date, 'Время', game['format_time']) config.set(date, 'Дополнительная информация', game['title'] + ' ' + game['name']) config.set(date, '+', '') config.set(date, '?', '') config.set(date, '-', '') if game['status']['id'] == 2: config.set(date, 'Статус', 'Резерв') else: config.set(date, 'Статус', '?') config.set(date, 'Системное поле', '') with open('games.ini', 'w') as config_file: config.write(config_file) message = bn.gameRegistered(date) +\ 'Название игры: ' + game['title'] + ' ' + game['name'] + '<br>' +\ 'Время игры: ' + game['format_time'] + '<br>' +\ 'Место: ' + game['place']['title'] + '<br>' +\ 'Адрес: ' + game['place']['address'] + '<br>' +\ 'Цена: ' + game['format_price'] + '<br>' +\ 'Описание: ' + game['description'] + '<br>' if str(game['status']['id']) == '1': message += 'Статус: Есть места' + '<br>' elif str(game['status']['id']) == '2': message += 'Статус: Только резерв' + '<br>' else: message += 'Статус: Мест нет' + '<br>' if message: codeExecutor(userMailing(message.replace('"', ''), from_id) +\ sendMessage(message_from_qp['successMsg'], peer_id)) else: codeExecutor(sendMessage(message_from_qp['successMsg'], peer_id)) else: codeExecutor(sendMessage(bn.requestError(), peer_id)) break if not game_is_found: codeExecutor(sendMessage(bn.noQpGame(), peer_id)) else: codeExecutor(sendMessage(json_response['message'], peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''---------------------------------------------------QGAME возвращает информацию по конкретной игре с сайта с указанием даты игры в формате ДД.ММ.ГГГГ-----------------------------------------------------''' elif new_message_list[0].lower() == 'qgame' and len(new_message_list) == 2: if len(new_message_list) == 2 and new_message_list[1].lower() == 'help': codeExecutor(sendMessage(opHelp(new_message_list[0].lower() + '.txt'), peer_id)) elif len(new_message_list) == 2: date = new_message_list[1] if not dateIsCorrect(date): codeExecutor(sendMessage(bn.incorrectDate(), peer_id)) continue config = configparser.ConfigParser() config.read('games.ini') response = requests.get('https://quizplease.ru/api/game?expand=place&city_id=6') json_response = json.loads(response.content.decode('utf-8'))['data'] if response.status_code == 200: message = str() for game in json_response: game_date = datetime.strptime(game['datetime'].split(' ')[0], '%d.%m.%y').strftime('%d.%m.%Y') if game_date == date: message += 'Название игры: ' + game['title'] + ' ' + game['name'] + '<br>' +\ 'Время игры: ' + game['format_time'] + '<br>' +\ 'Место: ' + game['place']['title'] + '<br>' +\ 'Адрес: ' + game['place']['address'] + '<br>' +\ 'Цена: ' + game['format_price'] + '<br>' +\ 'Описание: ' + game['description'] + '<br>' if str(game['status']['id']) == '1': message += 'Статус: Есть места <br>' elif str(game['status']['id']) == '2': message += 'Статус: Только резерв <br>' else: message += 'Статус: Мест нет <br>' if game_date in config.sections(): message += 'Чудо-зверята: Зарегистрированы' else: message += 'Чудо-зверята: Не зарегистрированы <br> <br>' +\ 'Для регистрации на эту игру введите qreg ' + date + '.' break if message: codeExecutor(sendMessage(message.replace('"', ''), peer_id)) else: codeExecutor(sendMessage(bn.noQpGame(), peer_id)) else: codeExecutor(sendMessage(json_response['message'], peer_id)) else: codeExecutor(sendMessage(bn.incorrectOp(new_message_list[0].lower()), peer_id)) '''-----------------------------------------------Здесь мы обрабатываем все остальное, полученное от пользователя, то, в чем бот не смог распознать команду-------------------------------------------------''' elif new_message_list[0].lower() == 'тест': tz = get_localzone() # local timezone d = datetime.now(tz).time() # or some other local date eastern = timezone('US/Eastern') eastern.zone print(eastern) else: request = apiai.ApiAI('bff8b97365d74955aa3e49ebbd63983f').text_request() request.lang = 'ru' request.session_id = 'session_1' request.query = new_message responseJson = json.loads(request.getresponse().read().decode('utf-8')) response = responseJson['result']['fulfillment']['speech'] if response: codeExecutor(sendMessage(response, peer_id)) else: config = configparser.ConfigParser() config.read('options.ini') if config.get('General Options', 'bot_gender') == 'femn': path = os.path.join(os.path.dirname(__file__), 'replicas', 'femn.txt') with open(path) as femn_replicas: answers = femn_replicas.readlines() codeExecutor(sendMessage(random.choice(answers).replace('\n', ''), peer_id)) elif config.get('General Options', 'bot_gender') == 'masc': path = os.path.join(os.path.dirname(__file__), 'replicas', 'masc.txt') with open(path) as femn_replicas: answers = femn_replicas.readlines() codeExecutor(sendMessage(random.choice(answers).replace('\n', ''), peer_id)) elif config.get('General Options', 'bot_gender') == 'neut': path = os.path.join(os.path.dirname(__file__), 'replicas', 'neut.txt') with open(path) as femn_replicas: answers = femn_replicas.readlines() codeExecutor(sendMessage(random.choice(answers).replace('\n', ''), peer_id)) else: path = os.path.join(os.path.dirname(__file__), 'replicas', 'none.txt') with open(path) as femn_replicas: answers = femn_replicas.readlines() codeExecutor(sendMessage(random.choice(answers).replace('\n', ''), peer_id)) '''----------------------------------"Тело" бота, выполняется только в том случае, если весь этот скрипт запускается как отдельный файл, а не как модуль из другого скрипта---------------------------------''' if __name__ == '__main__': if not os.path.exists('options.ini'): createConfig('options.ini')#---------------------------------------------------------------------------------------------------------------->Если конфиг с настройками не существует, создаем его if not os.path.exists('jobconfig.ini'): createConfig('jobconfig.ini')#-------------------------------------------------------------------------------------------------------------->Если конфиг джобов не существует, создаем его general_thread = threading.Thread(target=listen_server, daemon=True)#----------------------------------------------------------------------->Инициируем основной поток, в котором бот будет слушать сервер и #реагировать на новые сообщения job_thread = threading.Thread(target=do_jobs, daemon=True)#--------------------------------------------------------------------------------->Инициируем поток для джобов, в котором будет крутиться бесконечный цикл, #периодически запускающий джобы general_thread.start()#------------------------------------------------------------------------------------------------------------------------->Стартуем основной поток job_thread.start()#----------------------------------------------------------------------------------------------------------------------------->Стартуем поток джобов general_thread.join()#-------------------------------------------------------------------------------------------------------------------------->Основной поток будет ждать, пока выполнится этот поток job_thread.join()#------------------------------------------------------------------------------------------------------------------------------>Основной поток будет ждать, пока выполнится этот поток '''-----------------------------------------------------------------THE END----------------------------------------------------------------------------'''
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question