예제 #1
0
class BeginningHandlers:
    def __init__(self):
        self._splitwise = SplitwiseApp()

    def start_handler(
        self,
        update: Update,
        _: CallbackContext,
    ) -> NoReturn:
        id_ = update.effective_user.id
        name = update.effective_user.username

        if self._splitwise.user_exists(id_):
            name = self._splitwise.get_user_info(id_).name
            update.effective_chat.send_message(
                f'Привет, {name}! Ты уже был(а) здесь!')
        else:
            self._splitwise.add_new_user(User(id_, name))
            update.effective_chat.send_message(
                f'Привет, {name}! Ты здесь впервые!')
        update.effective_chat.send_message(
            'Меню:', reply_markup=buttons.get_menu_keyboard())

    def users_of_event_handler(
        self,
        update: Update,
        context: CallbackContext,
    ):
        token = context.args[0]
        users = self._splitwise.get_users_of_event(token)
        update.effective_chat.send_message(str(users))

    def text_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message('Выберите пункт меню:')
        update.effective_chat.send_message(
            'Меню:', reply_markup=buttons.get_menu_keyboard())

    def get_menu(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message(
            'Меню:', reply_markup=buttons.get_menu_keyboard())
예제 #2
0
class MenuButtonsConversationHandler:
    def __init__(self):
        self._splitwise = SplitwiseApp()

    def callback_query_handler(
        self,
        update: Update,
        _: CallbackContext,
    ) -> NoReturn:
        data = update.callback_query.data
        update.callback_query.answer()
        if data == menu_items.CREATE_EVENT:
            update.callback_query.edit_message_text(
                'Введи название мероприятия или нажми кнопку \'Отмена\'')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_cancel_button())
            update.callback_query.answer()
            return States.EVENT_NAME_STATE
        elif data == menu_items.JOIN_EVENT:
            update.callback_query.edit_message_text(
                'Введи токен мероприятия или нажми кнопку \'Отмена\'',
                reply_markup=buttons.get_cancel_button())
            update.callback_query.answer()
            return States.EVENT_TOKEN_STATE
        elif data == menu_items.SELECT_EVENT:
            user_id = update.effective_user.id
            events = self._splitwise.get_user_events(user_id)
            update.callback_query.edit_message_text('Выбери мероприятие')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_event_buttons(events))
            update.callback_query.answer()
            return States.ASKING_FOR_ACTION

    def fallback_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message(
            'Ошибка, но мы не знаем что произошло')

    def get_conversation_handler(self, ) -> ConversationHandler:
        conv_handler = ConversationHandler(
            entry_points=[
                CallbackQueryHandler(self.callback_query_handler),
            ],
            states={
                States.EVENT_NAME_STATE:
                [CreateEventConversation().get_conversation_handler()],
                States.ASKING_FOR_ACTION:
                [SelectEventConversation().get_conversation_handler()],
                States.EVENT_TOKEN_STATE:
                [JoinEventConversation().get_conversation_handler()],
            },
            fallbacks=[MessageHandler(Filters.all, self.fallback_handler)],
        )
        return conv_handler
예제 #3
0
class CreateEventConversation:
    def __init__(self, ):
        self._splitwise = SplitwiseApp()

    def event_name_handler(
        self,
        update: Update,
        _: CallbackContext,
    ) -> NoReturn:
        event_name = update.effective_message.text
        event_token = self._splitwise.create_event(
            user_id=update.effective_user.id,
            event_name=event_name,
        )
        update.effective_chat.send_message(
            f'Мероприятие "{event_name}" создано. Токен: `{event_token}`',
            parse_mode=ParseMode.MARKDOWN)
        update.effective_chat.send_message(
            'Меню:', reply_markup=buttons.get_menu_keyboard())
        return ConversationHandler.END

    def callback_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        if update.callback_query.data == menu_items.CANCEL:
            update.callback_query.answer('Создание мероприятия отменено')
            update.callback_query.edit_message_text('Меню:')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_menu_keyboard())
            return ConversationHandler.END
        else:
            update.callback_query.answer('Не на ту кнопку жмешь')

    def fallbacks_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message('Мимо кассы. Нужно имя.')

    def get_conversation_handler(self, ) -> ConversationHandler:
        conv_handler = ConversationHandler(
            entry_points=[
                MessageHandler(Filters.text, self.event_name_handler),
                CallbackQueryHandler(self.callback_handler),
            ],
            states={},
            fallbacks=[MessageHandler(Filters.all, self.fallbacks_handler)],
            map_to_parent={
                ConversationHandler.END: ConversationHandler.END,
            })
        return conv_handler
예제 #4
0
class SelectEventConversation:
    def __init__(self, ):
        self._splitwise = SplitwiseApp()

    def asking_for_action(
        self,
        update: Update,
        context: CallbackContext,
    ):
        if update.callback_query.data == menu_items.CANCEL:
            context.user_data.pop(States.CURRENT_EVENT_TOKEN, None)
            update.callback_query.edit_message_text('Меню:')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_menu_keyboard())
            update.callback_query.answer()
            return ConversationHandler.END
        event_token = update.callback_query.data
        context.user_data[States.CURRENT_EVENT_TOKEN] = event_token
        event = self._splitwise.get_event_info(event_token)
        update.callback_query.edit_message_text(
            f'{event.name}\nВыберите пункт меню:')
        update.callback_query.edit_message_reply_markup(
            reply_markup=buttons.get_event_commands_keyboard())
        update.callback_query.answer()
        return States.EVENT_ACTIONS

    def fallbacks_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message(
            'Что-то пошло не так. Попробуй еще раз')

    def get_conversation_handler(self, ) -> ConversationHandler:
        conv_handler = ConversationHandler(
            entry_points=[CallbackQueryHandler(self.asking_for_action)],
            states={
                States.EVENT_ACTIONS: [
                    ActionProcessHandlers().get_conversation_handler(),
                ]
            },
            fallbacks=[
                MessageHandler(Filters.all, self.fallbacks_handler),
            ],
            map_to_parent={
                ConversationHandler.END: ConversationHandler.END,
            })
        return conv_handler
예제 #5
0
 def __init__(
     self,
     token: str,
     db_name: str = 'database.sqlite',
 ):
     self.splitwise = SplitwiseApp(db_name=db_name)
     self.updater = Updater(token)
     dispatcher = self.updater.dispatcher
     dispatcher.add_handler(handlers.MenuButtonsConversationHandler().
                            get_conversation_handler())
     dispatcher.add_handler(
         CommandHandler(
             'users_of_event',
             handlers.BeginningHandlers().users_of_event_handler))
     dispatcher.add_handler(
         CommandHandler('start',
                        handlers.BeginningHandlers().start_handler))
     dispatcher.add_handler(
         CommandHandler('get_menu',
                        handlers.BeginningHandlers().get_menu))
     dispatcher.add_handler(
         MessageHandler(Filters.text,
                        handlers.BeginningHandlers().text_handler))
예제 #6
0
from app.splitwise import SplitwiseApp
from database.model_types import User

if __name__ == '__main__':
    splitwise = SplitwiseApp(db_name='testdb.sqlite')
    users = [
        (123, 'Ivan'),
        (456, 'Maria'),
        (789, 'San44ez'),
    ]

    for id_, name in users:
        splitwise.add_new_user(User(id=id_, name=name))

    for id_, _ in users:
        print(splitwise.get_user_info(id_))
예제 #7
0
 def __init__(self):
     self.splitwise = SplitwiseApp()
     raise NotImplementedError
예제 #8
0
def app(db_name):
    return SplitwiseApp(db_name)
예제 #9
0
from app.splitwise import SplitwiseApp

if __name__ == '__main__':
    splitwise = SplitwiseApp()
예제 #10
0
 def __init__(self):
     self._splitwise = SplitwiseApp()
