def pago(bot, update, args): # if update.message.chat_id != -318148079: # return bot.send_message(chat_id=update.message.chat_id, # text='Utilizza il gruppo ufficiale') user = select_user(update) dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') dt = datetime.strptime(dt, '%Y-%m-%d %H:%M:%S') _, _ = aggiorna_offerte_chiuse(dt) try: args, offers_user = check_pago_format(args, user) except ValueError: return bot.send_message(chat_id=update.message.chat_id, text=check_pago_format(args, user)) money_db, message = message_with_payment(user, args, offers_user) dbf.db_update(table='pays', columns=['pay_money', 'pay_status'], values=[money_db, 'Not Confirmed'], where='pay_user = "******" AND pay_status IS NULL'.format(user)) return bot.send_message(parse_mode='HTML', chat_id=update.message.chat_id, text=message)
def update_fields(url): brow = sf.open_browser() brow.get(url) brow.refresh() fields_in_db = dbf.db_select(table='fields', columns=['name'], where='') # TODO open_panels() changed sf.open_panels(brow) fields_bets = sf.all_fields_and_bets(brow) for field_name, bets in fields_bets: active = "{'active':selection.selected}" all_bets = bets.find_elements_by_xpath(f'.//div[@ng-class="{active}"]') for bet in all_bets: name = sf.extract_bet_name(bet) if f'{field_name}_{name}' in fields_in_db: dbf.db_update(table='fields', columns=['found'], values=['ACTIVE'], where=f'name = "{field_name}_{name}"') inactive = "selection-disabled ng-scope" all_bets = bets.find_elements_by_xpath(f'.//div[@class="{inactive}"]') for bet in all_bets: name = sf.extract_bet_name(bet) if f'{field_name}_{name}' in fields_in_db: dbf.db_update(table='fields', columns=['found'], values=['INACTIVE'], where=f'name = "{field_name}_{name}"')
def aggiorna_status_calciatori(): """ Aggiorna lo status di ogni calciatore nella tabella "players" del db. Lo status sarà la fantasquadra proprietaria del giocatore mentre ogni giocatore svincolato avrà status = FREE. """ asta = pd.read_excel(os.getcwd() + f'/Asta{cfg.YEAR}.xlsx', sheet_name="Foglio1", usecols=range(0, 32, 4)) asta = asta.iloc[4:].copy() for team in asta.columns: pls = asta[team].dropna() for pl in pls: dbf.db_update(table='players', columns=['player_status'], values=[team], where=f'player_name = "{pl.upper()}"') dbf.db_update(table='players', columns=['player_status'], values=['FREE'], where='player_status IS NULL')
def aggiorna_status_calciatori(): """ Aggiorna lo status di ogni calciatore nella tabella "players" del db. Lo status sarà la fantasquadra proprietaria del giocatore mentre ogni giocatore svincolato avrà status = FREE. """ asta = pd.read_excel(os.getcwd() + '/Asta{}.xlsx'.format(anno), sheet_name="Foglio1-1", usecols=range(0, 24, 3)) for team in asta.columns: pls = asta[team].dropna() for pl in pls: dbf.db_update(database=dbase, table='players', columns=['player_status'], values=[team], where='player_name = "{}"'.format(pl)) dbf.db_update(database=dbase, table='players', columns=['player_status'], values=['FREE'], where='player_status IS NULL')
def aggiorna_offerte_chiuse(dt_now, return_offers=False): """ Confronta i tempi trascorsi da ogni offerta e chiude quelle che hanno già raggiunto o superato le 24 ore necessarie. Utilizzata all'interno di confermo_autobid(), confermo_offerta(), crea_riepilogo(), offro() e pago(). :param dt_now: datetime, data e ora attuale :param return_offers: bool :return offers_win: list, contiene le offerte ancora aperte :return offers_no: list, contiene le offerte chiuse e non ufficializzate """ offers_win = dbf.db_select(table='offers', columns=[ 'offer_id', 'offer_user', 'offer_player', 'offer_price', 'offer_dt' ], where='offer_status = "Winning"') offers_no = dbf.db_select(table='offers', columns=[ 'offer_id', 'offer_user', 'offer_player', 'offer_price', 'offer_dt' ], where='offer_status = "Not Official"') # Se tra le offerte aperte ce n'è qualcuna per la quale sono già scadute # le 24 ore allora il suo status viene modificato a 'Not Official' ed # elimina eventuali autobids attivi per quel calciatore for of_id, tm, pl, pr, dt in offers_win: dt2 = datetime.strptime(dt, '%Y-%m-%d %H:%M:%S') diff = dt_now - dt2 if diff.total_seconds() > cfg.TIME_WINDOW1: offers_no.append((of_id, tm, pl, pr, dt)) dbf.db_update(table='offers', columns=['offer_status'], values=['Not Official'], where=f'offer_id = {of_id}') dbf.db_update(table='players', columns=['player_status'], values=[tm], where=f'player_name = "{pl}"') dbf.db_delete(table='autobids', where=f'autobid_player = "{pl}"') if return_offers: # Ridefinisco le due liste trasformando le stringhe in oggetti datetime offers_win = [(el[0], el[1], el[2], el[3], datetime.strptime(el[4], '%Y-%m-%d %H:%M:%S')) for el in offers_win if el not in offers_no] offers_no = [(el[0], el[1], el[2], el[3], datetime.strptime(el[4], '%Y-%m-%d %H:%M:%S')) for el in offers_no] return offers_win, offers_no
def prezzo_base_automatico(user, ab_id, player_name, autobid_value, active): """ Presenta un'offerta a prezzo base o comunica la mancanza di un'asta attiva. Utilizzata all'interno di confermo_autobid(). L'oggetto del return può essere un tuple o una str in modo da distinguere il messaggio da inviare in chat privata e quello da inviare nel gruppo ufficiale. Utilizzata all'interno di confermo_autobid(). :param user: str, fantasquadra :param ab_id: int, id dell'autobid :param player_name: str, nome del calciatore :param autobid_value: int, valore autobid :param active: bool :return: tuple o str a seconda dei casi """ if active: pl_id, pr_base = dbf.db_select( table='players', columns=['player_id', 'player_price'], where=f'player_name = "{player_name}"')[0] if autobid_value < pr_base: dbf.db_delete(table='autobids', where=f'autobid_id = {ab_id}') return ('Valore autobid troppo basso. ' + f'Prezzo base: {pr_base}'), None dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') dbf.db_insert( table='offers', columns=[ 'offer_user', 'offer_player', 'offer_player_id', 'offer_price', 'offer_dt', 'offer_status' ], values=[user, player_name, pl_id, pr_base, dt, 'Winning']) dbf.db_update(table='autobids', columns=['autobid_status'], values=['Confirmed'], where=f'autobid_id = {ab_id}') private = ('Autobid impostato ed offerta a prezzo base ' + 'ufficializzata.' + cfg.SEPAR + crea_riepilogo_autobid(user)) group = (f'<i>{user}</i> offre per <b>{player_name}</b>' + cfg.SEPAR + crea_riepilogo(dt)) return private, group else: dbf.db_delete(table='autobids', where=f'autobid_id = {ab_id}') return 'Nessuna asta trovata per il calciatore scelto.', None
def save_mantra_lineup(which_day, fteam, final_lineup, n_malus): result = [f"{nm}:{rl}" for nm, rl in final_lineup] result.insert(0, str(n_malus)) dbf.db_update(table='mantra_lineups', columns=[f'day_{which_day}'], values=[', '.join(result)], where=f'team_name="{fteam}"')
def aaa(bot, update): user = select_user(update) dbf.db_update( table='offers', columns=['offer_status'], values=['Not Official'], where='offer_user = "******" AND offer_status = "Winning"'.format(user)) return bot.send_message(chat_id=update.message.chat_id, text='Puoi pagare')
def confirm(update, context): """ Confirm the match and update the database. """ chat_id = update.message.chat_id user = utl.get_nickname(update) if utl.wrong_chat(chat_id=chat_id): message_id = update.message.message_id context.bot.deleteMessage(chat_id=chat_id, message_id=message_id) return context.bot.send_message( chat_id=utl.get_user_chat_id(update), text='Usa questo gruppo per i comandi.') if utl.nothing_pending(nickname=user): return context.bot.send_message(chat_id=chat_id, text='Nessun pronostico da confermare') if utl.match_already_chosen(nickname=user): return cancel(update, context, text='Pronostico non valido perché già presente') if utl.match_already_started(table='predictions', nickname=user): return cancel(update, context, text='Match già iniziato') if utl.quote_outside_limits(nickname=user): return cancel(update, context, text='Quota fuori limiti') # Remove other "Not Confirmed" preds of the same match, if any utl.remove_pending_same_match(nickname=user) # Update prediction status dbf.db_update(table='predictions', columns=['status'], values=['Confirmed'], where=f'user = "******" AND status = "Not Confirmed"') # Insert bet in the table "to_play" bet_id = utl.get_pending_bet_id() utl.update_to_play_table(nickname=user, bet_id=bet_id) # Notify user in private chat context.bot.send_message(chat_id=chat_id, text='Pronostico aggiunto correttamente') # Send summary in group chat summary = utl.create_summary_pending_bet() context.bot.send_message(parse_mode='HTML', chat_id=cfg.GROUP_ID, text=summary) # Play the bet automatically if utl.autoplay(): return play(update, context)
def scrape_results() -> None: brow = sf.open_browser() brow.get(cfg.URL) close_all_headers(browser=brow) top_headers = active_top_headers(browser=brow) for top_header in top_headers: if league_is_correct(header=top_header): league = get_league(header=top_header) all_teams = dbf.db_select(table='simulations', columns=['team1', 'team2'], where=f'league = "{league}"') all_teams = [tm for match in all_teams for tm in match] all_teams = list(set(all_teams)) click_expander(browser=brow, header=top_header) matches = get_matches(browser=brow) for match in matches: match_info = matches_info(match_elem=match) status, tm1, ggtm1, ggtm2, tm2, pt = match_info team1, team2 = get_teams(all_teams=all_teams, team1_name=tm1, team2_name=tm2) if not correct_match_is_found(tm1_name=team1, tm2_name=team2): # TODO do something continue if status != 'Finale': dbf.db_delete(table='simulations', where=(f'team1 = "{team1}" AND ' f'team2 = "{team2}"')) continue (ggtm1pt, ggtm2pt, ggtm1st, ggtm2st) = goal_details(goals_tm1=ggtm1, goals_tm2=ggtm2, pt_info=pt) dbf.db_update(table='simulations', columns=['goals_tm1_pt', 'goals_tm2_pt', 'goals_tm1_st', 'goals_tm2_st'], values=[ggtm1pt, ggtm2pt, ggtm1st, ggtm2st], where=(f'team1 = "{team1}" AND ' f'team2 = "{team2}" AND ' 'label is NULL')) click_expander(browser=brow, header=top_header) brow.close()
def start_asta(): print('Type PLAYER_NAME, FANTATEAM, PRICE:') try: nm, tm, pr = input().split(',') pr = int(pr.strip()) except ValueError: print('WRONG FORMAT') return start_asta() all_nm = dbf.db_select(table='players', columns=['name'], where='status = "FREE"', database=cfa.DB_NAME) names = jaccard_result(name_to_fix=nm, all_options=all_nm, ngrams_lenght=3) all_tm = dbf.db_select(table='teams', columns=['team_name'], where='', database=cfa.DB_NAME) tm = jaccard_result(name_to_fix=tm, all_options=all_tm, ngrams_lenght=3)[0] for opt in names: real_team, roles = dbf.db_select(table='players', columns=['team', 'roles'], where=f'name = "{opt}"', database=cfa.DB_NAME)[0] real_team = real_team[:3].upper() print(f'{opt} ({real_team}\t{roles})\t\t{tm}\t\t{pr}') print(('ENTER to confirm, SPACE to cancel, ' 'any letter if player is wrong.')) answer = input() if not answer: too_low, min_price = offer_is_too_low(player_name=opt, offer_value=pr) if too_low: print(f'DENIED. Min price is {min_price}.') else: dbf.db_update(table='players', columns=['status'], values=[tm], where=f'name = "{opt}"', database=cfa.DB_NAME) update_excel(winner_team=tm, pl_name=opt, pl_team=real_team, pl_roles=roles, pl_price=pr) with open('logs_asta.txt', 'a') as f: f.write(f'{opt}, {real_team}, {roles}, {tm}, {pr}\n') return start_asta() elif answer == ' ': return start_asta() else: continue
def scrape_roles_and_players_serie_a(brow: webdriver) -> webdriver: """ Scrape all players from each real team in Serie A and their roles. Players are used when 6 politico is needed. """ # Players which are already in the db with their roles already_in_db = dbf.db_select(table='roles', columns=['name'], where='') # Download excel file with the data # url = 'https://www.fantacalcio.it/quotazioni-fantacalcio/mantra' # brow.get(url) # close_popup(brow) # time.sleep(3) # button = './/button[@id="toexcel"]' # wait_visible(brow, WAIT, button) # brow.find_element_by_xpath(button).click() # time.sleep(2) players = open_excel_file(cfg.QUOTAZIONI_FILENAME) # Create dict where keys are the teams of Serie A and values are lists # containing their players shortlists = defaultdict(list) for row in range(len(players)): rl, nm, tm = players.loc[row, ['R', 'Nome', 'Squadra']].values nm = format_player_name(player_name=nm) shortlists[tm.upper()].append(nm) # Update roles in the db if nm not in already_in_db: dbf.db_insert(table='roles', columns=['name', 'role'], values=[nm, rl]) # Update the db teams_in_db = dbf.db_select(table='all_players_serie_a', columns=['team'], where='') for team, shortlist in shortlists.items(): shortlist = ', '.join(shortlist) if team not in teams_in_db: dbf.db_insert(table='all_players_serie_a', columns=['team', 'day_1'], values=[team.upper(), shortlist]) else: dbf.db_update(table='all_players_serie_a', columns=[f'day_{last_day_played()}'], values=[shortlist], where=f'team = "{team}"') return brow
def add_labels() -> None: pred_ids = dbf.db_select(table='simulations', columns=['id'], where='label IS NULL') for i, pred_id in enumerate(pred_ids, 1): print(f'\r{i}/{len(pred_ids)}', end='') label = 'WINNING' if pred_is_correct(pred_id=pred_id) else 'LOSING' dbf.db_update(table='simulations', columns=['label'], values=[label], where=f'id = {pred_id}')
def job_update_score(context): """ Once all matches in the bet are concluded, update the database. """ context.bot.send_message(chat_id=cfg.TESTAZZA_ID, text='Aggiornamento db') bets = utl.get_bets_to_update() if not bets: msg = 'Nessuna scommessa da aggiornare.' return context.bot.send_message(chat_id=context.job.context, text=msg) # Go to main page brow = sf.open_browser() brow.get(cfg.MAIN_PAGE) time.sleep(5) brow.refresh() time.sleep(5) # Login sf.login(brow) budget = sf.get_budget(brow) utl.update_budget(budget=budget) sf.open_profile_options(brow) sf.open_profile_history(brow) sf.set_time_filter(brow) sf.show_bets_history(brow) sf.update_database(brow, bets) brow.quit() dt = datetime.datetime.now() last_update = (f'*Last update:\n {dt.day}/{dt.month}/{dt.year} ' + f'at {dt.hour}:{dt.minute}') dbf.db_update(table='last_results_update', columns=['message'], values=[last_update], where='') os.system('python Classes.py') cfg.LOGGER.info('UPDATE - Database aggiornato correttamente.') context.bot.send_photo(chat_id=cfg.GROUP_ID, photo=open(f'score_{cfg.YEARS[-1]}.png', 'rb'))
def update_players_status_in_stats(team_name: str, list_of_players: list) -> None: # First set all players of team as FREE dbf.db_update(table='stats', columns=['status'], values=['FREE'], where=f'status = "{team_name}"') # Then update the status for player in list_of_players: dbf.db_update(table='stats', columns=['status'], values=[team_name], where=f'name = "{player}"')
def scrape_lineups_schemes_points() -> webdriver: """ Scrape lineups, schemes and absolute points. """ brow = manage_adblock() starting_day = last_day_played() + 1 for day in range(starting_day, 36): brow.get(f'{cfg.BASE_URL}formazioni/{day}') if day == starting_day: close_popup(brow) if wrong_day_for_lineups(brow=brow, day_to_scrape=day): return brow # Find all matches matches, scrape_points = find_matches(brow=brow) # Iterate the matches and update database for match in matches: match_data = get_match_data(brow=brow, match_element=match) for team, scheme, regular, bench, abs_points in match_data: team_name = get_team_name(brow=brow, team_element=team) captains, complete_lineup = get_lineup(regular_elem=regular, bench_elem=bench) dbf.db_update(table='captains', columns=[f'day_{day}'], values=[captains], where=f'team_name="{team_name}"') dbf.db_update(table='lineups', columns=[f'day_{day}'], values=[complete_lineup], where=f'team_name="{team_name}"') dbf.db_update(table='schemes', columns=[f'day_{day}'], values=[get_scheme(scheme_elem=scheme)], where=f'team_name="{team_name}"') if scrape_points: dbf.db_update( table='absolute_points', columns=[f'day_{day}'], values=[get_abs_points(points_elem=abs_points)], where=f'team_name="{team_name}"') return brow
def aggiorna_offerte_chiuse(dt_now): """ Confronta i tempi trascorsi da ogni offerta e chiude quelle che hanno già raggiunto o superato le 24 ore necessarie. Utilizzata all'interno di crea_riepilogo() e pago(). :param dt_now: datetime, data e ora attuale :return offers_win: list, contiene le offerte ancora aperte :return offers_no: list, contiene le offerte chiuse e non ufficializzate """ offers_win = dbf.db_select(table='offers', columns_in=[ 'offer_id', 'offer_user', 'offer_player', 'offer_price', 'offer_datetime' ], where='offer_status = "Winning"') offers_no = dbf.db_select(table='offers', columns_in=[ 'offer_id', 'offer_user', 'offer_player', 'offer_price', 'offer_datetime' ], where='offer_status = "Not Official"') for of_id, tm, pl, pr, dt in offers_win: dt2 = datetime.strptime(dt, '%Y-%m-%d %H:%M:%S') diff = dt_now - dt2 if diff.days > 0: offers_no.append((of_id, tm, pl, pr, dt)) dbf.db_update(table='offers', columns=['offer_status'], values=['Not Official'], where='offer_id = {}'.format(of_id)) offers_win = [(el[0], el[1], el[2], el[3], datetime.strptime(el[4], '%Y-%m-%d %H:%M:%S')) for el in offers_win if el not in offers_no] offers_no = [(el[0], el[1], el[2], el[3], datetime.strptime(el[4], '%Y-%m-%d %H:%M:%S')) for el in offers_no] return offers_win, offers_no
def pago(bot, update, args): """ Aggiorna la tabella "pays" del db con lo status di "Not Confirmed". :param bot: :param update: :param args: list, input dell'user :return: messaggio in chat """ chat_id = update.message.chat_id if chat_id == cfg.FANTA_ID: return bot.send_message(chat_id=chat_id, text='Utilizza la chat privata') user = select_user(update) dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') utl.aggiorna_offerte_chiuse(datetime.strptime(dt, '%Y-%m-%d %H:%M:%S')) # Elimino dal db tutte i pagamenti precedenti non confermati dall'utente dbf.db_delete(table='pays', where=f'pay_user = "******" AND pay_status IS NULL') # Controllo che il formato sia corretto result = utl.check_pago_format(args) if type(result) == str: return bot.send_message(chat_id=chat_id, text=result) else: acquisto, pagamento = result # Creo il messaggio di conferma ed aggiorno il db con il pagamento # provvisorio result = utl.message_with_payment(user, acquisto, pagamento) if type(result) == str: return bot.send_message(chat_id=chat_id, text=result) else: money_db, message = result dbf.db_update(table='pays', columns=['pay_money'], values=[money_db], where=f'pay_user = "******" AND pay_status IS NULL') return bot.send_message(parse_mode='HTML', chat_id=chat_id, text=message)
def aggiorna_db_con_nuove_quotazioni(): """ Aggiorna tutte le quotazioni dei calciatori prima di ogni mercato. Gestisce anche i trasferimenti interni alla Serie A aggiornando la squadra di appartenenza e l'arrivo di nuovi calciatori. """ mercati = ['PrimoMercato', 'SecondoMercato', 'TerzoMercato'] last = '' for i in mercati: name = os.getcwd() + '/Quotazioni_' + i + '.xlsx' if os.path.isfile(name): last = name players = pd.read_excel(last, sheet_name="Tutti", usecols=[1, 2, 3, 4]) pls_in_db = dbf.db_select(database=dbase, table='players', columns_in=['player_name']) for x in range(len(players)): role, pl, team, price = players.iloc[x].values if pl in pls_in_db: dbf.db_update(database=dbase, table='players', columns=['player_team', 'player_price'], values=[team[:3].upper(), int(price)], where='player_name = "{}"'.format(pl)) else: dbf.db_insert( database=dbase, table='players', columns=[ 'player_name', 'player_team', 'player_roles', 'player_price', 'player_status' ], values=[pl, team[:3].upper(), role, int(price), 'FREE']) del players
def update_stats() -> None: """ Update database used for market with stats. """ names_in_stats = dbf.db_select(table='stats', columns=['name'], where='') players = open_excel_file(cfg.QUOTAZIONI_FILENAME) for row in range(players.shape[0]): roles, name, team, price = players.iloc[row][[ 'R', 'Nome', 'Squadra', 'Qt. A' ]] name = format_player_name(player_name=name) matches, mv = calculate_mv(name) bonus = calculate_all_bonus(name) malus = calculate_all_malus(name) mfv = round(mv + (bonus - malus) / matches, 2) if matches else 0 regular, going_in, going_out = calculate_regular_in_out(name) if name in names_in_stats: dbf.db_update(table='stats', columns=[ 'name', 'team', 'roles', 'mv', 'mfv', 'regular', 'going_in', 'going_out', 'price' ], values=[ name, team, roles, mv, mfv, regular, going_in, going_out, price ], where=f'name = "{name}"') else: # print('New name for stats: ', name) dbf.db_insert(table='stats', columns=[ 'name', 'team', 'roles', 'status', 'mv', 'mfv', 'regular', 'going_in', 'going_out', 'price' ], values=[ name, team, roles, 'FREE', mv, mfv, regular, going_in, going_out, price ]) os.remove(cfg.QUOTAZIONI_FILENAME)
def aggiorna_budgets(): """ Aggiorna lo status di ogni calciatore nella tabella "players" del db. Lo status sarà la fantasquadra proprietaria del giocatore mentre ogni giocatore svincolato avrà status = FREE. """ asta = pd.read_excel(os.getcwd() + f'/Asta{cfg.YEAR}.xlsx', sheet_name="Foglio1", usecols=range(0, 32), nrows=3) for i in range(0, 32, 4): team = asta.iloc[:, i].name budget = int(asta.iloc[2, i + 1]) dbf.db_update(table='budgets', columns=['budget_value'], values=[budget], where=f'budget_team = "{team}"')
def fill_teams_table(): leagues = dbf.db_select(table='leagues', columns=['name'], where='') shorts = [] for league in leagues: old_teams = dbf.db_select(table='teams', columns=['name'], where=f'league = "{league}"') old_teams = set(old_teams) new_teams = dbf.db_select(table='matches', columns=['team1', 'team2'], where=f'league = "{league}"') new_teams = [el for pair in new_teams for el in pair] new_teams = set(new_teams) if new_teams - old_teams: dbf.db_delete(table='teams', where=f'league = "{league}"') for team in new_teams: dbf.db_insert(table='teams', columns=['league', 'name'], values=[league, team]) short = team.replace(' ', '') short = re.findall(r'[*A-Z]+', short)[0] short = short[:3] if league != 'CHAMPIONS LEAGUE' else short[:4] if short not in shorts: dbf.db_update(table='teams', columns=['short'], values=[short], where=f'name = "{team}"') shorts.append(short) else: dbf.db_update(table='teams', columns=['short'], values=['-'], where=f'name = "{team}"')
def scrape_allplayers_fantateam(brow: webdriver) -> webdriver: """ Scrape the complete set of players per each fantateam, day by day. """ # Go the webpage brow.get(f'{cfg.BASE_URL}rose') # Wait for this element to be visible check = './/h4[@class="has-select clearfix public-heading"]' wait_visible(brow, cfg.WAIT, check) # Find all the tables containing the shortlists shortlists = ('.//li[contains(@class,' '"list-rosters-item raised-2 current-competition-team")]') shortlists = brow.find_elements_by_xpath(shortlists) for shortlist in shortlists: team_elem = shortlist.find_element_by_xpath('.//h4') team_name = team_elem.get_attribute('innerText').strip() # Names containers players = [] names = shortlist.find_elements_by_xpath('.//td[@data-key="name"]') for player in names: name = player.get_attribute('innerText') name = format_player_name(player_name=name) players.append(name) # Update "all_players" table dbf.db_update(table='all_players', columns=[f'day_{last_day_played()}'], values=[', '.join(players)], where=f'team_name = "{team_name}"') # Update "stats" table update_players_status_in_stats(team_name, players) return brow
def update_budget(budget: float) -> None: dbf.db_update(table='last_results_update', columns=['budget'], values=[budget], where='')
def check_offer_value(user, offer_id, player, dt): """ Controlla che il valore dell'offerta sia valido. Nell'ordine: - In caso di prima offerta, se il valore offerto è sufficiente - In caso di rilancio, se l'offerta supera quella già presente - Nel caso la superi, se l'offerta supera un possibile autobid Utilizzata all'interno di confermo_offerta(). :param user: str, fantasquadra :param offer_id: int, id dell'offerta :param player: str, nome del giocatore :param dt: str, data ed ora attuali :return : str o tuple, messaggi in chat """ offer = dbf.db_select(table='offers', columns=['offer_price'], where=f'offer_id = {offer_id}')[0] # Prendo dal db i dettagli dell'ultima offerta valida per questo # calciatore, qualora ci sia try: last_id, last_user, last_offer = dbf.db_select( table='offers', columns=['offer_id', 'offer_user', 'offer_price'], where=(f'offer_player = "{player}" AND ' + 'offer_status = "Winning"'))[0] except IndexError: last_id = 0 last_user = None last_offer = 0 # Se si tratta di prima offerta, ne confronto il valore con il prezzo base # del calciatore ed aggiorno il db if not last_offer: price = dbf.db_select(table='players', columns=['player_price'], where=f'player_name = "{player}"')[0] if offer < price: dbf.db_delete(table='offers', where=f'offer_id = {offer_id}') return f'Offerta troppo bassa. Quotazione: {price}' else: dbf.db_update(table='offers', columns=['offer_dt', 'offer_status'], values=[dt, 'Winning'], where=f'offer_id = {offer_id}') private = 'Offerta aggiornata correttamente.' group = (f'<i>{user}</i> offre per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group # Se si tratta di rilancio, controllo che l'offerta superi quella già # esistente else: if offer <= last_offer: dbf.db_delete(table='offers', where=f'offer_id = {offer_id}') return ('Offerta troppo bassa. ' + f'Ultimo rilancio: {last_offer}, {last_user}') else: # Se la supera, resta da confrontarla con un eventuale autobid. # Quindi seleziono l'autobid già impostato dall'altro user oppure, # qualora non esista, assegno valore nullo ad alcune variabili in # modo da gestire il codice successivo try: iid, ab_user, nonce, tag, encr_value = dbf.db_select( table='autobids', columns=[ 'autobid_id', 'autobid_user', 'autobid_nonce', 'autobid_tag', 'autobid_value' ], where=f'autobid_player = "{player}"')[0] last_ab = int( dbf.decrypt_value(nonce, tag, encr_value).decode()) except IndexError: iid = 0 ab_user = None last_ab = 0 # Se l'offerta è inferiore all'autobid di un altro user: cancello # l'offerta dal db, aggiorno il valore dell'offerta dell'altro # utente e, qualora questo nuovo valore raggiunga il suo limite # di autobid, elimino tale autobid dal db if offer < last_ab: dbf.db_delete(table='offers', where=f'offer_id = {offer_id}') dbf.db_update(table='offers', columns=['offer_price', 'offer_dt'], values=[offer + 1, dt], where=f'offer_id = {last_id}') if offer + 1 == last_ab: dbf.db_delete(table='autobids', where=f'autobid_id = {iid}') private = ("Offerta troppo bassa. Non hai superato" + f" l'autobid di {ab_user}.") group = (f'<i>{user}</i> ha tentato un rilancio ' + f'per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group # Se invece l'offerta supera l'ultimo autobid allora cancello tale # autobid dal db ed aggiorno tutti gli altri parametri else: dbf.db_delete(table='autobids', where=f'autobid_id = {iid}') dbf.db_update(table='offers', columns=['offer_dt', 'offer_status'], values=[dt, 'Winning'], where=f'offer_id = {offer_id}') dbf.db_update(table='offers', columns=['offer_status'], values=['Lost'], where=f'offer_id = {last_id}') private = 'Offerta aggiornata correttamente.' group = (f'<i>{user}</i> ha rilanciato per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group
def check_autobid_value(user, player, new_id, new_ab): """ Esamina tutti i possibili casi ed agisce di conseguenza. :param user: str, fantasquadra :param player: str, calciatore :param new_id: int, id dell'autobid nel db :param new_ab: int, valore dell'autobid :return: tuple, bool o str """ # Controllo se c'è già un'asta in corso per il calciatore try: last_id, last_user, last_offer = dbf.db_select( table='offers', columns=['offer_id', 'offer_user', 'offer_price'], where=(f'offer_player = "{player}" AND ' + 'offer_status = "Winning"'))[0] except IndexError: last_id = 0 last_user = None last_offer = 0 # Se non c'è, gestisco la situazione in modo da presentare automaticamente # un'offerta a prezzo base oppure segnalare all'utente l'assenza di un'asta # attiva if not last_offer: private, group = prezzo_base_automatico(user, new_id, player, new_ab, active=True) return private, group # Se invece c'è allora ne confronto il valore con l'autobid che si sta # provando ad impostare. Se l'autobid è inferiore o uguale, lo elimino dal # db e lo segnalo all'user if new_ab <= last_offer: dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') return ("Valore autobid troppo basso. Impostare un valore superiore" + " all'attuale offerta vincente."), None # Se è superiore allora devo controllare che l'user dell'ultima offerta non # abbia impostato anche lui un autobid else: old_ab = dbf.db_select(table='autobids', columns=[ 'autobid_id', 'autobid_nonce', 'autobid_tag', 'autobid_value' ], where=(f'autobid_player = "{player}" AND ' + 'autobid_status = "Confirmed"')) # Caso 1: non c'è autobid ed il detentore dell'offerta è un avversario. # In questo caso l'avversario perde l'offerta a favore del nuovo user. # Il valore della nuova offerta sarà automaticamente uguale ad 1 # fantamilione in più rispetto alla precedente if not old_ab and user != last_user: dbf.db_update(table='offers', columns=['offer_status'], values=['Lost'], where=f'offer_id = {last_id}') dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') pl_id = dbf.db_select(table='players', columns=['player_id'], where=f'player_name = "{player}"')[0] dbf.db_insert( table='offers', columns=[ 'offer_user', 'offer_player', 'offer_player_id', 'offer_price', 'offer_dt', 'offer_status' ], values=[user, player, pl_id, last_offer + 1, dt, 'Winning']) # Cancello l'autobid nel caso venga raggiunto il suo valore if new_ab == last_offer + 1: dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') private = ('Hai dovuto utilizzare tutto il tuo autobid. ' + 'Reimposta un valore più alto nel caso volessi ' + 'continuare ad usarlo.' + cfg.SEPAR + crea_riepilogo_autobid(user)) else: dbf.db_update(table='autobids', columns=['autobid_status'], values=['Confirmed'], where=f'autobid_id = {new_id}') private = ('Offerta aggiornata ed autobid impostato ' + 'correttamente.' + cfg.SEPAR + crea_riepilogo_autobid(user)) group = (f'<i>{user}</i> rilancia per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group # Caso 2: non c'è autobid ed il detentore dell'offerta è lo stesso user. # In questo caso viene semplicemente impostato l'autobid elif not old_ab and user == last_user: dbf.db_update(table='autobids', columns=['autobid_status'], values=['Confirmed'], where=f'autobid_id = {new_id}') return ('Autobid impostato correttamente.' + cfg.SEPAR + crea_riepilogo_autobid(user)), None # Se c'è già un autobid si aprono altri possibili casi else: old_id, last_nonce, last_tag, last_value = old_ab[0] old_ab = int( dbf.decrypt_value(last_nonce, last_tag, last_value).decode()) # Caso 3: il nuovo autobid supera il vecchio ed il detentore # dell'offerta è un avversario. Simile al Caso 1. # Il valore della nuova offerta sarà automaticamente uguale ad 1 # fantamilione in più rispetto al precedente autobid if new_ab > old_ab and user != last_user: dbf.db_update(table='offers', columns=['offer_status'], values=['Lost'], where=f'offer_id = {last_id}') dbf.db_delete(table='autobids', where=f'autobid_id = {old_id}') dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') pl_id = dbf.db_select(table='players', columns=['player_id'], where=f'player_name = "{player}"')[0] dbf.db_insert( table='offers', columns=[ 'offer_user', 'offer_player', 'offer_player_id', 'offer_price', 'offer_dt', 'offer_status' ], values=[user, player, pl_id, old_ab + 1, dt, 'Winning']) if new_ab == old_ab + 1: dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') private = ('Hai dovuto utilizzare tutto il tuo autobid. ' + 'Reimposta un valore più alto nel caso ' + 'volessi continuare ad usarlo.' + cfg.SEPAR + crea_riepilogo_autobid(user)) else: dbf.db_update(table='autobids', columns=['autobid_status'], values=['Confirmed'], where=f'autobid_id = {new_id}') private = ('Offerta aggiornata ed autobid impostato ' + 'correttamente.' + cfg.SEPAR + crea_riepilogo_autobid(user)) group = (f'<i>{user}</i> rilancia ' + f'per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group # Caso 4: il nuovo autobid supera il vecchio ed il detentore # dell'offerta è lo stesso user. Viene aggiornato l'autobid # precedente al nuovo valore più alto elif new_ab > old_ab and user == last_user: nonce, tag, value = dbf.encrypt_value(str(new_ab)) dbf.db_update( table='autobids', columns=['autobid_nonce', 'autobid_tag', 'autobid_value'], values=[nonce, tag, value], where=f'autobid_id = {old_id}') dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') return (f'Hai aumentato il tuo autobid per {player} ' + f'da {old_ab} a {new_ab}.' + cfg.SEPAR + crea_riepilogo_autobid(user)), None # Caso 5: il nuovo autobid non supera il vecchio ed il detentore # dell'offerta è un avversario. Il nuovo autobid non viene # confermato e l'offerta del detentore viene aggiornata ad un # valore pari all'autobid tentato dall'user più 1 fantamilione elif new_ab < old_ab and user != last_user: dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') dbf.db_update(table='offers', columns=['offer_price', 'offer_dt'], values=[new_ab + 1, dt], where=f'offer_id = {last_id}') if old_ab == new_ab + 1: dbf.db_delete(table='autobids', where=f'autobid_id = {old_id}') private = 'Autobid troppo basso.' group = (f'<i>{user}</i> ha tentato un rilancio' + f' per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group # Caso 6: il nuovo autobid non supera il vecchio ed il detentore # dell'offerta è lo stesso user. Viene aggiornato l'autobid # precedente al nuovo valore più basso elif new_ab < old_ab and user == last_user: nonce, tag, value = dbf.encrypt_value(str(new_ab)) dbf.db_update( table='autobids', columns=['autobid_nonce', 'autobid_tag', 'autobid_value'], values=[nonce, tag, value], where=f'autobid_id = {old_id}') dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') return (f'Hai diminuito il tuo autobid per {player} ' + f'da {old_ab} a {new_ab}.' + cfg.SEPAR + crea_riepilogo_autobid(user)), None # Caso 7: il nuovo autobid è uguale al vecchio ed il detentore # dell'offerta è un avversario. Viene convalidato quello del # detentore per averlo impostato in anticipo elif new_ab == old_ab and user != last_user: dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') sex = dbf.db_select(table='teams', columns=['team_sex'], where=f'team_name = "{last_user}"')[0] dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') dbf.db_delete(table='autobids', where=f'autobid_id = {old_id}') dbf.db_update(table='offers', columns=['offer_price', 'offer_dt'], values=[new_ab, dt], where=f'offer_id = {last_id}') private = (f"Autobid uguale a quello di {last_user}." + " Ha la precedenza " + sex + " perché l'ha " + "impostato prima.") group = (f'<i>{user}</i> ha tentato un rilancio' + f' per <b>{player}</b>.' + cfg.SEPAR + crea_riepilogo(dt)) return private, group # Caso 8: il nuovo autobid è uguale al vecchio ed il detentore # dell'offerta è lo stesso user. elif new_ab == old_ab and user == last_user: dbf.db_delete(table='autobids', where=f'autobid_id = {new_id}') return 'Hai già impostato questo valore di autobid.', None
def check_offer_value(offer_id, player, dt): """ Controlla se l'offerta è valida. Nell'ordine controlla: - In caso di rilancio, se è troppo tardi per farlo - In caso di rilancio, se l'offerta supera quella già presente - In caso di prima offerta, se il valore offerto è sufficiente Utilizzata all'interno di conferma_offerta(). :param offer_id: int, id dell'offerta :param player: str, nome del giocatore :param dt: str, data ed ora attuali :return last_id: int, l'id dell'offerta più recente per questo giocatore. 0 nel caso non si tratti di rilancio ma di prima offerta. """ offer = dbf.db_select(table='offers', columns_in=['offer_price'], where='offer_id = {}'.format(offer_id))[0] price = dbf.db_select(table='players', columns_in=['player_price'], where='player_name = "{}"'.format(player))[0] try: cond1 = 'offer_player = "{}" AND offer_status = "Winning"'.format( player) cond2 = 'offer_player = "{}" AND offer_status = "Not Official"'.format( player) last_id, last_user, last_offer, last_dt = dbf.db_select( table='offers', columns_in=[ 'offer_id', 'offer_user', 'offer_price', 'offer_datetime' ], where='{} OR {}'.format(cond1, cond2) # where='offer_player = "{}" AND '.format(player) + # 'offer_status = "Winning"' )[0] except IndexError: last_offer = 0 last_user = '' last_id = 0 last_dt = '2030-01-01 00:00:00' if too_late_to_offer(dt, last_dt): dbf.db_delete(table='offers', where='offer_id = {}'.format(offer_id)) dbf.db_update(table='offers', columns=['offer_status'], values=['Not Official'], where='offer_id = {}'.format(last_id)) dbf.db_update(table='players', columns=['player_status'], values=[last_user], where='player_name = "{}"'.format(player)) return ('Troppo tardi, 24 ore scadute. ' + '{} acquistato da {}'.format(player, last_user)) if offer <= last_offer: dbf.db_delete(table='offers', where='offer_id = {}'.format(offer_id)) return ('Offerta troppo bassa. ' + 'Ultimo rilancio: {}, {}'.format(last_offer, last_user)) elif offer < price: dbf.db_delete(table='offers', where='offer_id = {}'.format(offer_id)) return 'Offerta troppo bassa. Quotazione: {}'.format(price) else: return last_id
def play(update, context): """ Play the bet online. """ # Check matches to play available = utl.get_preds_available_to_play() pending_txt = utl.remove_not_confirmed_before_play() too_late_txt = utl.remove_too_late_before_play() if not available: message = f'{pending_txt}\n{too_late_txt}\n\nNessun pronostico attivo' return context.bot.send_message(chat_id=cfg.GROUP_ID, text=message) args = context.args # Euros to bet euros = utl.euros_to_play(args) # Message to update n_bets = len(available) live_info = 'Pronostici aggiunti: {}/{}' mess_id = context.bot.send_message(chat_id=cfg.GROUP_ID, text=live_info.format( 0, n_bets)).message_id # Go to main page brow = sf.open_browser() brow.get(cfg.MAIN_PAGE) time.sleep(5) # Add all predictions for i, (url, panel, field, bet) in enumerate(available, 1): brow.get(url) sf.add_bet_to_basket(brow, panel, field, bet) context.bot.edit_message_text(chat_id=cfg.GROUP_ID, message_id=mess_id, text=live_info.format(i, n_bets)) # Insert euros to bet sf.insert_euros(brow, euros) # Login brow = sf.login(brow=brow) live_info = f'Pronostici aggiunti: {n_bets}/{n_bets}\n\nLogged in' context.bot.edit_message_text(chat_id=cfg.GROUP_ID, message_id=mess_id, text=live_info) # Budget before playing money_before = sf.get_budget(brow) # Place bet sf.place_bet(brow) # Budget after playing money_after = sf.get_money_after(brow, before=money_before) if money_after < money_before: cfg.LOGGER.info('PLAY - Bet has been played.') if money_after != money_before - euros: msg = "L'importo scommesso è diverso da quello selezionato." context.bot.send_message(parse_mode='HTML', chat_id=cfg.GROUP_ID, text=msg) bet_id = utl.get_pending_bet_id() prize = utl.get_quotes_prod(bet_id=bet_id) # Update bet table dt = datetime.datetime.now().replace(microsecond=0) dbf.db_update(table='bets', columns=['date', 'euros', 'status'], values=[dt, euros, 'Placed'], where=f'id = {bet_id}') # Empty table with bets dbf.empty_table(table='to_play') utl.update_budget(budget=money_after) # Print the summary msg = 'Scommessa giocata correttamente.\n\n' msg += utl.create_list_of_matches(bet_id=bet_id) msg += f'\nVincita: <b>{prize*euros: .2f} €</b>\n\n\n' msg += f'\nBudget aggiornato: <b>{money_after} €</b>' context.bot.send_message(parse_mode='HTML', chat_id=cfg.GROUP_ID, text=msg) else: msg = 'Non è stato possibile giocare la scommessa.' context.bot.send_message(chat_id=cfg.GROUP_ID, text=msg) brow.quit()
def conferma_offerta(bot, update): """ Conferma l'offerta effettuata (se valida) ed aggiorna il db di conseguenza. Infine manda un messaggio in chat con tutte le offerte aperte e chiuse. :param bot: :param update: :return: Nothing """ # if update.message.chat_id != -318148079: # return bot.send_message(chat_id=update.message.chat_id, # text='Utilizza il gruppo ufficiale') user = select_user(update) dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') try: of_id, pl = select_offer_to_confirm(user) except ValueError: return bot.send_message(chat_id=update.message.chat_id, text=select_offer_to_confirm(user)) # not_off = dbf.db_select( # table='offers', # columns_in=['offer_player'], # where='offer_status = "Not Official"') # if pl in not_off: # dbf.db_delete( # table='offers', # where='offer_user = "******" and offer_player = "{}"'.format(user, # pl)) # return bot.send_message(chat_id=update.message.chat_id, # text='Asta già conclusa.') status = dbf.db_select(table='players', columns_in=['player_status'], where='player_name = "{}"'.format(pl))[0] if status != 'FREE': dbf.db_delete(table='offers', where='offer_id = {}'.format(of_id)) return bot.send_message( chat_id=update.message.chat_id, text='Giocatore non svincolato ({}).'.format(status)) last_valid_offer = check_offer_value(of_id, pl, dt) if type(last_valid_offer) == str: return bot.send_message(chat_id=update.message.chat_id, text=last_valid_offer) pl_id = dbf.db_select(table='players', columns_in=['player_id'], where='player_name = "{}"'.format(pl))[0] delete_not_conf_offers_by_others(pl_id, user) dbf.db_update(table='offers', columns=['offer_datetime', 'offer_status'], values=[dt, 'Winning'], where='offer_id = {}'.format(of_id)) dbf.db_update(table='offers', columns=['offer_status'], values=['Lost'], where='offer_id = {}'.format(last_valid_offer)) crea_riepilogo(bot, update, dt)
def conferma_pagamento(bot, update): # if update.message.chat_id != -318148079: # return bot.send_message(chat_id=update.message.chat_id, # text='Utilizza il gruppo ufficiale') user = select_user(update) try: pay_id, pl, pr, mn = dbf.db_select( table='pays', columns_in=['pay_id', 'pay_player', 'pay_price', 'pay_money'], where='pay_user = "******" AND pay_status = "Not Confirmed"'.format( user))[-1] dbf.db_delete(table='pays', where='pay_id != {} AND pay_player = "{}"'.format( pay_id, pl)) except IndexError: return bot.send_message(chat_id=update.message.chat_id, text='Nulla da confermare per {}'.format(user)) budget = dbf.db_select(table='budgets', columns_in=['budget_value'], where='budget_team = "{}"'.format(user))[0] # if len(mn) > 1: mn = mn.split(', ') for i in mn: try: int(i) except ValueError: budget += dbf.db_select(table='players', columns_in=['player_price'], where='player_name = "{}"'.format( i.split(' (')[0]))[0] if budget < pr: dbf.db_delete(table='pays', where='pay_user = "******" AND pay_player = "{}"'.format( user, pl)) return bot.send_message(chat_id=update.message.chat_id, text='Budget insufficiente'.format(user)) else: dbf.db_update(table='budgets', columns=['budget_value'], values=[budget - pr], where='budget_team = "{}"'.format(user)) dbf.db_update(table='players', columns=['player_status'], values=[user], where='player_name = "{}"'.format(pl)) dbf.db_update( table='offers', columns=['offer_status'], values=['Official'], where='offer_player = "{}" AND offer_status = "Not Official"'. format(pl)) dbf.db_update(table='pays', columns=['pay_status'], values=['Confirmed'], where='pay_player = "{}"'.format(pl)) for i in mn: try: int(i) except ValueError: dbf.db_update(table='players', columns=['player_status'], values=['FREE'], where='player_name = "{}"'.format( i.split(' (')[0])) return bot.send_message(chat_id=update.message.chat_id, text='Rosa {} aggiornata'.format(user))