Ejemplo n.º 1
0
def snipe(obj):
    obj.current_strategy = 'Snipe'
    temp_settings = obj.strategy_settings['snipe']
    min_price = temp_settings['min_price']
    max_price = temp_settings['max_price']
    players = temp_settings['players']
    rotate = temp_settings['rotate']
    remove_keys = ['min_price', 'max_price', 'players', 'rotate']
    settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
    multi_log(obj, 'Sniping...', level='title')
    # Go through player lists
    if not rotate:
        for player in players:
            futbin_price = info.get_price(player, obj=obj)
            if futbin_price > 0:
                if obj.get_credits() > futbin_price and min_price <= futbin_price <= max_price:
                    snipe_criteria = {
                        'search_type': 'Players',
                        'player': player,
                        'quality': None,
                        'position': None,
                        'chem_style': None,
                        'nation': None,
                        'league': None,
                        'club': None,
                        'min_bin': None,
                        'include': None,
                        'exclude': None,
                    }
                    common_snipe(obj, name=info.get_player_info(snipe_criteria['player'], False)['name'], snipe_criteria=snipe_criteria, strategy='snipe', **settings)
    else:
        rotations_remaining = settings['max_tries']
        temp_settings = settings
        remove_keys = ['max_tries']
        settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
        while rotations_remaining > 0:
            for player in players:
                futbin_price = info.get_price(player, obj=obj)
                if futbin_price > 0:
                    if obj.get_credits() > futbin_price and min_price <= futbin_price <= max_price:
                        snipe_criteria = {
                            'search_type': 'Players',
                            'player': player,
                            'quality': None,
                            'position': None,
                            'chem_style': None,
                            'nation': None,
                            'league': None,
                            'club': None,
                            'min_bin': None,
                            'include': None,
                            'exclude': None,
                        }
                        common_snipe(obj, name=info.get_player_info(snipe_criteria['player'], False)['name'], snipe_criteria=snipe_criteria, strategy='snipe', max_tries=1, **settings)
            rotations_remaining -= 1
 def buy_and_search(target_player):
     player_info = info.get_player_info(target_player,
                                        include_futbin_price=True)
     player_name = player_info['name']
     bids = 0
     if obj.credits > player_info['futbin_price']:
         hunt_criteria = {
             'search_type': 'Players',
             'player': target_player,
             'quality': None,
             'position': None,
             'chem_style': None,
             'nation': None,
             'league': None,
             'club': None,
             'min_bin': None,
             'include': None,
             'exclude': None,
         }
         bids = common_hunt(obj=obj,
                            name=player_name,
                            hunt_criteria=hunt_criteria,
                            strategy='futbin_cheapest_sbc',
                            **settings)
     return bids
Ejemplo n.º 3
0
 def buy_and_search(target_player, group, total_b):
     bids = 0
     futbin_price = info.get_price(target_player['asset_id'], obj)
     if target_player['change'] >= 10 and futbin_price > 0:
         if (group == 'down' and obj.credits > target_player['futbin_price'] and target_player['futbin_price'] * 1.2 >= futbin_price) \
                 or (group == 'up' and obj.credits > target_player['futbin_price']):
             hunt_criteria = {
                 'search_type': 'Players',
                 'player': target_player['asset_id'],
                 'quality': None,
                 'position': None,
                 'chem_style': None,
                 'nation': None,
                 'league': None,
                 'club': None,
                 'min_bin': None,
                 'include': None,
                 'exclude': None,
             }
             if group == 'down':
                 max_bin = futbin_price * (1 -
                                           (target_player['change'] / 200))
             else:
                 max_bin = futbin_price * (1 -
                                           (target_player['change'] / 300))
             bids += common_hunt(obj,
                                 hunt_criteria=hunt_criteria,
                                 name=info.get_player_info(
                                     hunt_criteria['player'],
                                     False)['name'],
                                 strategy='futbin_market_{}'.format(group),
                                 price=max_bin,
                                 **settings)
     return bids
Ejemplo n.º 4
0
def arbitrage(obj):
    obj.current_strategy = 'Arbitrage'
    temp_settings = obj.strategy_settings['arbitrage']
    min_price = temp_settings['min_price']
    max_price = temp_settings['max_price']
    min_profit = temp_settings['min_profit']
    min_percentage_of_price = temp_settings['min_percentage_of_price']
    players = temp_settings['players']
    remove_keys = [
        'min_price', 'max_price', 'min_profit', 'min_percentage_of_price',
        'players'
    ]
    settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
    multi_log(obj, 'Conducting Arbitrage...', level='title')
    players_to_arbitrage = []
    # Go through player lists
    for player in players:
        futbin = info.get_price(player, obj, False, False, 'futbin')
        futhead = info.get_price(player, obj, False, False, 'futhead')
        if futbin != 0 and futhead != 0:
            potential = int(round((futbin * 0.95) - futhead))
            percent = abs(int(round((potential / futbin) * 100)))
            if potential > min_profit and percent > min_percentage_of_price:
                players_to_arbitrage.append(
                    (player, futhead, futbin, potential))
        sleep(0.25)
    if len(players_to_arbitrage) == 0:
        multi_log(obj, 'No players to arbitrage')
        return None
    for player in players_to_arbitrage:
        search_price = player[2]
        tier = info.get_tier(search_price)
        search_price = info.round_down(search_price,
                                       Global.rounding_tiers[tier])
        sell_price = info.round_down(player[2] - (0.2 * player[3]),
                                     Global.rounding_tiers[tier])
        if search_price > 0:
            if obj.get_credits(
            ) > search_price and min_price <= search_price <= max_price:
                snipe_criteria = {
                    'search_type': 'Players',
                    'player': player[0],
                    'quality': None,
                    'position': None,
                    'chem_style': None,
                    'nation': None,
                    'league': None,
                    'club': None,
                    'min_bin': None,
                    'include': None,
                    'exclude': None,
                }
                common_snipe(obj,
                             name=info.get_player_info(
                                 snipe_criteria['player'], False)['name'],
                             snipe_criteria=snipe_criteria,
                             price=search_price,
                             sell_price=sell_price,
                             strategy='arbitrage',
                             **settings)
Ejemplo n.º 5
0
 def check_transfer_targets(return_data):
     if obj.location != 'transfer_targets':
         obj.go_to('transfer_targets')
     multi_log(obj, 'Waiting on last bid to expire')
     while True:
         max_expire = 0
         watched_items = obj.__get_items__(
             p_element='../..',
             p_type='xpath',
             gp_element="//*[contains(text(), 'Watched Items')]",
             gp_type='xpath',
             get_price=False)
         if len(watched_items) == 0:
             break
         for item in watched_items:
             if item['time_left'] > max_expire:
                 max_expire = item['time_left']
         obj.keep_alive(max_expire + 5)
     expired_bids = obj.__get_items__(
         p_element='../..',
         p_type='xpath',
         gp_element="//*[contains(text(), 'Expired Items')]",
         gp_type='xpath',
         get_price=False)
     expired = {}
     for expired_bid in expired_bids:
         if expired_bid['asset_id'] in settings['players']:
             if expired_bid['asset_id'] not in list(expired.keys()):
                 expired[expired_bid['asset_id']] = {
                     'bid_amounts': 0,
                     'num_results': 0
                 }
             expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[
                 'current_bid']
             expired[expired_bid['asset_id']]['num_results'] += 1
     for asset, data in expired.items():
         return_data[asset]['average_bid'] = info.round_down(
             data['bid_amounts'] / data['num_results'], rounding)
     for return_asset, return_info in return_data.items():
         name = info.get_player_info(return_asset, False)['name']
         multi_log(
             obj,
             '{}\'s Average Bid: {}'.format(name,
                                            return_info['average_bid']))
         database.save_market_data(obj, name, return_info['asset_id'],
                                   return_info['average_bid'],
                                   return_info['minimum_bin'])
     obj.clear_expired()
     return {}, 0
Ejemplo n.º 6
0
def coin_transfer_list(obj, lose_coins, players):
    # List player for 80-90% of max with a bid random few steps below and for 1 day
    run_transfer_finish = False
    for i, player in enumerate(players):
        name = info.get_player_info(player)['name']
        tier = info.get_tier(38000)
        step = Global.rounding_tiers[tier]
        start_price = info.round_down(int(38000 + (rand(-10, 10) * step)), Global.rounding_tiers[tier])
        bin_price = info.round_down(start_price + (rand(6, 10) * step), Global.rounding_tiers[tier])
        result = find_player(obj, player)
        if len(result) == 1:
            run_transfer_finish = True
            obj.sell(result[0], start_price, bin_price, duration='1 Day')
            # Record min bid and bin and time to expire
            expires = datetime.now() + timedelta(days=1)
            with open(obj.config_file) as config:
                new_config = yaml.load(config)
                new_player = {
                    'asset_id': player,
                    'start_price': start_price,
                    'bin_price': bin_price,
                    'expires': expires,
                    'lose_coins': lose_coins
                    }
                try:
                    new_config['coin_transfer']['players'].append(new_player)
                except AttributeError:
                    new_config['coin_transfer']['players'] = []
                    new_config['coin_transfer']['players'].append(new_player)
            with open(obj.config_file, 'w') as update:
                yaml.dump(new_config, update)
        else:
            multi_log(obj, 'Error finding player {} for coin transfer'.format(name), level='error', notify=True, title='Coin Transfer Error')
    if run_transfer_finish:
        # Start buy script that runs in background
        coin_transfer_finish_prep.prep(obj.bot_number, lose_coins)
        multi_log(obj, 'Waiting for coin transfer to finish in the background.')
        obj.location = 'home'
    else:
        multi_log(obj, 'Something went wrong with coin transferring and there were no players to list.', level='error', notify=True, title='Coin Transfer Error')
Ejemplo n.º 7
0
def hunt(obj):
    obj.current_strategy = 'Hunt'
    temp_settings = obj.strategy_settings['hunt']
    min_price = temp_settings['min_price']
    max_price = temp_settings['max_price']
    players = temp_settings['players']
    remove_keys = ['min_price', 'max_price', 'players']
    settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
    multi_log(obj, 'Hunting...', level='title')
    total_bids = 0
    # Search and bid
    for player in players:
        futbin_price = info.get_price(player, obj=obj)
        if futbin_price > 0:
            if obj.get_credits() > futbin_price and min_price <= futbin_price <= max_price:
                hunt_criteria = {
                    'search_type': 'Players',
                    'player': player,
                    'quality': None,
                    'position': None,
                    'chem_style': None,
                    'nation': None,
                    'league': None,
                    'club': None,
                    'min_bin': None,
                    'include': None,
                    'exclude': None,
                }
                num_bids = common_hunt(obj=obj, name=info.get_player_info(hunt_criteria['player'], False)['name'], hunt_criteria=hunt_criteria, strategy='hunt', **settings)
                if num_bids == 'limit':
                    common_wait_to_expire(obj=obj, strategy='hunt')
                else:
                    total_bids += num_bids

    if total_bids > 0:
        if not settings['use_max_buy']:
            common_fight(obj=obj, strategy='hunt', settings=settings)
        else:
            common_wait_to_expire(obj=obj, strategy='hunt')
Ejemplo n.º 8
0
def amass(obj):
    obj.current_strategy = 'Amass'
    temp_settings = obj.strategy_settings['amass']
    players = temp_settings['players']
    remove_keys = ['players']
    settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
    multi_log(obj, 'Amassing players...', level='title')
    total_bids = 0
    # Search and bid
    for player in players:
        player_name = info.get_player_info(player,
                                           include_futbin_price=False)['name']
        hunt_criteria = {
            'search_type': 'Players',
            'player': player,
            'quality': None,
            'position': None,
            'chem_style': None,
            'nation': None,
            'league': None,
            'club': None,
            'min_bin': None,
            'include': None,
            'exclude': None,
        }
        num_bids = common_hunt(obj=obj,
                               name=player_name,
                               hunt_criteria=hunt_criteria,
                               strategy='amass',
                               **settings)
        if num_bids == 'limit':
            common_wait_to_expire(obj=obj, strategy='amass')
        else:
            total_bids += num_bids
    if total_bids > 0:
        common_wait_to_expire(obj=obj, strategy='amass')
        total_bids = 0
