First kinda working version
We can download the infos from smash.gg, but the SVG generation fails for now.master
parent
874188a20d
commit
dccde354bd
|
@ -1,9 +1,14 @@
|
||||||
from .version import VERSION_NAME
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
import os, os.path
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import jinja2
|
||||||
|
|
||||||
|
import smashgg
|
||||||
|
import version
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
def main():
|
def main():
|
||||||
|
@ -22,7 +27,7 @@ def main():
|
||||||
|
|
||||||
parser.add_argument( "--token", "-t",
|
parser.add_argument( "--token", "-t",
|
||||||
default = None,
|
default = None,
|
||||||
help = "the auhentication token to use" )
|
help = "the authentication token to use" )
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
top8_parser = subparsers.add_parser(
|
top8_parser = subparsers.add_parser(
|
||||||
|
@ -34,10 +39,19 @@ def main():
|
||||||
default = None,
|
default = None,
|
||||||
help = "The tournament slug or id",
|
help = "The tournament slug or id",
|
||||||
)
|
)
|
||||||
|
top8_parser.add_argument(
|
||||||
|
"--resourcesdir", "-RD",
|
||||||
|
default = "res",
|
||||||
|
help = "The directories containing images and templates resources",
|
||||||
|
)
|
||||||
|
top8_parser.add_argument(
|
||||||
|
"--templatesdir", "-TD",
|
||||||
|
default = "templates",
|
||||||
|
help = "The local result templates directory",
|
||||||
|
)
|
||||||
top8_parser.add_argument(
|
top8_parser.add_argument(
|
||||||
"--template", "-T",
|
"--template", "-T",
|
||||||
default = "default",
|
default = "rebootlyon",
|
||||||
help = "The local result template to use",
|
help = "The local result template to use",
|
||||||
)
|
)
|
||||||
top8_parser.add_argument(
|
top8_parser.add_argument(
|
||||||
|
@ -47,6 +61,13 @@ def main():
|
||||||
"does not exist, one will be created from the smashgg data",
|
"does not exist, one will be created from the smashgg data",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
top8_parser.add_argument(
|
||||||
|
"--outfile", "-o",
|
||||||
|
default = None,
|
||||||
|
help = "The SVG local result file to output to ; defaults to " \
|
||||||
|
"./tournament-slug.svg",
|
||||||
|
)
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
parser.add_argument( "--verbose", "-v",
|
parser.add_argument( "--verbose", "-v",
|
||||||
default = 0,
|
default = 0,
|
||||||
|
@ -63,7 +84,7 @@ def main():
|
||||||
|
|
||||||
# Set log level
|
# Set log level
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
log = logging.getLogger(NAME)
|
log = logging.getLogger(version.NAME)
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
log_handler_console = logging.StreamHandler()
|
log_handler_console = logging.StreamHandler()
|
||||||
|
@ -85,9 +106,285 @@ def main():
|
||||||
# Print version if required
|
# Print version if required
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
if args.version:
|
if args.version:
|
||||||
print(VERSION_NAME)
|
print(version.VERSION_NAME)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
if args.command not in [ "top8" ]:
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
if args.command == "top8":
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(args.lkrz_file, "r") as f:
|
||||||
|
# TODO parse config file to fill tournament & top_players
|
||||||
|
log.error("config file loading is not implemened yet")
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
except:
|
||||||
|
# Get infos from smash.gg and write the config file
|
||||||
|
tournament, top_players = getTournamentTop(
|
||||||
|
id_or_slug = args.tournament,
|
||||||
|
top = 8,
|
||||||
|
token = args.token,
|
||||||
|
proxy = args.proxy,
|
||||||
|
log = log,
|
||||||
|
)
|
||||||
|
|
||||||
|
if tournament is None or top_players is None:
|
||||||
|
log.error("Could not load data from smash.gg")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
lkrz_data = "\n".join(
|
||||||
|
[ tournament.conf() ] \
|
||||||
|
+ list(map(
|
||||||
|
lambda p:p.conf(),
|
||||||
|
top_players.values(),
|
||||||
|
))
|
||||||
|
)
|
||||||
|
|
||||||
|
if args.lkrz_file is None:
|
||||||
|
args.lkrz_file = "{}.lkrz".format(tournament.slug)
|
||||||
|
|
||||||
|
with open(args.lkrz_file, "w", encoding="utf8") as f:
|
||||||
|
f.write(lkrz_data)
|
||||||
|
|
||||||
|
# Template rendering
|
||||||
|
log.info("Génération du SVG en utilisant le template")
|
||||||
|
|
||||||
|
jj2_env = jinja2.Environment(
|
||||||
|
loader = jinja2.FileSystemLoader(
|
||||||
|
os.path.join(
|
||||||
|
args.resourcesdir,
|
||||||
|
args.templatesdir,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
jj2_tpl = jj2_env.get_template(
|
||||||
|
os.path.join(
|
||||||
|
args.template,
|
||||||
|
"template.svg.j2",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"tournament": tournament,
|
||||||
|
"players" : sorted(
|
||||||
|
top_players.values(),
|
||||||
|
key = lambda p: p.placement,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if args.oufile is None:
|
||||||
|
args.outfile = "{}.svg".format(tournament.slug)
|
||||||
|
|
||||||
|
jj2_tpl.stream(context).dump( args.outfile )
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
def getTournamentTop(
|
||||||
|
id_or_slug,
|
||||||
|
top=8,
|
||||||
|
token = "",
|
||||||
|
proxy = None,
|
||||||
|
log=None):
|
||||||
|
"""Returns a tuple : the smashgg.Tournament object and a list of the top
|
||||||
|
smashgg.Player in that tournament."""
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Select the right event (the one with the most entrants or the most sets)
|
||||||
|
def selectBiggestEvent(data, log=None):
|
||||||
|
|
||||||
|
try:
|
||||||
|
event = data["events"][0]
|
||||||
|
except:
|
||||||
|
log.error("No event found in data")
|
||||||
|
log.debug(data)
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
numEntrants = event["numEntrants"]
|
||||||
|
except KeyError:
|
||||||
|
numEntrants = event["standings"]["pageInfo"]["total"]
|
||||||
|
|
||||||
|
for e in data["events"]:
|
||||||
|
try:
|
||||||
|
ne = e["numEntrants"]
|
||||||
|
except KeyError:
|
||||||
|
ne = e["standings"]["pageInfo"]["total"]
|
||||||
|
|
||||||
|
if ne > numEntrants:
|
||||||
|
event = e
|
||||||
|
numEntrants = ne
|
||||||
|
|
||||||
|
log.info("Selected Event '{}' with {} entrants" \
|
||||||
|
.format(
|
||||||
|
event["name"],
|
||||||
|
numEntrants,
|
||||||
|
))
|
||||||
|
|
||||||
|
return event
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
data = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = smashgg.run_query(
|
||||||
|
query_name = "getTournamentTopById",
|
||||||
|
variables = {
|
||||||
|
"id" : int(id_or_slug), # If this fails, it's a slug
|
||||||
|
"top": top,
|
||||||
|
},
|
||||||
|
token = token,
|
||||||
|
proxy = proxy,
|
||||||
|
log = log,
|
||||||
|
)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
data = smashgg.run_query(
|
||||||
|
query_name = "getTournamentTopBySlug",
|
||||||
|
variables = {
|
||||||
|
"slug" : id_or_slug,
|
||||||
|
"top": top,
|
||||||
|
},
|
||||||
|
token = token,
|
||||||
|
proxy = proxy,
|
||||||
|
log = log,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tournament_data = data["tournament"]
|
||||||
|
except:
|
||||||
|
log.error("Failed to load Tournaments")
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
if tournament_data is None:
|
||||||
|
log.error("Failed to load Tournament")
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
event = selectBiggestEvent(tournament_data, log)
|
||||||
|
|
||||||
|
if event is None :
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
# Get the tournament
|
||||||
|
tournament = smashgg.Tournament(
|
||||||
|
id = tournament_data["id"],
|
||||||
|
slug = tournament_data["slug"],
|
||||||
|
name = tournament_data["name"],
|
||||||
|
startAt = \
|
||||||
|
datetime.datetime. \
|
||||||
|
fromtimestamp(tournament_data["startAt"]),
|
||||||
|
numEntrants = event["standings"]["pageInfo"]["total"],
|
||||||
|
venueAddress = tournament_data["venueAddress"],
|
||||||
|
venueName = tournament_data["venueName"],
|
||||||
|
city = tournament_data["city"],
|
||||||
|
countryCode = tournament_data["countryCode"],
|
||||||
|
hashtag = tournament_data["hashtag"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Get the top players
|
||||||
|
top_players = {}
|
||||||
|
|
||||||
|
standings = event["standings"]["nodes"]
|
||||||
|
|
||||||
|
for standing in standings :
|
||||||
|
|
||||||
|
seeding = None
|
||||||
|
for seed in standing["entrant"]["seeds"]:
|
||||||
|
# Take the seeding from the phase with *all* Event entrants
|
||||||
|
if seed["phase"]["numSeeds"] == tournament.numEntrants:
|
||||||
|
seeding = seed["groupSeedNum"]
|
||||||
|
|
||||||
|
participant_data = standing["entrant"]["participants"][0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
twitterHandle = participant_data \
|
||||||
|
["player"] \
|
||||||
|
["user"] \
|
||||||
|
["authorizations"] \
|
||||||
|
[0] \
|
||||||
|
["externalUsername"]
|
||||||
|
except TypeError:
|
||||||
|
twitterHandle = None
|
||||||
|
|
||||||
|
|
||||||
|
player = smashgg.Player(
|
||||||
|
id = standing["entrant"]["id"],
|
||||||
|
prefix = participant_data["prefix"],
|
||||||
|
gamerTag = participant_data["gamerTag"],
|
||||||
|
placement = standing["placement"],
|
||||||
|
seeding = seeding,
|
||||||
|
twitterHandle = twitterHandle,
|
||||||
|
)
|
||||||
|
|
||||||
|
top_players[player.id] = player
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Now, we need to find which characters those top players chose
|
||||||
|
data = None
|
||||||
|
|
||||||
|
data = smashgg.run_query(
|
||||||
|
query_name = "getCharsByTournamentIdAndEntrantIds",
|
||||||
|
variables = {
|
||||||
|
"tournamentId" : int(tournament.id),
|
||||||
|
"entrantIds": [ id for id in top_players.keys() ],
|
||||||
|
},
|
||||||
|
token = token,
|
||||||
|
proxy = proxy,
|
||||||
|
log = log,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tournament_data = data["tournament"]
|
||||||
|
except:
|
||||||
|
log.error("Failed to load Tournament")
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
if tournament_data is None:
|
||||||
|
log.error("Failed to load Tournament")
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
event = selectBiggestEvent(tournament_data, log)
|
||||||
|
|
||||||
|
if event is None :
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
# TODO check that sets number is < to hardcoded 100 max value (cf query)
|
||||||
|
sets = event["sets"]["nodes"]
|
||||||
|
|
||||||
|
for s in sets:
|
||||||
|
try:
|
||||||
|
for g in s["games"]:
|
||||||
|
|
||||||
|
winnerId = g["winnerId"]
|
||||||
|
|
||||||
|
for slct in g["selections"]:
|
||||||
|
|
||||||
|
if slct["selectionType"] == "CHARACTER":
|
||||||
|
eid = slct["entrant"]["id"]
|
||||||
|
try:
|
||||||
|
top_players[eid].add_character_selection(
|
||||||
|
character = slct["selectionValue"],
|
||||||
|
win = (winnerId == eid),
|
||||||
|
)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
except TypeError:
|
||||||
|
# If some games or selections are null, this can happen
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Return the data
|
||||||
|
return tournament, top_players
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue