コード例 #1
0
def switch_on(bot, update, job_queue, chat_data):
    """Add the job to the queue"""

    msg = update.message
    if mq.get_user_settings(msg.chat_id)[base_config.NOTIFICATIONS]:
        msg.reply_text(messages.ALREADY_ON_TEXT, reply_markup=kb_main, parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    mq.update_setting(msg.chat_id, setting=base_config.NOTIFICATIONS, value=True)
    if 'job' in chat_data:
        chat_data['job'].schedule_removal()
    job = job_queue.run_repeating(notify, int(mq.get_user_settings(msg.chat_id)[base_config.INTERVAL]),
                                  context={'chat_id': msg.chat_id})
    chat_data['job'] = job
    msg.reply_text(messages.NOTIFICATIONS_ON_TEXT, parse_mode=messages.MARKDOWN)
コード例 #2
0
def show_your_coins(bot, update):
    """Show the user's coins list"""

    msg = update.message
    msg.reply_text('`' + '`, `'.join(mq.get_user_settings(msg.chat_id)[base_config.COINS]) + '`',
                   reply_markup=kb_main, parse_mode=messages.MARKDOWN)
    return MAIN_MENU
コード例 #3
0
def show_your_exchanges(bot, update):
    """Show user's exchanges list"""

    user_exchanges = mq.get_user_settings(update.message.chat_id)[base_config.EXCHANGES]
    update.message.reply_text('`' + '`, `'.join(user_exchanges) + '`',
                              reply_markup=kb_main, parse_mode=messages.MARKDOWN)
    return MAIN_MENU
コード例 #4
0
def set_interval_dialog(bot, update, chat_data, job_queue):
    """
    Begin the dialog with for setting an interval value
    
    Args:
        :param bot: <object> bot instance 
        :param update: <dict> update object that contains updates from user chat
        :param chat_data: <dict> stores the data for the chat. In this case a job object stores in it
        :param job_queue: <object> queue of jobs. The notify job automatically adds to queue after start 
        
    Returns:
        :return: settings menu identifier
    """

    msg = update.message
    interval = int(msg.text)
    if interval <= 0:
        msg.reply_text(messages.SET_INTERVAL_BAD_VALUE_TEXT,
                       parse_mode=messages.MARKDOWN)
    else:
        mq.update_setting(msg.chat_id,
                          setting=base_config.INTERVAL,
                          value=interval)
        if mq.get_user_settings(msg.chat_id)[base_config.NOTIFICATIONS]:
            chat_data['job'].schedule_removal()
            job = job_queue.run_repeating(notify,
                                          interval,
                                          context={"chat_id": msg.chat_id})
            chat_data['job'] = job
            msg.reply_text(messages.SET_INTERVAL_SUCC_TEXT.format(interval),
                           reply_markup=kb_settings,
                           parse_mode=messages.MARKDOWN)
        return SETTINGS_MENU
    return SET_INTERVAL
コード例 #5
0
def remove_exchange(bot, update, args):
    """Remove exchange to exchanges list by which the bot will notify the user"""

    msg = update.message
    try:
        exchange = args[0].replace('-', '_').lower()
        user_exchanges = mq.get_user_settings(
            msg.chat_id)[base_config.EXCHANGES]
        if exchange not in user_exchanges:
            user_exchanges = exchange_convert(user_exchanges)
            msg.reply_text(messages.ALREADY_DISABLED_EXCHANGE_TEXT.format(
                '`' + '`, `'.join(user_exchanges) + '`'),
                           reply_markup=kb_main,
                           parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        mq.remove_from_list(msg.chat_id,
                            list=base_config.EXCHANGES,
                            value=exchange)
        new_user_exchanges = '`' + '`, `'.join(
            exchange_convert(set(user_exchanges) - {exchange})) + '`'
        msg.reply_text(
            messages.REMOVE_EXCHANGE_SUCC_TEXT.format(new_user_exchanges),
            reply_markup=kb_main,
            parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    except (IndexError, ValueError):
        msg.reply_text(messages.REMOVE_EXCHANGE_HELP_TEXT,
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
コード例 #6
0
def add_exchange(bot, update, args):
    """Add exchange to exchanges list by which the bot will notify the user"""

    msg = update.message
    try:
        exchange = args[0].replace('-', '_').lower()
        if exchange not in mq.exchanges:
            exchanges = exchange_convert(mq.exchanges)
            msg.reply_text(messages.UNSUPPORTED_EXCHANGE_TEXT.format(
                '`' + '`, `'.join(exchanges) + '`'),
                           reply_markup=kb_main,
                           parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        user_exchanges = mq.get_user_settings(
            msg.chat_id)[base_config.EXCHANGES]
        if exchange in user_exchanges:
            msg.reply_text(messages.ALREADY_ENABLED_EXCHANGE_TEXT.format(
                '`' + exchange_convert(exchange) + '`'),
                           reply_markup=kb_main,
                           parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        mq.add_to_list(msg.chat_id, list=base_config.EXCHANGES, value=exchange)
        new_user_exchanges = '`' + '`, `'.join(
            exchange_convert(set(user_exchanges + [exchange]))) + '`'
        msg.reply_text(
            messages.ADD_EXCHANGE_SUCC_TEXT.format(new_user_exchanges),
            reply_markup=kb_main,
            parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    except (IndexError, ValueError):
        msg.reply_text(messages.ADD_EXCHANGE_HELP_TEXT,
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
コード例 #7
0
def remove_coin(bot, update, args):
    """Remove coin from coins list by which the bot will notify the user"""

    msg = update.message
    try:
        coin = args[0].upper()
        user_coins = mq.get_user_settings(msg.chat_id)[base_config.COINS]
        if coin not in user_coins:
            msg.reply_text(
                messages.ALREADY_DISABLED_COIN.format('`' +
                                                      '`, `'.join(user_coins) +
                                                      '`'),
                reply_markup=kb_main,
                parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        mq.remove_from_list(msg.chat_id, list=base_config.COINS, value=coin)
        new_user_coins = '`' + '`, `'.join(set(user_coins) - {coin}) + '`'
        msg.reply_text(messages.REMOVE_COIN_SUCC_TEXT.format(new_user_coins),
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    except (IndexError, ValueError):
        msg.reply_text(messages.REMOVE_COIN_HELP_TEXT,
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
コード例 #8
0
def add_coin(bot, update, args):
    """Add coin to coins list by which the bot will notify the user"""

    msg = update.message
    try:
        coin = args[0].upper()
        if coin not in mq.coins:
            msg.reply_text(
                messages.UNSUPPORTED_COIN_TEXT.format('`' +
                                                      '`, `'.join(mq.coins) +
                                                      '`'),
                reply_markup=kb_main,
                parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        user_coins = mq.get_user_settings(msg.chat_id)[base_config.COINS]
        if coin in user_coins:
            msg.reply_text(messages.ALREADY_ENABLED_COIN.format('`' + coin +
                                                                '`'),
                           reply_markup=kb_main,
                           parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        mq.add_to_list(msg.chat_id, list=base_config.COINS, value=coin)
        new_user_coins = '`' + '`, `'.join(set(user_coins + [coin])) + '`'
        msg.reply_text(messages.ADD_COIN_SUCC_TEXT.format(new_user_coins),
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    except (IndexError, ValueError):
        msg.reply_text(messages.ADD_COIN_HELP_TEXT,
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
コード例 #9
0
def set_interval(bot, update, args, chat_data, job_queue):
    """Set interval between notifications in seconds"""

    msg = update.message
    try:
        interval = int(args[0])
        if interval <= 0:
            msg.reply_text(messages.SET_INTERVAL_BAD_VALUE_TEXT,
                           reply_markup=kb_main,
                           parse_mode=messages.MARKDOWN)
            return MAIN_MENU
        mq.update_setting(msg.chat_id,
                          setting=base_config.INTERVAL,
                          value=interval)
        if mq.get_user_settings(msg.chat_id)[base_config.NOTIFICATIONS]:
            chat_data['job'].schedule_removal()
            job = job_queue.run_repeating(notify,
                                          interval,
                                          context={'chat_id': msg.chat_id})
            chat_data['job'] = job
        msg.reply_text(messages.SET_INTERVAL_SUCC_TEXT.format(interval),
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    except (IndexError, ValueError, IndexError):
        msg.reply_text(messages.SET_INTERVAL_HELP_TEXT,
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    except OverflowError:
        msg.reply_text(messages.SET_INTERVAL_BIG_VALUE_EXCEPTION,
                       reply_markup=kb_main,
                       parse_mode=messages.MARKDOWN)
        return MAIN_MENU
コード例 #10
0
def switch(bot, update, job_queue, chat_data):
    """Switch notifications on/off"""

    if mq.get_user_settings(update.message.chat_id)[base_config.NOTIFICATIONS]:
        switch_off(bot, update, job_queue, chat_data)
    else:
        switch_on(bot, update, job_queue, chat_data)
    return SETTINGS_MENU
コード例 #11
0
def switch_off(bot, update, job_queue, chat_data):
    """Remove the job if the user changed their mind"""

    msg = update.message
    if not mq.get_user_settings(msg.chat_id)[base_config.NOTIFICATIONS]:
        msg.reply_text(messages.ALREADY_OFF_TEXT, reply_markup=kb_main, parse_mode=messages.MARKDOWN)
        return MAIN_MENU
    mq.update_setting(msg.chat_id, setting=base_config.NOTIFICATIONS, value=False)
    chat_data['job'].schedule_removal()
    msg.reply_text(messages.NOTIFICATIONS_OFF_TEXT, parse_mode=messages.MARKDOWN)
コード例 #12
0
def start(bot, update, args, job_queue, chat_data):
    """
    Main entry point of the bot. This command starts the bot interface and checks user authorization.
    
    Args:
        :param bot: <object> bot instance 
        :param update: <dict> update object that contains updates from user chat
        :param args: arguments that user enters after command. In this case command /start receives 
                     the unique hash key for user authentication
        :param job_queue: <object> queue of jobs. The notify job automatically adds to queue after start 
        :param chat_data: <dict> stores the data for the chat. In this case a job object stores in it.
        
    Returns:
        :return: Main menu identifier
    """
    msg = update.message
    user = mq.get_user(msg.chat_id)
    if not user:
        if len(args) == 0:
            msg.reply_text(messages.ABOUT_TEXT, parse_mode=messages.MARKDOWN)
            msg.reply_text(messages.GET_REGISTRATION_TEXT,
                           parse_mode=messages.MARKDOWN)
            return BLACK_HOLE
        else:
            key = args[0]
            email = mq.get_user_email(key)
            if not email or mq.get_user_by_email(email):
                msg.reply_text(messages.AUTHORIZATION_FAIL_TEXT,
                               parse_mode=messages.MARKDOWN)
                return BLACK_HOLE
            else:
                mq.add_user(msg, email)
                msg.reply_text(messages.AUTHORIZATION_SUCC_TEXT,
                               parse_mode=messages.MARKDOWN)

    msg.reply_text(messages.HELLO_TEXT,
                   reply_markup=kb_main,
                   parse_mode=messages.MARKDOWN)

    # Add job to queue
    if 'job' not in chat_data:
        user_settings = mq.get_user_settings(msg.chat_id)
        if user_settings[base_config.NOTIFICATIONS]:
            job = job_queue.run_repeating(
                notify,
                int(user_settings[base_config.INTERVAL]),
                context={'chat_id': msg.chat_id})
            chat_data['job'] = job

    return MAIN_MENU
コード例 #13
0
def threshold(bot, update):
    """
    Send static message for threshold setting

    Returns:
        :return: threshold menu identifier
    """

    msg = update.message
    threshold = mq.get_user_settings(msg.chat_id)[base_config.THRESHOLD]
    msg.reply_text(messages.SET_THRESHOLD_TEXT.format(threshold),
                   reply_markup=kb_back,
                   parse_mode=messages.MARKDOWN)
    return SET_THRESHOLD
コード例 #14
0
def interval(bot, update):
    """
    Send static message for interval setting
    
    Returns:
        :return: interval menu identifier
    """

    msg = update.message
    interval = mq.get_user_settings(msg.chat_id)[base_config.INTERVAL]
    msg.reply_text(messages.SET_INTERVAL_TEXT.format(interval),
                   reply_markup=kb_back,
                   parse_mode=messages.MARKDOWN)
    return SET_INTERVAL
コード例 #15
0
def add_remove_exchange(bot, update):
    """
    Begin dialog for change exchange's list
    
    Returns:
        :return: change exchange's list dialog identifier
             
    """
    msg = update.message
    user_ex = '`' + '`, `'.join(
        exchange_convert(
            mq.get_user_settings(msg.chat_id)[base_config.EXCHANGES])) + '`'
    msg.reply_text(messages.ADD_RM_EX_TEXT.format(user_ex),
                   reply_markup=kb_back,
                   parse_mode=messages.MARKDOWN)
    return ADD_RM_EX
コード例 #16
0
def remove_coin_dialog(bot, update):
    """Remove coin from user's list and send message to user about operation's result"""

    msg = update.message
    coin = msg.text[3:].strip(' \t\n\r').upper()
    user_coins = mq.get_user_settings(msg.chat_id)[base_config.COINS]
    if coin not in user_coins:
        msg.reply_text(
            messages.ALREADY_DISABLED_COIN.format('`' +
                                                  '`, `'.join(user_coins) +
                                                  '`'),
            parse_mode=messages.MARKDOWN)
        return ADD_RM_COINS
    mq.remove_from_list(msg.chat_id, list=base_config.COINS, value=coin)
    new_user_coins = '`' + '`, `'.join(set(user_coins) - {coin}) + '`'
    msg.reply_text(messages.REMOVE_COIN_SUCC_TEXT.format(new_user_coins),
                   parse_mode=messages.MARKDOWN)
    return ADD_RM_COINS
コード例 #17
0
def show_settings(bot, update):
    """
    Send message to user with his current settings
    """
    msg = update.message
    user_settings = mq.get_user_settings(msg.chat_id)
    coins = '`' + '`, `'.join(user_settings[base_config.COINS]) + '`'
    exchanges = '`' + '`, `'.join(
        exchange_convert(user_settings[base_config.EXCHANGES])) + '`'
    threshold = str(user_settings[base_config.THRESHOLD])
    interval = str(user_settings[base_config.INTERVAL])
    notifications = 'enabled 🔊' if user_settings[
        base_config.NOTIFICATIONS] else 'disabled 🔇'
    settings_message = messages.SETTINGS_TEXT.format(notifications, interval,
                                                     threshold, coins,
                                                     exchanges)
    msg.reply_text(settings_message, parse_mode=messages.MARKDOWN)
    return ALERTS_MENU
コード例 #18
0
def add_coin_dialog(bot, update):
    """Add coin to user's list and send message to user about operation's result"""

    msg = update.message
    coin = msg.text[4:].strip(' \t\n\r').upper()
    if coin not in mq.coins:
        msg.reply_text(messages.UNSUPPORTED_COIN_CONV_TEXT.format(coin),
                       parse_mode=messages.MARKDOWN)
        return ADD_RM_COINS
    user_coins = mq.get_user_settings(msg.chat_id)[base_config.COINS]
    if coin in user_coins:
        msg.reply_text(messages.ALREADY_ENABLED_COIN.format(coin),
                       parse_mode=messages.MARKDOWN)
        return ADD_RM_COINS
    mq.add_to_list(msg.chat_id, list=base_config.COINS, value=coin)
    new_user_coins = '`' + '`, `'.join(set(user_coins + [coin])) + '`'
    msg.reply_text(messages.ADD_COIN_SUCC_TEXT.format(new_user_coins),
                   parse_mode=messages.MARKDOWN)
    return ADD_RM_COINS
コード例 #19
0
def add_remove_coin(bot, update):
    """
    Begin dialog for change coin's list
    
    Args:
        :param bot: <telegram.Bot> bot instance
        :param update: <telegram.update.Update> update instance 
    
    Returns:
        :return: change coin's list dialog identifier
         
    """
    msg = update.message
    user_coins = '`' + '`, `'.join(
        mq.get_user_settings(msg.chat_id)[base_config.COINS]) + '`'
    msg.reply_text(messages.ADD_RM_COINS_TEXT.format(user_coins),
                   reply_markup=kb_back,
                   parse_mode=messages.MARKDOWN)
    return ADD_RM_COINS
コード例 #20
0
def remove_exchange_dialog(bot, update):
    """Remove exchange from user's list and send message to user about operation's result"""

    msg = update.message
    exchange = msg.text[3:].strip(' \t\n\r').replace('-', '_').lower()
    user_exchanges = mq.get_user_settings(msg.chat_id)[base_config.EXCHANGES]
    if exchange not in user_exchanges:
        user_exchanges = exchange_convert(user_exchanges)
        msg.reply_text(messages.ALREADY_DISABLED_EXCHANGE_TEXT.format(
            '`' + '`, `'.join(user_exchanges) + '`'),
                       parse_mode=messages.MARKDOWN)
        return ADD_RM_EX
    mq.remove_from_list(msg.chat_id,
                        list=base_config.EXCHANGES,
                        value=exchange)
    new_user_exchanges = '`' + '`, `'.join(
        exchange_convert(set(user_exchanges) - {exchange})) + '`'
    msg.reply_text(
        messages.REMOVE_EXCHANGE_SUCC_TEXT.format(new_user_exchanges),
        parse_mode=messages.MARKDOWN)
    return ADD_RM_EX
コード例 #21
0
def add_exchange_dialog(bot, update):
    """Add exchange to user's list and send message to user about operation's result """

    msg = update.message
    exchange = msg.text[4:].strip(' \t\n\r').replace('-', '_').lower()
    if exchange not in mq.exchanges:
        msg.reply_text(
            messages.UNSUPPORTED_EXCHANGE_CONV_TEXTS.format(exchange),
            parse_mode=messages.MARKDOWN)
        return ADD_RM_EX
    user_exchanges = mq.get_user_settings(msg.chat_id)[base_config.EXCHANGES]
    if exchange in user_exchanges:
        msg.reply_text(messages.ALREADY_ENABLED_EXCHANGE_TEXT.format(
            exchange_convert(exchange)),
                       parse_mode=messages.MARKDOWN)
        return ADD_RM_EX
    mq.add_to_list(msg.chat_id, list=base_config.EXCHANGES, value=exchange)
    new_user_exchanges = '`' + '`, `'.join(
        set(exchange_convert(user_exchanges + [exchange]))) + '`'
    msg.reply_text(messages.ADD_EXCHANGE_SUCC_TEXT.format(new_user_exchanges),
                   parse_mode=messages.MARKDOWN)
    return ADD_RM_EX
コード例 #22
0
def crawl(chat_id):
    """
    Return list of lists that contains coin name, two exchanges names, and diff in percent between
    bid and ask on coin on this exchanges (diff always positive, bid bigger than ask)
    
    Args:
        :param chat_id: <int> or <string> user's chat id
         
    Returns:
        :return: <list> of lists that contains 4 items: [coin name, first exchange name,
            second exchange name, diff in percent between bid and ask coin's price on exchanges],
            bid price is higher than ask price 
     
    """
    user_settings = mq.get_user_settings(chat_id)
    threshold = user_settings[base_config.THRESHOLD]
    user_coins = user_settings[base_config.COINS]
    user_exchanges = user_settings[base_config.EXCHANGES]
    res = []
    for user_coin in user_coins:
        try:
            coin_doc = mq.get_coin(user_coin)
            exchanges_list = []
            for user_exch in user_exchanges:
                try:
                    exch_doc_list = list(
                        filter(
                            lambda coin_exch: coin_exch['name'] == user_exch,
                            coin_doc['exchanges']))
                    if len(exch_doc_list) > 0:
                        exch_doc = exch_doc_list[0]
                        name = exch_doc['name']
                        ask = exch_doc['ask']
                        bid = exch_doc['bid']
                        if ask and bid:
                            exchanges_list.append({
                                'name': name,
                                'ask': ask,
                                'bid': bid
                            })
                except Exception as e:
                    logger.warning('chat_id: {}; error: {}\n'
                                   '{}'.format(chat_id, str(e), format_exc()))
            if len(exchanges_list) > 1:
                combined_exchanges = combinations(exchanges_list, 2)
                for exchanges_pair in combined_exchanges:
                    try:
                        check_res = _price_checker(
                            exchanges_pair=exchanges_pair,
                            threshold=threshold,
                            coin_name=coin_doc['name'].replace('/', '\_'))
                        if check_res:
                            res.append(check_res)
                    except Exception as e:
                        logger.warning('chat_id: {}; error: {}\n'
                                       '{}'.format(chat_id, str(e),
                                                   format_exc()))
        except Exception as e:
            logger.warning('chat_id: {}; error: {}\n'
                           '{}'.format(chat_id, str(e), format_exc()))
    return res