Ejemplo n.º 9
0
def acquire(obj, player_list, futbin_multiplier, increase_each_round=False, max_increases=5, sell_acquired_if_full=True, special_only=False):
    obj.current_strategy = 'Acquire'
    snipe_settings = obj.strategy_settings['acquire']['snipe']
    hunt_settings = obj.strategy_settings['acquire']['hunt']
    if type(player_list) is not list:
        new = [player_list]
        player_list = new
    if special_only:
        quality = 'Special'
    else:
        quality = None
    multi_log(obj, 'Acquiring Players...', level='title')
    # Go through player lists
    remaining_players = player_list
    acquired = []
    iteration = 1
    while len(remaining_players) > 0:
        bids = 0
        search_list = []
        if iteration > 1:
            snipe_settings['max_results'] = 9999999
        print('{:<30}  {:<20}  {:<20}'.format('Name', 'Futbin Price', 'Asset ID'))
        for player in remaining_players:
            player_info = info.get_player_info(player, include_futbin_price=True)
            print('{:<30}  {:<20}  {:<20}'.format(player_info['name'], player_info['futbin_price'], player))
            search_list.append(player_info)
        for player in search_list:
            name = player['name']
            futbin_price = player['futbin_price']
            tier = info.get_tier(futbin_price)
            max_bin = max(200, info.round_down(futbin_price * futbin_multiplier, Global.rounding_tiers[tier]))
            if increase_each_round:
                max_bin += Global.rounding_tiers[tier] * iteration
            include = []
            if quality and quality.lower() == 'special' and int(player['asset_id']) <= 300000:
                special_ids = info.get_special_ids(player['asset_id'])
                for s in list(special_ids.values()):
                    if int(s) >= 300000:
                        include.append(s)
                include.append(info.get_base_id(player['asset_id']))
                include.append(player.get('asset_id', None))
            elif int(player['asset_id']) > 300000:
                include.append(player['asset_id'])
                include.append(info.get_base_id(player['asset_id']))
            snipe_criteria = {
                'search_type': 'Players',
                'player': player['asset_id'],
                'quality': quality,
                'position': None,
                'chem_style': None,
                'nation': None,
                'league': None,
                'club': None,
                'min_bin': None,
                'include': include,
                'exclude': None,
            }
            snipe_result = common_snipe(obj=obj, snipe_criteria=snipe_criteria, name=name, strategy='acquire', price=max_bin,
                                        max_item_buys=1, sell_acquired_if_full=sell_acquired_if_full, **snipe_settings)
            if snipe_result == 'too many':
                multi_log(obj, 'Lots of results returned. Trying to get this cheaper by bidding...')
                max_bin -= Global.rounding_tiers[tier]
            elif snipe_result > 0:
                acquired.append((name, max_bin))
                for i, player_id in enumerate(remaining_players):
                    if str(player_id) == str(player['asset_id'] or str(player_id) in include):
                        remaining_players.pop(i)
                        break
                continue
            if obj.get_credits() > player['futbin_price']:
                num_bids = common_hunt(obj=obj, name=name, hunt_criteria=snipe_criteria, price=max_bin, strategy='acquire', max_item_bids=1, **hunt_settings)
                if num_bids == 'limit':
                    common_wait_to_expire(obj, 'acquire', remaining_players, acquired, sell_acquired_if_full=sell_acquired_if_full)
                    break
                elif num_bids == 'owned' or num_bids == 'sniped':
                    acquired.append((name, max_bin))
                    for i, player_id in enumerate(remaining_players):
                        if str(player_id) == str(player['asset_id']) or str(player_id) in include:
                            remaining_players.pop(i)
                            break
                else:
                    bids += num_bids
        if bids > 0:
            remaining_players, acquired = common_wait_to_expire(obj, 'acquire', remaining_players, acquired, sell_acquired_if_full=sell_acquired_if_full)
        if increase_each_round and iteration <= max_increases:
            iteration += 1
            if len(remaining_players) > 0:
                multi_log(obj, message='Increasing search price by {} step(s)'.format(min(iteration, max_increases)))
    multi_log(obj, message='Got all players!', level='green', notify=True, title='DONE')
    print('Acquired:')
    print('-' * 50)
    print('{:<30}  {:<6}'.format('Name', 'Price'))
    for player in acquired:
        print('{:<30}  {:<6}'.format(player[0], player[1]))
    return 'done'
