Пример #1
0
class StateChanger:
    def __init__(self, bot, redis_storage):
        self.bot = bot
        self.redis = redis_storage
        self.geo_radius = 5
        self.keyboard = Keyboard()
        self.text = Text(self.redis)

    def get_state(self, user_id):
        return self.redis.get_str(user_id, "state")

    def set_state(self, user_id, state):
        if state in config.permitted_states:
            self.redis.hset(str(user_id), "state", state)
        else:
            raise ValueError("There is no such state")

    def go_into_state(self, user_id, state, arbitrary_response=None):
        """
        Standard state changer
        """
        self.set_state(user_id, state)

        text = self.text.get_bot_text(user_id, state, arbitrary_response)

        keyboard = self.keyboard.get_state_keyboard(state)
        self.bot.send_message(user_id,
                              text,
                              reply_markup=keyboard,
                              parse_mode='markdown')

    #######################
    #######################
    #######################
    #######################
    # Custom state changers

    def already_set_direction(self, user_id, state):
        self.set_state(user_id, state)
        keyboard = types.InlineKeyboardMarkup()
        keyboard.add(
            types.InlineKeyboardButton(text='Всё равно продолжить',
                                       callback_data='Всё равно продолжить'))

        if state == 'already_set_departure':
            station_name = self.redis.get_str(user_id, 'dep_station')
        else:
            station_name = self.redis.get_str(user_id, 'arr_station')
        text = config.permitted_states[state]['message'].format(station_name)
        self.bot.send_message(user_id,
                              text,
                              reply_markup=keyboard,
                              parse_mode="markdown")

    def specify_radius(self, user_id, state):
        self.set_state(user_id, state)
        comeback = self.keyboard.geostations()
        keyboard = self.keyboard.specify_radius()

        responses = config.permitted_states[state]['message']
        self.bot.send_message(user_id,
                              responses[0],
                              reply_markup=comeback,
                              parse_mode="markdown")
        self.bot.send_message(user_id,
                              responses[1],
                              reply_markup=keyboard,
                              parse_mode="markdown")

    def direction_input(self, user_id, state):
        self.set_state(user_id, state)

        comeback = self.keyboard.get_additional_comeback_keyboard()
        keyboard = self.keyboard.direction_input(state)

        responses = config.permitted_states[state]['message']
        self.bot.send_message(user_id,
                              responses[0],
                              reply_markup=comeback,
                              parse_mode='markdown')
        self.bot.send_message(user_id, responses[1], reply_markup=keyboard)

    def specify_direction_region(self, user_id, state):
        self.set_state(user_id, state)

        country = self.redis.get_str(user_id, 'country')
        country_string = "Страна: *{0}*\n".format(country)
        regions_alphabet = yandex_api.get_regions_alphabet(country)

        comeback = self.keyboard.get_additional_comeback_keyboard()
        keyboard = self.keyboard.specify_direction_region(regions_alphabet)

        responses = config.permitted_states[state]['message']
        self.bot.send_message(user_id,
                              country_string + responses[0],
                              reply_markup=comeback,
                              parse_mode='markdown')
        self.bot.send_message(user_id, responses[1], reply_markup=keyboard)

    def direction_region(self, user_id, state, callback):
        self.set_state(user_id, state)
        country = self.redis.get_str(user_id, 'country')
        desired_regions = yandex_api.give_me_regions_by_letter(
            callback.data, country)

        keyboard = self.keyboard.direction_region(desired_regions)

        self.bot.edit_message_reply_markup(
            message_id=callback.message.message_id,
            chat_id=callback.message.chat.id,
            inline_message_id=callback.inline_message_id,
            reply_markup=keyboard)

    def check_values(self, user_id, state, stations):
        self.set_state(user_id, state)

        if len(stations) == 0:
            self.bot.send_message(
                user_id, 'К сожалению, станция не найдена! Попробуйте снова.')

        elif len(stations) == 1:
            chosen_station = stations[0]
            station_code = chosen_station['codes']['yandex_code']
            if self.get_state(user_id) == 'specify_arrival_station':
                self.redis.hset(user_id, 'arr_station',
                                chosen_station['title'])
                self.redis.hset(user_id, 'arr_code', station_code)
            else:
                self.redis.hset(user_id, 'dep_station',
                                chosen_station['title'])
                self.redis.hset(user_id, 'dep_code', station_code)
                latitude, longitude = chosen_station[
                    'latitude'], chosen_station['longitude']
                self.redis.hset(user_id, 'latitude', latitude)
                self.redis.hset(user_id, 'longitude', longitude)
            self.sure_station(user_id, state, chosen_station['title'])
        else:
            self.clarify_direction(user_id, stations)

    def both_stations_set(self, user_id):
        if self.redis.hexists(user_id, 'arr_code') and self.redis.hexists(
                user_id, 'dep_code'):
            return True
        else:
            return False

    def clarify_direction(self, user_id, stations):
        self.redis.hset(user_id, 'stations', json.dumps(stations))
        keyboard = types.InlineKeyboardMarkup()
        keyboard.add(*[
            types.InlineKeyboardButton(text=station['direction'],
                                       callback_data='D' +
                                       station['direction'])
            for station in stations
        ])
        self.bot.send_message(user_id,
                              'Выберете железнодорожную ветку вашей станции!',
                              reply_markup=keyboard)

    def change_radius(self, r_diff, c):
        if self.geo_radius == 1 and r_diff < 0 or self.geo_radius == 20 and r_diff > 0:
            return
        self.geo_radius += r_diff
        if self.geo_radius < 1:
            self.geo_radius = 1
        elif self.geo_radius > 20:
            self.geo_radius = 20

        keyboard = self.keyboard.specify_radius()
        self.bot.edit_message_text(message_id=c.message.message_id,
                                   chat_id=c.message.chat.id,
                                   inline_message_id=c.inline_message_id,
                                   text='Радиус поиска   -  *%d км*' %
                                   self.geo_radius,
                                   reply_markup=keyboard,
                                   parse_mode='markdown')

    def geo_stations(self, user_id, location):
        latitude = location.latitude
        longitude = location.longitude
        nearest_stations = yandex_api.get_nearest_stations(
            latitude, longitude, self.geo_radius)

        stations = nearest_stations['stations']
        keyboard = types.InlineKeyboardMarkup(row_width=1)
        keyboard.add(*[
            types.InlineKeyboardButton(text=station['title'],
                                       callback_data='gs' + station['code'] +
                                       ' ' + station['title'])
            for station in stations
        ])
        self.bot.send_message(user_id,
                              'В радиусе %d км найдены такие станции:' %
                              self.geo_radius,
                              reply_markup=keyboard)

    def sure_station_geo(self, user_id, state, station_title):
        print(state)
        self.set_state(user_id, state)

        keyboard = types.InlineKeyboardMarkup()
        keyboard.add(
            types.InlineKeyboardButton(text='Изменить',
                                       callback_data='Изменить'))
        keyboard.add(
            types.InlineKeyboardButton(text='Подтвердить',
                                       callback_data='Подтвердить'))

        direction = 'отправления' if state == 'sure_dep' else 'прибытия'
        station_confirmation = "Ваша станция {0}:\n" \
                               "*регион {0}*: согласно геопозиции\n" \
                               "*станция {0}*: {1}".format(direction, station_title)
        self.bot.send_message(user_id,
                              station_confirmation,
                              reply_markup=keyboard,
                              parse_mode="markdown")

    def sure_station(self, user_id, state, station_title):
        keyboard = types.InlineKeyboardMarkup()
        keyboard.add(
            types.InlineKeyboardButton(text='Изменить',
                                       callback_data='Изменить'))
        keyboard.add(
            types.InlineKeyboardButton(text='Подтвердить',
                                       callback_data='Подтвердить'))

        if state == 'specify_departure_station':
            region = self.redis.get_str(user_id, 'dep_region')
            direction = 'отправления'
        else:
            direction = 'прибытия'
            region = self.redis.get_str(user_id, 'arr_region')

        station_confirmation = "Ваша станция {0}:\n" \
                               "*регион {0}*: {1}\n" \
                               "*станция {0}*: {2}".format(direction, region, station_title)
        self.bot.send_message(user_id,
                              station_confirmation,
                              reply_markup=keyboard,
                              parse_mode="markdown")

    def create_route(self, user_id, bot_response):
        state = 'created_route'
        self.set_state(user_id, state)
        ad_keyboard = types.InlineKeyboardMarkup()
        ad_keyboard.add(
            types.InlineKeyboardButton(text='Добавить в Мои маршруты',
                                       callback_data='добавить'))

        keyboard = self.keyboard.create_route(state)
        self.bot.send_message(user_id,
                              bot_response,
                              reply_markup=ad_keyboard,
                              parse_mode='markdown')
        self.bot.send_message(user_id,
                              'Что Вас интересует?',
                              reply_markup=keyboard,
                              parse_mode='markdown')

    def specific_route(self, user_id, route_number):
        state = 'specific_route'
        self.set_state(user_id, state)
        text = self.text.get_bot_text(user_id,
                                      state,
                                      route_number=route_number)

        keyboard = self.keyboard.get_state_keyboard(state)
        self.bot.send_message(user_id,
                              text,
                              reply_markup=keyboard,
                              parse_mode='markdown')

    def notify_me(self, user_id, electr_number):
        state = 'notify_me'
        self.set_state(user_id, state)
        text = self.text.get_bot_text(user_id,
                                      state,
                                      electr_number=electr_number)

        keyboard = self.keyboard.get_state_keyboard(state)
        self.bot.send_message(user_id,
                              text,
                              reply_markup=keyboard,
                              parse_mode='markdown')