예제 #11
0
class AddExpenseHandlers:
    def __init__(self, ):
        self._splitwise = SplitwiseApp()

    @staticmethod
    def _get_sum_or_none(text) -> Optional[int]:
        try:
            sum_ = int(text)
        except ValueError:
            return None
        return sum_ if sum_ > 0 else None

    def expense_name(
        self,
        update: Update,
        context: CallbackContext,
    ) -> States:
        expense_name = update.effective_message.text
        context.user_data[States.EXPENSE].name = expense_name
        update.effective_chat.send_message(
            'Введи потраченную сумму или нажми кнопку \'Отмена\'.',
            reply_markup=buttons.get_cancel_button())
        return States.EXPENSE_SUM

    def expense_sum(
        self,
        update: Update,
        context: CallbackContext,
    ) -> Optional[States]:
        # let's use integer division and forget about cents for some time
        expense_sum = self._get_sum_or_none(update.effective_message.text)
        if not expense_sum:
            update.effective_chat.send_message(
                'Потраченная сумма вводится в формате: 123(целое число). '
                'Потраченная сумма должна быть больше нуля. '
                'Попробуй еще раз')
            return None

        context.user_data[States.EXPENSE].sum = expense_sum
        expense_id = self._splitwise.add_expense(
            context.user_data[States.EXPENSE])
        context.user_data[States.EXPENSE].id = expense_id
        expense = self._splitwise.get_expense(expense_id)
        update.effective_chat.send_message(f'Создана трата: {str(expense)}.')
        update.effective_chat.send_message('Приступим к записи долгов')
        users = self._splitwise.get_users_of_event(
            context.user_data[States.CURRENT_EVENT_TOKEN])
        update.effective_chat.send_message(
            'Назови имя должника',
            reply_markup=buttons.get_user_buttons(users))
        return States.DEBTOR_NAME

    def debtor_name(self, update: Update, context: CallbackContext):
        if update.callback_query.data == menu_items.CANCEL:
            return self.cancel_button_handler(update, context)

        user_debt = Debt()
        user_debt.lender_id = update.effective_user.id
        user_debt.debtor_id = int(update.callback_query.data)
        context.user_data[States.DEBT] = user_debt
        user = self._splitwise.get_user_info(int(update.callback_query.data))
        update.callback_query.edit_message_text(
            f'{user.name}\nСколько он тебе задолжал?')
        update.callback_query.answer()
        return States.DEBT_SUM

    def debt_sum(
        self,
        update: Update,
        context: CallbackContext,
    ) -> NoReturn:
        debt_sum = self._get_sum_or_none(update.effective_message.text)
        if not debt_sum:
            update.effective_chat.send_message(
                'Долг вводится в формате: 123(целое число). '
                'Долг должен быть положительным. '
                'Попробуй еще раз')
            return None

        context.user_data[States.DEBT].sum = debt_sum
        context.user_data[States.DEBT].expense_id = context.user_data[
            States.EXPENSE].id
        debt = context.user_data[States.DEBT]
        self._splitwise.add_debt(debt)
        update.effective_chat.send_message('Записал!')
        users = self._splitwise.get_users_of_event(
            context.user_data[States.EXPENSE].event_token)
        update.effective_chat.send_message(
            'Назови имя следующего должника или нажмите "Закончить"',
            reply_markup=buttons.get_user_buttons(users))
        return States.DEBTOR_NAME

    def cancel_button_handler(
        self,
        update: Update,
        context: CallbackContext,
    ):
        data = update.callback_query.data
        if data == menu_items.CANCEL:
            context.user_data.pop(States.EXPENSE, None)
            context.user_data.pop(States.DEBT, None)
            event_token = context.user_data[States.CURRENT_EVENT_TOKEN]
            event = self._splitwise.get_event_info(event_token)
            update.callback_query.edit_message_text(
                f'\n\n {event.name}\nВыберите пункт меню:')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_event_commands_keyboard())
            update.callback_query.answer('Закончили')
            return States.EVENT_ACTIONS
        return None

    def fallbacks_button_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message('Хватит жмакать на кнопки')

    def fallbacks_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message(
            'Что-то пошло не так. Попробуй еще раз раз раз')

    def get_conversation_handler(self, ) -> ConversationHandler:
        conv_handler = ConversationHandler(
            entry_points=[
                MessageHandler(Filters.text, self.expense_name),
                CallbackQueryHandler(self.cancel_button_handler)
            ],
            states={
                States.EXPENSE_SUM: [
                    MessageHandler(Filters.text, self.expense_sum),
                    CallbackQueryHandler(self.cancel_button_handler)
                ],
                States.DEBTOR_NAME: [CallbackQueryHandler(self.debtor_name)],
                States.DEBT_SUM: [MessageHandler(Filters.text, self.debt_sum)],
            },
            fallbacks=[
                CallbackQueryHandler(self.fallbacks_button_handler),
                MessageHandler(Filters.all, self.fallbacks_handler)
            ],
            map_to_parent={
                ConversationHandler.END: ConversationHandler.END,
                States.EVENT_ACTIONS: States.EVENT_ACTIONS,
            })
        return conv_handler