Ejemplo n.º 10
0
 def add_player(player_to_search):
     rating = None
     quality = 'Special'
     search_panel = obj.__get_class__('ClubSearchFilters', as_list=False)
     sleep(Global.micro_min / 2)
     name_list = []
     if type(player_to_search) is int or (type(player_to_search) is str
                                          and any(n in player_to_search
                                                  for n in '1234567890')):
         have_id = True
         if int(player_to_search) >= 300000:
             quality = 'Special'
         try:
             db_player = Global.fifa_players[player_to_search]
         except KeyError:
             try:
                 player_to_search = info.get_base_id(player_to_search)
                 db_player = Global.fifa_players[player_to_search]
             except KeyError:
                 multi_log(
                     obj,
                     'No player with id {} in fifa_players.json, Unable to find player'
                     .format(player_to_search),
                     level='error')
                 return 'no_name'
         name_list = [
             db_player['first_name'], db_player['last_name'],
             db_player['surname']
         ]
         temp_names = []
         for name in name_list:
             if name:
                 temp_names.append(name)
         name_list = temp_names
         if len(name_list) == 3:
             name_list = [
                 name_list[2], name_list[0] + ' ' + name_list[1],
                 name_list[0] + ' ' + name_list[2],
                 name_list[1] + ' ' + name_list[2],
                 name_list[1] + ' ' + name_list[0], name_list[1],
                 name_list[2] + ' ' + name_list[0],
                 name_list[2] + ' ' + name_list[1], name_list[0]
             ]
         elif len(name_list) == 2:
             name_list = [
                 name_list[0] + ' ' + name_list[1],
                 name_list[1] + ' ' + name_list[0], name_list[1],
                 name_list[0]
             ]
         if not rating and int(player_to_search) < 300000:
             try:
                 rating = Global.fifa_players[player_to_search]['rating']
             except KeyError:
                 pass
     else:
         have_id = False
         name = player_to_search.title()
         name_list.append(name)
     name_found = False
     while not name_found:
         if not name_list:
             multi_log(
                 obj, message='Unable to find {}.'.format(player_to_search))
             return []
         name = name_list[0]
         name_box = search_panel.find_element_by_class_name('textInput')
         obj.__type_element__(name_box, name)
         name_parent = name_box.find_element_by_xpath('..')
         sleep(Global.micro_max)
         result_list = name_parent.find_element_by_tag_name('ul')
         results = result_list.find_elements_by_class_name('btn-text')
         if not results:
             if len(name_list) <= 1:
                 multi_log(obj,
                           'Unable to find results for {}'.format(
                               player_to_search),
                           level='warn',
                           notify=True,
                           title='Search Error')
                 return []
             else:
                 og_name = name
                 new_name = name_list[1]
                 multi_log(obj,
                           '\"{}\" not found. Trying \"{}\"'.format(
                               og_name, new_name),
                           level='debug')
                 search_panel = obj.__get_class__('ClubSearchFilters',
                                                  as_list=False)
                 name_list = name_list[1:]
         else:
             for r in results:
                 if have_id:
                     if rating and len(results) > 1:
                         result_parent = r.find_element_by_xpath('..')
                         result_rating = result_parent.find_element_by_class_name(
                             'btn-subtext').text
                         if str(rating) == str(result_rating):
                             obj.__click_element__(r)
                             name_found = True
                             break
                     else:
                         try:
                             obj.__click_element__(r)
                             name_found = True
                             break
                         except StaleElementReferenceException:
                             return []
                 else:
                     if name.lower() in parse.remove_accents(
                             r.text).lower():
                         if rating and len(results) > 1:
                             result_parent = r.find_element_by_xpath('..')
                             result_rating = result_parent.find_element_by_class_name(
                                 'btn-subtext').text
                             if str(rating) == str(result_rating):
                                 obj.__click_element__(r)
                                 name_found = True
                                 break
                         else:
                             obj.__click_element__(r)
                             name_found = True
                             break
             if not name_found:
                 name_list = name_list[1:]
     if quality is not None:
         quality = quality.title()
         quality_dropdown = search_panel.find_element_by_xpath(
             ".//*[contains(text(), 'Quality')]")
         obj.__click_element__(quality_dropdown)
         sleep(5)
         quality_parent = quality_dropdown.find_element_by_xpath('..')
         obj.__check_for_errors__()
         quality_parent.find_element_by_xpath(
             ".//*[contains(text(), '{}')]".format(quality)).click()
     else:
         try:
             obj.__click_element__(
                 search_panel.find_element_by_xpath(
                     './/div[3]/div[2]/div[3]/div/a')
             )  # Remove quality filter
         except ElementNotVisibleException:
             pass
     obj.__click_element__(
         search_panel.find_element_by_xpath(
             './/div[3]/div[2]/div[4]/div/a'))  # Remove position filter
     obj.__click_element__(
         search_panel.find_element_by_xpath(
             ".//*[contains(text(), 'Search')]"))
     sleep(Global.small_min)
     results = obj.__get_class__('MyClubResults', as_list=False)
     if not results:
         multi_log(
             obj, 'Missing {} for SBC solution'.format(
                 info.get_player_info(player_to_search, False)['name']))
         return False
     try:
         results.find_element_by_class_name('has-action').click()
         obj.__click_xpath__(".//*[contains(text(), 'Swap Player')]")
         return True
     except (TimeoutException, ElementNotVisibleException,
             NoSuchElementException):
         pass
     multi_log(
         obj, 'Missing {} for coin transfer'.format(
             info.get_player_info(player_to_search, False)['name']))
     return False
Ejemplo n.º 11
0
 def check_transfer_targets():
     if obj.location != 'transfer_targets':
         obj.go_to('transfer_targets')
     multi_log(obj, 'Waiting on last bid to expire')
     while True:
         max_expire = 0
         watched_items = obj.__get_items__(
             p_element='../..',
             p_type='xpath',
             gp_element="//*[contains(text(), 'Watched Items')]",
             gp_type='xpath',
             get_price=False)
         if len(watched_items) == 0:
             break
         for item in watched_items:
             if item['time_left'] > max_expire:
                 max_expire = item['time_left']
         obj.keep_alive(max_expire + 5)
     expired_bids = obj.__get_items__(
         p_element='../..',
         p_type='xpath',
         gp_element="//*[contains(text(), 'Expired Items')]",
         gp_type='xpath',
         get_price=False)
     expired = {}
     for expired_bid in expired_bids:
         if expired_bid['asset_id'] not in list(expired.keys()):
             expired[expired_bid['asset_id']] = {
                 'bid_amounts': 0,
                 'num_results': 0
             }
         expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[
             'current_bid']
         expired[expired_bid['asset_id']]['num_results'] += 1
     return_players = []
     for asset, data in expired.items():
         futbin_price = info.get_price(asset)
         tier = info.get_tier(futbin_price)
         rounding = Global.rounding_tiers[tier]
         average_bid = info.round_down(
             data['bid_amounts'] / data['num_results'], rounding)
         coins_from_sale = futbin_price * 0.95
         potential_profit = coins_from_sale - average_bid
         if settings[
                 'use_buy_percent'] and potential_profit >= coins_from_sale - (
                     futbin_price * obj.bin_settings['buy_percent']):
             return_players.append({
                 'asset_id':
                 asset,
                 'name':
                 info.get_player_info(asset, False)['name'],
                 'bid':
                 average_bid,
                 'futbin':
                 futbin_price
             })
         elif potential_profit >= settings['min_profit']:
             return_players.append({
                 'asset_id':
                 asset,
                 'name':
                 info.get_player_info(asset, False)['name'],
                 'bid':
                 average_bid,
                 'futbin':
                 futbin_price
             })
     for player_data in return_players:
         name = info.get_player_info(player_data['asset_id'], False)['name']
         multi_log(
             obj, '{}\'s Average Bid: {}  |  Futbin price: {}'.format(
                 name, player_data['bid'], player_data['futbin']))
     obj.clear_expired()
     return return_players
