def __init__(self, tournament, tag_remap={}): self.tag_remap = tag_remap self._parse_url(tournament) smash = pysmash.SmashGG() self.sets = smash.tournament_show_sets(self.tournament, self.event) self.entrants = smash.tournament_show_players(self.tournament, self.event)
def get_tournament_placings(bracket_url): # Map tags to their respective placings in this bracket placings_map = {} if 'challonge' in bracket_url: LOG.info('just entering "get tournament palcings') standings_html, status = hit_url(bracket_url + '/standings') soup = BeautifulSoup(standings_html, "html.parser") tds = soup.find_all('td') # Cycle thorugh these tds, and find the ones that represent different placings current_placing = 1 for td in tds: if td.has_attr('class') and td['class'][0] == 'rank': current_placing = int(td.getText()) span = td.find('span') # Player tags are kept in <span> elements if span: player = span.getText() # Coalesce tags player = get_coalesced_tag(player) placings_map[player.lower()] = current_placing LOG.info( 'just got placing {} for player {} in bracket {}'.format( current_placing, player, bracket_url)) # This bracket is from smashgg else: smash = pysmash.SmashGG() url_parts = bracket_url.split('/') if 'tournament' in url_parts and 'events' in url_parts: t = url_parts[url_parts.index('tournament') + 1] e = url_parts[url_parts.index('events') + 1] players = smash.tournament_show_players(t, e) for player_dict in players: tag = player_dict['tag'] # sanitize the tag tag = ''.join([i if ord(i) < 128 else ' ' for i in tag]) place = player_dict['final_placement'] placings_map[tag.lower()] = place return placings_map
def __init__(self, tournament, event, tier, points, ids=None): self.tournament = tournament self.event = event self.tier = tier self.points = float(points) self.ids = ids # Wrapper. self.smash = pysmash.SmashGG() # Datos self.players = self.smash.tournament_show_players( self.tournament, self.event) self.all_sets = self.smash.tournament_show_sets( self.tournament, self.event) # If we specify certain events, select sets from those events. if ids: self.all_sets = [ x for x in self.all_sets if x["bracket_id"] in self.ids ] # Para imprimir self.winners = 'w' self.losers = 'l'
#!/usr/bin/python import json import operator import argparse import os import pysmash parser = argparse.ArgumentParser(description="Pull Tournament Results") parser.add_argument('tournament', type=str) args = parser.parse_args() smash = pysmash.SmashGG() tournament = args.tournament events = smash.tournament_show_events(tournament) directory = '../fgcbot/data/tournaments/' + tournament os.mkdir(directory) for event in events['events']: os.mkdir(directory + '/' + event) sets = smash.tournament_show_players(tournament, event) sets.sort(key=operator.itemgetter('final_placement')) with open( '../fgcbot/data/tournaments' + '/' + tournament + '/' + event + '/results.json', 'w+') as f: json.dump(sets, f)
def analyze_smashgg_tournament(db, url, scene, dated, urls_per_player=False, display_name=None, testing=False): global smash global skip_count if smash == None: smash = pysmash.SmashGG() # For testing purposes, sometimes we don't want to update the web use_web = not testing match_pairs = [] tag_to_gid = {} # Exctract the tournament and event names # eg url: # https://smash.gg/tournament/pulsar-premier-league/events/rocket-league-3v3/brackets/68179 # tournament name = pulsar-premier-leauge # event name = rocket-league-3v3 url_parts = url.split('/') LOG.info("about to analyze smashgg bracket: {}".format(url)) if 'tournament' in url_parts and 'events' in url_parts: t = url_parts[url_parts.index('tournament')+1] e = url_parts[url_parts.index('events')+1] try: start_at_epoch = smash.tournament_show(t)['start_at'] date = datetime.datetime.utcfromtimestamp(start_at_epoch).strftime("%Y-%m-%d") except Exception: LOG.exc('We couldnt find a date for tournament {}'.format(t)) date = '2017-09-26' # The event will be either 'melee' or 'wiiu' players = smash.tournament_show_players(t, e) # Sleep between requests to prevent rate limiting time.sleep(.5) # Check if these players are already in the players table scenes = bracket_utils.get_list_of_scene_names() for player in players: p = sanitize_tag(player['tag']) create_player_if_not_exist(p, scene, db, testing) if not testing: # Calculate the group for these two players gid = calculate_and_update_group(p, scene, db) if not p in tag_to_gid else tag_to_gid[p] tag_to_gid[p] = gid # Create a map of ID to tag tag_id_dict = {} for player in players: id = int(player["entrant_id"]) tag = player["tag"] # sanitize the tag tag = sanitize_tag(tag) tag = get_coalesced_tag(tag) tag_id_dict[id] = tag sets = smash.tournament_show_sets(t, e) # Sleep between requests to prevent rate limiting time.sleep(.5) placings = bracket_utils.get_tournament_placings(url) for s in sets: l_id = int(s['loser_id']) w_id = int(s['winner_id']) s1 = s['entrant_1_score'] s2 = s['entrant_2_score'] # If we don't have score info, default to 3-0 entrant_1_score = 3 if s1 == None else int(s1) entrant_2_score = 0 if s2 == None else int(s2) score = json.dumps([max(entrant_1_score, entrant_2_score), min(entrant_1_score, entrant_2_score)]) if l_id in tag_id_dict and w_id in tag_id_dict: loser = tag_id_dict[l_id] winner = tag_id_dict[w_id] if loser in placings and winner in placings: winner_place = placings[winner] loser_place = placings[loser] # Only record this match if at least one of these players got top 64 # Probably no one cares about r1 pools matches between two scrubs # Having less matches will also reduce time needed to rank players if winner_place > 64 and loser_place > 64: skip_count = skip_count + 1 if skip_count % 100 == 0: LOG.info('Both these players suck, so not entering this match {} got {} and {} got {}. Have now skipped {} total'.format(winner, winner_place, loser, loser_place, skip_count)) continue else: # We don't have the placing for this player. Skip continue else: continue sql = "INSERT INTO matches(player1, player2, winner, date, scene, url, display_name, score) VALUES ('{winner}', '{loser}', '{winner}', '{date}', '{scene}', '{url}', '{display_name}', '{score}');" args = {'winner': winner, 'loser': loser, 'winner': winner, 'date': date, 'scene': scene, 'url': url, 'display_name': display_name, 'score': score} db.exec(sql, args) # Get the group that these 2 players belong to if not testing: g1 = tag_to_gid[winner] g2 = tag_to_gid[loser] if not testing: # Also update the player web with this match match_pairs.append((winner, g1, loser, g2)) else: LOG.info("ERROR PARSING SMASHGG: {}".format(url)) return if not testing: # we need to pass a list of scenes to the player web LOG.info('about to update match pairs for bracket {}'.format(url)) update_web(match_pairs, db) LOG.info('finished updating match pairs for bracket {}'.format(url))
def __setSmashGGMatches(self, url): cur = self.db.cursor() #Smash.gg wrapper smash = pysmash.SmashGG() # Get tournament name tournament_name = url.split("/tournament/")[1].split("/")[0] # # # Ann Arbor should be replaced by region use tourney information to find venue address and get State from there. # # p = (0, tournament_name, stripNum(tournament_name), 'Ann Arbor') cur.execute("INSERT INTO tournaments (id, name, series, location, date) VALUES (%s, %s, %s, %s, default);", p) players = smash.tournament_show_players(tournament_name, 'melee-singles') # Add all players to database if they're not in there already for player in players: # Santitize tag of fuckery tag = player['tag'].lower() tag = tag.replace(" ", "") re.sub(r"[^\\x00-\\x7f]", "", tag) tag.replace(u"\u2122", '') #tag = str(tag.encode('ascii', 'replace')) cur.execute("SELECT * FROM players WHERE tag = %s;", [tag]) result = cur.fetchone() # Add player to database if not result: self.players[tag] = glicko2.Player() p = (0, tag, player['entrant_id']) cur.execute("INSERT INTO players (id, tag, sponsor, smashgg_id, skill) VALUES (%s, %s, null, %s, default);", p) else: p = (player['entrant_id'], tag) cur.execute("UPDATE players SET smashgg_id = %s WHERE tag = %s;", p) self.db.commit() cur.execute("SELECT id FROM players WHERE tag = %s;", [tag]) player_id = cur.fetchone()[0] cur.execute("SELECT id FROM tournaments WHERE name = %s;", [tournament_name]) tournament_id = cur.fetchone()[0] cur.execute("INSERT INTO attended (id, player_id, tournament_id) VALUES (%s, %s, %s);", [0, player_id, tournament_id]) self.db.commit() # Split this into another function sets = smash.tournament_show_sets(tournament_name, 'melee-singles') for match in sets: entrant1Id = match['entrant_1_id'] entrant2Id = match['entrant_2_id'] winner_id = match['winner_id'] loser_id = match['loser_id'] entrant1_tag = '' entrant2_tag = '' winner_tag = '' loser_tag = '' winner_set_count = 0 loser_set_count = 0 entrant1Score = match['entrant_1_score'] entrant2Score = match['entrant_2_score'] cur.execute("SELECT tag FROM players WHERE smashgg_id = %s;", [entrant1Id]) entrant1_tag = cur.fetchone()[0] cur.execute("SELECT tag FROM players WHERE smashgg_id = %s;", [entrant2Id]) entrant2_tag = cur.fetchone()[0] if entrant1_tag and entrant2_tag: entrant1_tag = entrant1_tag.lower() entrant1_tag = entrant1_tag.replace(" ", "") entrant2_tag = entrant2_tag.lower() entrant2_tag = entrant2_tag.replace(" ", "") newMatch = Match(entrant1_tag, entrant1Score, entrant2_tag, entrant2Score) self.matches.append(newMatch) self.db.commit() cur.close() return len(players)
def get_smashgg_brackets(pages=None, all_brackets=True, singles=True, scene='pro'): results = 0 per_page = 5 page = 1 if pages == None else pages[0] brackets = {} smash = pysmash.SmashGG() def iterate(): print('PAGE {}'.format(page)) # melee #results_url = 'https://smash.gg/results?per_page=5&filter=%7B%22completed%22%3Atrue%2C%22videogameIds%22%3A%221%22%7D&page={}'.format(page) results_url = "https://smash.gg/tournaments?per_page=30&filter=%7B%22upcoming%22%3Afalse%2C%22videogameIds%22%3A4%2C%22past%22%3Atrue%7D&page={}".format( page) #wiiu #results_url = 'https://smash.gg/results?per_page=5&filter=%7B%22completed%22%3Atrue%2C%22videogameIds%22%3A3%7D&page={}'.format(page) #Get the html page r = get(results_url) data = r.text soup = BeautifulSoup(data, "html.parser") grep = 'singles' if singles else 'doubles' #print(data) links = soup.find_all('a') for link in links: try: if link.has_attr('href') and 'tournament' in link['href']: url_parts = link['href'].split('/') t = url_parts[url_parts.index('tournament') + 1] if t in brackets: continue events = smash.tournament_show_events(t) def get_event(events, matches): # Do we have a melee singles event? for e in events['events']: if all([match in e for match in matches]): return e return None if scene == 'pro_wiiu': e = get_event(events, ['wii', 'single']) if e == None: e = get_event(events, ['single']) if e == None: e = get_event(events, ['wii']) if e == None: e = get_event(events, ['smash-4']) if e == None: e = get_event(events, ['smash4']) if e == None: e = get_event(events, ['smash']) if e == None: continue elif scene == 'pro': e = get_event(events, ['melee', 'single']) if e == None: e = get_event(events, ['single']) if e == None: e = get_event(events, ['gamecube']) if e == None: e = get_event(events, ['melee']) if e == None: e = get_event(events, ['smash']) if e == None: continue url = 'https://smash.gg/tournament/{}/events/{}'.format( t, e) brackets[t] = url with open('threaded_smash_gg_brackets.txt', 'a') as f: f.write('PAGE{}[[{}]]\n'.format(page, url)) except Exception as e: continue if pages: for page in pages: iterate() else: while results < 7730: iterate() results = results + per_page page = page + 1 return brackets