예제 #12
0
class ActionProcessHandlers:
    def __init__(self):
        self._splitwise = SplitwiseApp()

    def callback_query_handler(
        self,
        update: Update,
        context: CallbackContext,
    ) -> NoReturn:
        data = update.callback_query.data
        event_token = context.user_data[States.CURRENT_EVENT_TOKEN]
        event = self._splitwise.get_event_info(event_token)
        user_id = update.effective_user.id
        if data == menu_items.SHOW_DEBTS:
            lenders_info, debtors_info = self._splitwise.get_final_transactions(
                event_token)
            if user_id in debtors_info:
                update.callback_query.edit_message_text(
                    'Вы должны: \n' + str(debtors_info[user_id]) +
                    f'\n\n {event.name}\nВыберите пункт меню:')
            elif user_id in lenders_info:
                update.callback_query.edit_message_text(
                    'Вам должны: \n' + str(lenders_info[user_id]) +
                    f'\n\n {event.name}\nВыберите пункт меню:')
            else:
                update.callback_query.edit_message_text(
                    'Вы никому не должны и вам никто не должен!!!' +
                    f'\n\n {event.name}\nВыберите пункт меню:')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_event_commands_keyboard())
            update.callback_query.answer()
            return States.EVENT_ACTIONS
        elif data == menu_items.ADD_EXPENSE:
            event_token = context.user_data[States.CURRENT_EVENT_TOKEN]
            try:
                self._splitwise.get_event_info(event_token)
            except KeyError:
                update.effective_chat.send_message(
                    'Мероприятия с таким токеном не существует. Повторите создание траты:'
                )
                return ConversationHandler.END
            expense = Expense()
            expense.event_token = event_token
            expense.lender_id = user_id
            context.user_data[States.EXPENSE] = expense
            update.callback_query.edit_message_text(
                'Введи название траты или нажми \'Отмена\'',
                reply_markup=buttons.get_cancel_button())
            return States.EXPENSE_NAME
        elif data == menu_items.CANCEL:
            del context.user_data[States.CURRENT_EVENT_TOKEN]
            update.callback_query.edit_message_text('Меню:')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_menu_keyboard())
            update.callback_query.answer()
            return ConversationHandler.END

    def fallbacks_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message(
            'Что-то пошло не так. Попробуй еще раз раз')

    def get_conversation_handler(self, ) -> ConversationHandler:
        conv_handler = ConversationHandler(
            entry_points=[
                CallbackQueryHandler(self.callback_query_handler),
            ],
            states={
                States.EXPENSE_NAME:
                [AddExpenseHandlers().get_conversation_handler()],
            },
            fallbacks=[MessageHandler(Filters.all, self.fallbacks_handler)],
            map_to_parent={
                ConversationHandler.END: ConversationHandler.END,
                States.EVENT_ACTIONS: States.EVENT_ACTIONS,
            })
        return conv_handler
예제 #13
0
class JoinEventConversation:
    def __init__(self, ):
        self._splitwise = SplitwiseApp()

    def event_token_handler(
        self,
        update: Update,
        _: CallbackContext,
    ) -> NoReturn:
        event_token = update.effective_message.text
        user_id = update.effective_user.id
        try:
            self._splitwise.get_event_info(event_token)
        except KeyError:
            update.effective_chat.send_message(
                'Мероприятия с таким токеном не существует. '
                'Введи корректный токен или нажми кнопку \'Отмена\'',
                reply_markup=buttons.get_cancel_button())
            return None
        if self._splitwise.user_participates_in_event(user_id, event_token):
            update.effective_chat.send_message(
                'Не прокатит! Ты уже зарегистрирован в этом мероприятии')
            update.effective_chat.send_message(
                'Меню:', reply_markup=buttons.get_menu_keyboard())
            return ConversationHandler.END
        self._splitwise.add_user_to_event(user_id, event_token)
        update.effective_chat.send_message(
            'Ты успешно присоединился к мероприятию')
        update.effective_chat.send_message(
            'Меню:', reply_markup=buttons.get_menu_keyboard())
        return ConversationHandler.END

    def callback_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        if update.callback_query.data == menu_items.CANCEL:
            update.callback_query.edit_message_text('Меню:')
            update.callback_query.edit_message_reply_markup(
                reply_markup=buttons.get_menu_keyboard())
            return ConversationHandler.END
        else:
            update.callback_query.answer('Не на ту кнопку жмешь', )

    def fallbacks_handler(
        self,
        update: Update,
        _: CallbackContext,
    ):
        update.effective_chat.send_message('Давай токен говори')

    def get_conversation_handler(self, ) -> ConversationHandler:
        conv_handler = ConversationHandler(
            entry_points=[
                MessageHandler(Filters.text, self.event_token_handler),
                CallbackQueryHandler(self.callback_handler),
            ],
            states={},
            fallbacks=[MessageHandler(Filters.all, self.fallbacks_handler)],
            map_to_parent={
                ConversationHandler.END: ConversationHandler.END,
            })
        return conv_handler