Ejemplo n.º 12
0
def silver_flip(obj):
    def check_transfer_targets():
        if obj.location != 'transfer_targets':
            obj.go_to('transfer_targets')
        multi_log(obj, 'Waiting on last bid to expire')
        while True:
            max_expire = 0
            watched_items = obj.__get_items__(
                p_element='../..',
                p_type='xpath',
                gp_element="//*[contains(text(), 'Watched Items')]",
                gp_type='xpath',
                get_price=False)
            if len(watched_items) == 0:
                break
            for item in watched_items:
                if item['time_left'] > max_expire:
                    max_expire = item['time_left']
            obj.keep_alive(max_expire + 5)
        expired_bids = obj.__get_items__(
            p_element='../..',
            p_type='xpath',
            gp_element="//*[contains(text(), 'Expired Items')]",
            gp_type='xpath',
            get_price=False)
        expired = {}
        for expired_bid in expired_bids:
            if expired_bid['asset_id'] not in list(expired.keys()):
                expired[expired_bid['asset_id']] = {
                    'bid_amounts': 0,
                    'num_results': 0
                }
            expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[
                'current_bid']
            expired[expired_bid['asset_id']]['num_results'] += 1
        return_players = []
        for asset, data in expired.items():
            futbin_price = info.get_price(asset)
            tier = info.get_tier(futbin_price)
            rounding = Global.rounding_tiers[tier]
            average_bid = info.round_down(
                data['bid_amounts'] / data['num_results'], rounding)
            coins_from_sale = futbin_price * 0.95
            potential_profit = coins_from_sale - average_bid
            if settings[
                    'use_buy_percent'] and potential_profit >= coins_from_sale - (
                        futbin_price * obj.bin_settings['buy_percent']):
                return_players.append({
                    'asset_id':
                    asset,
                    'name':
                    info.get_player_info(asset, False)['name'],
                    'bid':
                    average_bid,
                    'futbin':
                    futbin_price
                })
            elif potential_profit >= settings['min_profit']:
                return_players.append({
                    'asset_id':
                    asset,
                    'name':
                    info.get_player_info(asset, False)['name'],
                    'bid':
                    average_bid,
                    'futbin':
                    futbin_price
                })
        for player_data in return_players:
            name = info.get_player_info(player_data['asset_id'], False)['name']
            multi_log(
                obj, '{}\'s Average Bid: {}  |  Futbin price: {}'.format(
                    name, player_data['bid'], player_data['futbin']))
        obj.clear_expired()
        return return_players

    obj.current_strategy = 'Silver Flip'
    temp_settings = obj.strategy_settings['silver_flip']
    min_price = temp_settings['min_price']
    max_price = temp_settings['max_price']
    max_results = temp_settings['max_results']
    market_monitor = temp_settings['market_monitor']
    players = temp_settings['players']
    remove_keys = [
        'max_iterations', 'min_price', 'max_price', 'market_monitor',
        'players', 'max_results'
    ]
    settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
    multi_log(obj, 'Silver Flipping...', level='title')
    # Get market information
    bid_players = []
    if len(players) == 0 or market_monitor['refresh']:
        obj.strategy_settings['silver_flip']['players'] = []
        for league in market_monitor['leagues']:
            iterations = 0
            multi_log(obj, 'Getting market data for {}.'.format(league))
            while iterations < market_monitor['iterations']:
                full = False
                bid_results = obj.search(search_type='Players',
                                         quality='Silver',
                                         league=league,
                                         min_buy=min_price,
                                         max_buy=max_price)
                iterations += 1
                for bid_result in bid_results:
                    if bid_result['time_left'] <= market_monitor[
                            'max_time_left'] and bid_result[
                                'current_bid'] != bid_result['start_price']:
                        bid_result['element'].click()
                        obj.keep_alive(Global.micro_min)
                        err = obj.__check_for_errors__()
                        if err == 'limit':
                            full = True
                            break
                        side_panel = obj.__get_class__('DetailView',
                                                       as_list=False)
                        try:
                            side_panel.find_element_by_class_name(
                                'watch').click()
                            err = obj.__check_for_errors__()
                            if err == 'limit':
                                full = True
                                break
                        except (ElementNotVisibleException, TimeoutException,
                                NoSuchElementException):
                            pass
                while not full:
                    try:
                        nav_bar = obj.__get_class__('pagingContainer',
                                                    as_list=False)
                    except (ElementNotVisibleException, NoSuchElementException,
                            TimeoutException):
                        nav_bar = obj.__get_class__('mainHeader',
                                                    as_list=False)
                    try:
                        next_btn = nav_bar.find_element_by_class_name('next')
                        obj.__click_element__(next_btn)
                        bid_results = obj.__get_items__()
                        least_time_left = 99999999
                        for bid_result in bid_results:
                            if bid_result['time_left'] <= market_monitor[
                                    'max_time_left'] and bid_result[
                                        'current_bid'] != bid_result[
                                            'start_price']:
                                bid_result['element'].click()
                                obj.keep_alive(Global.micro_max)
                                err = obj.__check_for_errors__()
                                if err == 'limit':
                                    full = True
                                    break
                                side_panel = obj.__get_class__('DetailView',
                                                               as_list=False)
                                try:
                                    side_panel.find_element_by_class_name(
                                        'watch').click()
                                    err = obj.__check_for_errors__()
                                    if err == 'limit':
                                        full = True
                                        break
                                except (ElementNotVisibleException,
                                        TimeoutException,
                                        NoSuchElementException):
                                    pass
                            if bid_result['time_left'] < least_time_left:
                                least_time_left = bid_result['time_left']
                    except (ElementNotVisibleException, NoSuchElementException,
                            TimeoutException):
                        break
                    if full or least_time_left > market_monitor[
                            'max_time_left']:
                        break
                temp_players = check_transfer_targets()
                for temp_player in temp_players:
                    if temp_players not in players:
                        bid_players.append(temp_player)
    else:
        with open(obj.config_file) as config:
            old_config = yaml.load(config)
            bid_players = old_config['strategy_settings']['silver_flip'][
                'players']
    # Get BIN info if futbin update is too late
    for bid_player in bid_players:
        max_bin, update = info.get_price(bid_player['asset_id'],
                                         obj,
                                         return_updated=True)
        tier = info.get_tier(max_bin)
        rounding = Global.rounding_tiers[tier]
        now = datetime.now()
        last_update = bid_player.get('last_update', None)
        if last_update:
            difference = (now - last_update).seconds
        else:
            difference = (now - now - timedelta(hours=99)).seconds
        if update > settings['max_futbin_update'] and update < difference:
            multi_log(
                obj, 'Price data for {} out of date. Getting current price...'.
                format(info.get_player_info(bid_player['asset_id'])['name']))
            num_results = 0
            total_bins = 0
            bin_with_results = []
            while num_results < 3:
                bin_results = obj.search(search_type='Players',
                                         player=bid_player['asset_id'],
                                         max_bin=max_bin)
                if len(bin_results) > max_results:
                    if total_bins == 0:
                        min_bin = 999999
                        for bin_result in bin_results:
                            if bin_result['buy_now_price'] < min_bin:
                                min_bin = bin_result[
                                    'buy_now_price'] - Global.rounding_tiers[
                                        tier]
                            max_bin = min_bin
                        continue
                    else:
                        for bin_result in bin_results:
                            if bin_result[
                                    'buy_now_price'] not in bin_with_results:
                                total_bins += bin_result['buy_now_price']
                                num_results += 1
                        if len(bin_results) > 0:
                            bin_with_results.append(max_bin)
                elif len(bin_results) == 0:
                    max_bin += rounding * 2
                else:
                    for bin_result in bin_results:
                        if bin_result['buy_now_price'] not in bin_with_results:
                            total_bins += bin_result['buy_now_price']
                            num_results += 1
                            max_bin += rounding
                    if len(bin_results) > 0:
                        bin_with_results.append(max_bin)
            minimum_bin = info.round_down(total_bins / num_results, rounding)
            bid_player['minimum_bin'] = minimum_bin
            bid_player['last_update'] = datetime.now()
        else:
            bid_player['minimum_bin'] = max_bin
        coins_from_sale = bid_player['minimum_bin'] * 0.95
        potential_profit = coins_from_sale - bid_player['bid']
        current_players = []
        if bid_player['asset_id'] not in current_players:
            current_players.append(bid_player['asset_id'])
            if settings['use_buy_percent']:
                if potential_profit >= coins_from_sale - (
                        bid_player['minimum_bin'] *
                        obj.bin_settings['buy_percent']):
                    players.append(bid_player)
            else:
                if potential_profit >= settings['min_profit']:
                    players.append(bid_player)
    with open(obj.config_file) as config:
        new_config = yaml.load(config)
        new_config['strategy_settings']['silver_flip']['players'] = players
    with open(obj.config_file, 'w') as update:
        yaml.dump(new_config, update)
    total_bids = 0
    # Search and bid
    for player in players:
        futbin_price = player['minimum_bin']
        if futbin_price > 0:
            if obj.get_credits(
            ) > futbin_price and min_price <= futbin_price <= max_price:
                hunt_criteria = {
                    'search_type': 'Players',
                    'player': player['asset_id'],
                    'quality': None,
                    'position': None,
                    'chem_style': None,
                    'nation': None,
                    'league': None,
                    'club': None,
                    'min_bin': None,
                    'include': None,
                    'exclude': None,
                }
                num_bids = common_hunt(obj=obj,
                                       name=info.get_player_info(
                                           hunt_criteria['player'],
                                           False)['name'],
                                       price=futbin_price,
                                       hunt_criteria=hunt_criteria,
                                       strategy='silver_flip',
                                       **settings)
                if num_bids == 'limit':
                    common_wait_to_expire(obj=obj, strategy='hunt')
                else:
                    total_bids += num_bids

    if total_bids > 0:
        if not settings['use_max_buy']:
            common_fight(obj=obj, strategy='silver_flip', settings=settings)
        else:
            common_wait_to_expire(obj=obj, strategy='silver_flip')
Ejemplo n.º 13
0
def sbc_hunt(obj):
    obj.current_strategy = 'SBC Hunt'
    temp_settings = obj.strategy_settings['sbc_hunt']
    max_iterations = temp_settings['max_iterations']
    min_price = temp_settings['min_price']
    max_price = temp_settings['max_price']
    only_new = temp_settings['only_new']
    solutions_per_challenge = temp_settings['solutions_per_challenge']
    refresh_players = temp_settings['refresh_players']
    max_players = temp_settings['max_players']
    remove_keys = [
        'max_iterations', 'min_price', 'max_price', 'only_new',
        'refresh_players', 'players', 'solutions_per_challenge', 'max_players'
    ]
    settings = {k: v for k, v in temp_settings.items() if k not in remove_keys}
    multi_log(obj, 'SBC Hunting...', level='title')
    if refresh_players:
        all_players = []

        def remove_cookie_warning():
            sleep(Global.micro_max)
            script = "var elements=document.getElementsByClassName('cc_container');while(elements.length>0){elements[0].parentNode.removeChild(elements[0]);};"
            obj.driver.execute_script(script)

        def get_players():
            player_cards = obj.__get_class__('cardetails')
            sbc_solution_players = []
            for card in player_cards:
                try:
                    sbc_icon = card.find_element_by_class_name(
                        'sbc-alternatives')
                    if 'display: none' in sbc_icon.get_attribute('style'):
                        card_details = card.find_element_by_class_name(
                            'pcdisplay')
                        sbc_player_id = card_details.get_attribute(
                            'data-resource-id')
                        if platform == 'ps':
                            sbc_player_price = card_details.get_attribute(
                                'data-price-ps3')
                        elif platform == 'pc':
                            sbc_player_price = card_details.get_attribute(
                                'data-price-pc')
                        else:
                            sbc_player_price = card_details.get_attribute(
                                'data-price-xbl')
                        sbc_player_price = parse.price_parse(sbc_player_price)
                        if type(sbc_player_price) is not int:
                            sbc_player_price = 0
                        sbc_solution_players.append({
                            'asset_id': sbc_player_id,
                            'price': sbc_player_price
                        })
                except NoSuchElementException:
                    pass
            return sbc_solution_players

        if 'pc' in obj.platform:
            platform = 'pc'
        elif 'xbox' in obj.platform:
            platform = 'xbox'
        else:
            platform = 'ps'
        futbin_url = 'https://www.futbin.com/squad-building-challenges'
        multi_log(obj, 'Getting players from SBC challenges...')
        obj.driver.get(futbin_url)
        obj.location = 'futbin'
        remove_cookie_warning()
        if only_new:
            try:
                sets = obj.__get_class__('round-star-label')
            except TimeoutException:
                multi_log(obj, message='No new sets found')
                obj.__login__()
                return
        else:
            sets = obj.__get_class__('set_name')
        set_links = []
        for sbc in sets:
            gp = sbc.find_element_by_xpath('../..')
            set_name = gp.find_element_by_class_name('set_name').text.lower()
            if 'loan' not in set_name:
                set_column = gp.find_element_by_xpath('../../..')
                set_link = set_column.find_element_by_tag_name(
                    'a').get_attribute('href')
                set_links.append(set_link)
        for s_link in set_links:
            if len(all_players) >= max_players:
                break
            obj.new_tab(s_link)
            chal_links = []
            chal_names = obj.__get_class__('chal_name')
            for chal in chal_names:
                if len(all_players) >= max_players:
                    break
                chal_column = chal.find_element_by_xpath('../..')
                chal_link = chal_column.find_element_by_xpath(
                    ".//*[contains(text(), 'Completed Challenges')]"
                ).get_attribute('href')
                chal_links.append(chal_link)
            for c_link in chal_links:
                if len(all_players) >= max_players:
                    break
                obj.new_tab(c_link)
                remove_cookie_warning()
                # Get cheapest solution
                solutions = []
                relevant_price = '{}_price'.format(platform)
                remove_cookie_warning()
                table = obj.__get_class__('chal_table', as_list=False)
                for row in table.find_elements_by_xpath('.//tr'):
                    if 'thead_des' != row.get_attribute('class'):
                        data = row.find_elements_by_xpath('.//td')
                        if data:
                            try:
                                solution = {
                                    'ps_price':
                                    parse.price_parse(data[5].text),
                                    'xbox_price':
                                    parse.price_parse(data[6].text),
                                    'pc_price': parse.price_parse(data[7].text)
                                }
                                if solution[
                                        relevant_price] <= max_price * 11 * 3:
                                    solutions.append([
                                        solution, row, data[1].text,
                                        int(data[9].text),
                                        int(data[10].text)
                                    ])
                            except IndexError:
                                continue
                if len(solutions) == 0:
                    multi_log(obj,
                              'No good solutions found. Skipping...',
                              level='warn')
                else:
                    sorted_solutions = sorted(
                        solutions, key=lambda s: s[0][relevant_price])

                    for cheap in sorted_solutions[0:solutions_per_challenge +
                                                  1]:
                        try:
                            cheap_url = cheap[1].find_element_by_class_name(
                                'squad_url').get_attribute('href')
                            obj.new_tab(cheap_url)
                        except WebDriverException:
                            break
                        solution_players = get_players()
                        for player in solution_players:
                            if min_price <= player[
                                    'price'] <= max_price and player[
                                        'asset_id'] not in all_players and len(
                                            all_players) < max_players:
                                all_players.append(player['asset_id'])
                        with open(obj.config_file) as config:
                            new_config = yaml.load(config)
                            new_config['strategy_settings']['sbc_hunt'][
                                'players'] = all_players
                        with open(obj.config_file, 'w') as update:
                            yaml.dump(new_config, update)
                        obj.close_tab()
                obj.close_tab()
            obj.close_tab()
        obj.__login__()
    else:
        with open(obj.config_file) as config:
            old_config = yaml.load(config)
            all_players = old_config['strategy_settings']['sbc_hunt'][
                'players']
    multi_log(obj, 'Amassing SBC players...', level='header')
    total_bids = 0
    # Search and bid
    i = 0
    while i < max_iterations:
        for player in all_players:
            player_name = info.get_player_info(
                player, include_futbin_price=False)['name']
            hunt_criteria = {
                'search_type': 'Players',
                'player': player,
                'quality': None,
                'position': None,
                'chem_style': None,
                'nation': None,
                'league': None,
                'club': None,
                'min_bin': None,
                'include': None,
                'exclude': None,
            }
            num_bids = common_hunt(obj=obj,
                                   name=player_name,
                                   hunt_criteria=hunt_criteria,
                                   strategy='sbc_hunt',
                                   **settings)
            if num_bids == 'limit':
                common_wait_to_expire(obj=obj, strategy='sbc_hunt')
            else:
                total_bids += num_bids
        i += 1
    if total_bids > 0:
        common_wait_to_expire(obj=obj, strategy='sbc_hunt')
Ejemplo n.º 14
0
def price_fix(obj):
    obj.current_strategy = 'Price Fix'
    settings = obj.strategy_settings['price_fix']
    snipe_settings = settings['snipe']
    hunt_settings = settings['hunt']
    players = settings['players']
    multi_log(obj, 'Price-fixing Players...', level='title')
    bids = 0
    for num, player in players.items():
        name = info.get_player_info(player['asset_id'], False)['name']
        futbin_price = info.get_price(player['asset_id'], obj, False)
        if futbin_price > player['sell_price']:
            multi_log(
                obj,
                '{} price of {} is too low. Their Futbin price is {}'.format(
                    name, player['sell_price'], futbin_price),
                level='warn')
            continue
        max_bin = player['sell_price']
        tier = info.get_tier(max_bin)
        if settings['use_buy_percent']:
            max_bin = min(
                futbin_price,
                info.round_down(
                    max_bin * obj.bin_settings[tier]['buy_percent'],
                    Global.rounding_tiers[tier]))
        else:
            max_bin = info.round_down(
                (player['sell_price'] * 0.95) - settings['min_profit'],
                Global.rounding_tiers[tier])
        sell_price = player['sell_price']
        snipe_criteria = {
            'search_type': 'Players',
            'player': player['asset_id'],
            'quality': None,
            'position': None,
            'chem_style': None,
            'nation': None,
            'league': None,
            'club': None,
            'min_bin': None,
        }
        common_snipe(obj=obj,
                     snipe_criteria=snipe_criteria,
                     name=name,
                     strategy='price_fix',
                     price=max_bin,
                     sell_price=sell_price,
                     **snipe_settings)
        if obj.get_credits() > max_bin:
            num_bids = common_hunt(obj=obj,
                                   name=name,
                                   hunt_criteria=snipe_criteria,
                                   strategy='price_fix',
                                   price=max_bin,
                                   **hunt_settings)
            if num_bids == 'limit':
                common_wait_to_expire(obj=obj,
                                      strategy='price_fix',
                                      sell_price=sell_price)
            else:
                bids += num_bids
        if bids > 0:
            common_wait_to_expire(obj=obj,
                                  strategy='price_fix',
                                  sell_price=sell_price)
            bids = 0
Ejemplo n.º 15
0
def market_monitor(obj):
    def check_transfer_targets(return_data):
        if obj.location != 'transfer_targets':
            obj.go_to('transfer_targets')
        multi_log(obj, 'Waiting on last bid to expire')
        while True:
            max_expire = 0
            watched_items = obj.__get_items__(
                p_element='../..',
                p_type='xpath',
                gp_element="//*[contains(text(), 'Watched Items')]",
                gp_type='xpath',
                get_price=False)
            if len(watched_items) == 0:
                break
            for item in watched_items:
                if item['time_left'] > max_expire:
                    max_expire = item['time_left']
            obj.keep_alive(max_expire + 5)
        expired_bids = obj.__get_items__(
            p_element='../..',
            p_type='xpath',
            gp_element="//*[contains(text(), 'Expired Items')]",
            gp_type='xpath',
            get_price=False)
        expired = {}
        for expired_bid in expired_bids:
            if expired_bid['asset_id'] in settings['players']:
                if expired_bid['asset_id'] not in list(expired.keys()):
                    expired[expired_bid['asset_id']] = {
                        'bid_amounts': 0,
                        'num_results': 0
                    }
                expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[
                    'current_bid']
                expired[expired_bid['asset_id']]['num_results'] += 1
        for asset, data in expired.items():
            return_data[asset]['average_bid'] = info.round_down(
                data['bid_amounts'] / data['num_results'], rounding)
        for return_asset, return_info in return_data.items():
            name = info.get_player_info(return_asset, False)['name']
            multi_log(
                obj,
                '{}\'s Average Bid: {}'.format(name,
                                               return_info['average_bid']))
            database.save_market_data(obj, name, return_info['asset_id'],
                                      return_info['average_bid'],
                                      return_info['minimum_bin'])
        obj.clear_expired()
        return {}, 0

    check_sleep(obj)
    obj.current_strategy = 'Market Monitor'
    settings = obj.strategy_settings['market_monitor']
    multi_log(obj, 'Monitoring Market...', level='title')
    obj.clear_expired()
    cumulative_bids = 0
    return_data = {}
    for player in settings['players']:
        return_data[player] = {
            'asset_id': player,
            'minimum_bin': 0,
            'average_bid': 0
        }
        num_results = 0
        total_bins = 0
        player_info = info.get_player_info(player, include_futbin_price=True)
        name = player_info['name']
        futbin_price = player_info['futbin_price']
        tier = info.get_tier(futbin_price)
        rounding = Global.rounding_tiers[tier]
        max_bin = futbin_price - (rounding * 2)
        search_criteria = {
            'search_type': 'Players',
            'player': player,
        }
        multi_log(
            obj, 'Getting market data for {}. Futbin price: {}'.format(
                name, futbin_price))
        # Get bin info
        bin_with_results = []
        while num_results < settings['min_results']:
            bin_results = actions.search(obj=obj,
                                         max_bin=max_bin,
                                         **search_criteria)
            if len(bin_results) > settings['max_results']:
                if total_bins == 0:
                    min_bin = 999999
                    for bin_result in bin_results:
                        if bin_result['buy_now_price'] < min_bin:
                            min_bin = bin_result[
                                'buy_now_price'] - Global.rounding_tiers[tier]
                        max_bin = min_bin
                    continue
                else:
                    for bin_result in bin_results:
                        if bin_result['buy_now_price'] not in bin_with_results:
                            total_bins += bin_result['buy_now_price']
                            num_results += 1
                    if len(bin_results) > 0:
                        bin_with_results.append(max_bin)
            else:
                for bin_result in bin_results:
                    if bin_result['buy_now_price'] not in bin_with_results:
                        total_bins += bin_result['buy_now_price']
                        num_results += 1
                if len(bin_results) > 0:
                    bin_with_results.append(max_bin)
            max_bin += rounding
        minimum_bin = info.round_down(total_bins / num_results, rounding)
        multi_log(obj,
                  '{}\'s Average Minimum BIN: {}'.format(name, minimum_bin))
        return_data[player]['minimum_bin'] = minimum_bin
        # Get bid info
        max_buy = max(minimum_bin + (5 * rounding),
                      futbin_price + (3 * rounding))
        num_results = 0
        bid_results = actions.search(obj=obj,
                                     max_buy=max_buy,
                                     **search_criteria)
        for bid_result in bid_results:
            if bid_result['time_left'] <= 300 and (
                    bid_result['current_bid'] != bid_result['start_price']
                    or bid_result['current_bid'] <=
                (futbin_price -
                 (5 * rounding))) and num_results < settings['min_results']:
                try:
                    bid_result['element'].click()
                except WebDriverException:
                    try:
                        obj.__click_xpath__(".//*[contains(text(), 'OK')]")
                    except TimeoutException:
                        pass
                    check_transfer_targets(return_data)
                obj.keep_alive(Global.micro_min)
                side_panel = obj.__get_class__('DetailView', as_list=False)
                try:
                    side_panel.find_element_by_class_name('watch').click()
                    num_results += 1
                    cumulative_bids += 1
                except (ElementNotVisibleException, TimeoutException,
                        NoSuchElementException):
                    pass
                except WebDriverException:
                    obj.__click_xpath__(".//*[contains(text(), 'OK')]")
                    check_transfer_targets(return_data)
            elif num_results >= settings['min_results']:
                break
    check_transfer_targets(return_data)
    directory.split('\\')[:-2]) + '\config\\bot{}.yml'.format(gain_coins)
with open(gain_config_file) as config:
    gain_config = yaml.load(config)
settings = gain_config['coin_transfer']
remaining = []
sorted_players = result = sorted(settings['players'],
                                 key=lambda x: x['expires'])
for player in sorted_players:
    if str(player['lose_coins']) == str(
            lose_coins) and player['expires'] > datetime.now():
        remaining.append(player)
while len(remaining) > 0:
    for i, player in enumerate(remaining):
        asset_id = player['asset_id']
        base_id = info.get_base_id(asset_id)
        name = info.get_player_info(base_id,
                                    include_futbin_price=False)['name']
        bid_price = player['start_price']
        bin_price = player['bin_price']
        multi_log(
            None,
            'Received coin transfer information. Waiting until {} is near expiration'
            .format(name))
        expires = player['expires']
        multi_log(
            None, '{} will expire at {}'.format(
                name, '{0:%H:%M on %m/%d}'.format(expires)))
        start = expires - timedelta(minutes=5)
        while True:
            now = datetime.now()
            if start <= now < expires:
                break