diff --git a/.gitignore b/.gitignore index c74671a..dd660bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ -venv -lokrez/res/ssbu *.bkp *.test +venv +res +build +dist +*.egg-info + # final products *.png *.svg diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2affd2b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Lertsenem + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.adoc b/README.adoc index 7929e08..797e851 100644 --- a/README.adoc +++ b/README.adoc @@ -20,14 +20,20 @@ Requirements ------------ === Modules -- *jinja2* is the only mandatory external module +- *appdirs* is needed to find the right emplacements for config, cache and data + files according to the OS ; +- *jinja2* is needed for templating ; +- *requests* is needed for HTTP(s) requests ; - *cairosvg* can be used for some rasterized exports (see corresponding section) === Templates -The *rebootlyon* template needs the *Impact* font (available by default on +The *rebootlyonXXX* templates needs the *Impact* font (available by default on Windows, install +ttf-mscorefonts-installer+ on Ubuntu or Debian). +The *rebootlyon2020* template also need the *Gobold Regular* font, available at +https://www.dafont.com/gobold.font (free for personnal use). + === Exports The default and preferred output format is *SVG*. @@ -36,23 +42,29 @@ extension in the filename supplied to +--outfile+. Those exports are based on the *SVG* output. To export in *PNG*, lokrez will first try to use *Inkscape* command line. If -that fails (inkscape is not install, or lokrez can't find it in your PATH), it -will try to use the *cairosvg* module (which can create artefacts for some SVG -objects). +that fails (inkscape is not installed, or lokrez can't find it in your PATH), +it will try to use the *cairosvg* module (which can create artefacts for some +SVG objects). To export in *PDF* or *PS*, lokrez will try to use the *cairosvg* module. === Images The SSBU characters images are not included (since this is both copyrighted -work and a lot of heavy bitmaps), you'll have to get them by your own means and -put them in a +res/ssbu/chars+ directory. They should be named like so : +work and a lot of heavy bitmaps). The +init+ command is designed to download +them for you and rename them according to lokrez expectations. Use it with ++lokrez init ssbu+. Then you can go make yourself a cup of coffee or two, +because that's about 3G you're going to download. + +By default, the images are + +For reference, the images names look like : ----- {charactername}/chara_{formatnumber}_{charactername}_{skinnumber}.png ----- where: -- +charactername+ is the character name (see appendix for valid names) +- +charactername+ is the character name (see <<_SSBU_charaappendix for valid names) - +formatnumber+ indicates what kind of image it is * +0+ is a 128x128 head crop * +1+ is a 512x512 bust crop @@ -68,7 +80,7 @@ Annexes ------- === SSBU Characters names -These are the string uised to name SSBU characters. +These are the string used to name SSBU characters. - +banjo & kazooie+ - +bayonetta+ diff --git a/lokrez/__init__.py b/lokrez/__init__.py index a9555d5..9b67506 100644 --- a/lokrez/__init__.py +++ b/lokrez/__init__.py @@ -2,44 +2,49 @@ import argparse import configparser import datetime import html +import json import logging -import os, os.path +import pathlib import sys -import export -import resources -import smashgg -import version +import appdirs +from . import export +from . import resources +from . import smashgg +from . import version + +# ============================================================================= +__version__ = version.__version__ +__license__ = version.__license__ + +ROOTDIR = pathlib.Path(__file__).absolute().parent + +APPDIRS = appdirs.AppDirs(version.NAME, version.ENTITY) # ============================================================================= def main(): # ------------------------------------------------------------------------- - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser( + formatter_class = argparse.ArgumentDefaultsHelpFormatter, + ) subparsers = parser.add_subparsers( dest = "command", help = "commands", ) - parser.add_argument( "--proxy", "-p", - default = None, - help = "the proxy to use" ) - - parser.add_argument( "--token", "-t", - default = None, - help = "the authentication token to use" ) - parser.add_argument( - "--rootdir", "-RD", + "--proxy", "-p", default = None, - help = "The directories containing this script, defaults to '.'", + help = "the proxy to use", ) # ------------------------------------------------------------------------- init_parser = subparsers.add_parser( "init", + formatter_class = argparse.ArgumentDefaultsHelpFormatter, ) init_parser.add_argument( @@ -50,13 +55,15 @@ def main(): init_parser.add_argument( "--imgdir", "-ID", - default = "res/ssbu", + type = pathlib.Path, + default = pathlib.Path(APPDIRS.user_data_dir) / "res", help = "The directory we should download the resources to", ) # ------------------------------------------------------------------------- top8_parser = subparsers.add_parser( "top8", + formatter_class = argparse.ArgumentDefaultsHelpFormatter, ) top8_parser.add_argument( @@ -64,35 +71,52 @@ def main(): default = None, help = "The tournament slug or id", ) + + top8_parser.add_argument( + "--token", "-t", + default = None, + help = "the authentication token to use", + ) + top8_parser.add_argument( "--imgdir", "-ID", - default = "res/ssbu", - help = "The directories containing images", + type = pathlib.Path, + default = pathlib.Path(APPDIRS.user_data_dir) / "res", + help = "The directories containing images, be careful whether " \ + "you specify an absolute path or a relative one.", + ) + top8_parser.add_argument( + "--playerskinsdb", "-PD", + type = pathlib.Path, + default = ROOTDIR / "data" / "playerskinsdb.json", + help = "A JSON file matching player tags, characters and " \ + "preferred skins", ) top8_parser.add_argument( "--templatesdir", "-TD", - default = "templates", + type = pathlib.Path, + default = ROOTDIR / "templates", help = "The local result templates directory", ) top8_parser.add_argument( "--template", "-T", - default = "rebootlyon", + default = "rebootlyon2020", help = "The local result template to use", ) top8_parser.add_argument( "--lkrz-file", "-f", + type = pathlib.Path, default = None, help = "The lkrz file in which the results are stored ; if it " \ "does not exist, one will be created from the smashgg data", ) - top8_parser.add_argument( "--outfile", "-o", + type = pathlib.Path, default = None, - help = "The SVG local result file to output to ; defaults to " \ - "./tournament-slug.svg", + help = "The SVG or PNG local result file to output to ; if it's " \ + "not specified, it will use the tournament slug as name", ) - top8_parser.add_argument( "--name-seo-delimiter", default = None, @@ -144,12 +168,6 @@ def main(): print(version.VERSION_NAME) return 0 - # Set default arguments - # ------------------------------------------------------------------------- - # Default rootdir is "." - if args.rootdir is None: - args.rootdir = "." # TODO compute script root? - # ------------------------------------------------------------------------- if args.command not in [ "init", "top8" ]: parser.print_help() @@ -157,20 +175,29 @@ def main(): # ------------------------------------------------------------------------- if args.command == "init": + args.imgdir.mkdir(parents=True, exist_ok=True) resources.download_res_ssbu( dstdir = args.imgdir, + proxy = args.proxy, log = log, ) return 0 # ------------------------------------------------------------------------- if args.command == "top8": + # Initialize PLAYERSKINS db + log.debug("loading playerskins db from '{}'" \ + .format(args.playerskinsdb)) + with args.playerskinsdb.open("r") as f: + smashgg.PLAYERSKINS = json.load(f) + + # tournament = None top_players = {} - try: + if args.lkrz_file is not None: lkrz = configparser.ConfigParser() - lkrz.read(args.lkrz_file) + lkrz.read(str(args.lkrz_file)) log.info("Loading data from '{}'".format(args.lkrz_file)) @@ -210,9 +237,7 @@ def main(): top_players[player.gamerTag] = player - except Exception as e: - - log.warning(e) + else: # Get infos from smash.gg and write the config file tournament, top_players = getTournamentTop( @@ -236,27 +261,32 @@ def main(): ) if args.lkrz_file is None: - args.lkrz_file = "{}.lkrz".format(tournament.slug) + args.lkrz_file = pathlib.Path( + "{}.lkrz".format(tournament.slug) + ) - with open(args.lkrz_file, "w", encoding="utf8") as f: + with args.lkrz_file.open("w", encoding="utf8") as f: f.write(lkrz_data) # Default outfile is 'tournament-slug.svg' if args.outfile is None: - args.outfile = "{}.svg".format(tournament.slug) + args.outfile = pathlib.Path( + "{}.svg".format(tournament.slug), + ) # Build the context which will be passed to the template + try: + dir_res_ssbu = args.imgdir.as_uri() # not absolute => error + except ValueError: + dir_res_ssbu = args.imgdir.as_posix() + context = { "tournament": tournament.clean_name(args.name_seo_delimiter), "players" : sorted( top_players.values(), key = lambda p: p.placement, ), - "dir_root": args.rootdir, - "dir_res_ssbu": os.path.join( - args.imgdir, - "chars", - ), + "dir_res_ssbu": dir_res_ssbu, } rv = export.generate_outfile( @@ -264,7 +294,8 @@ def main(): args.template, context, args.outfile, - log, + log = log, + cachedir = pathlib.Path(APPDIRS.user_cache_dir), ) if rv is None: @@ -329,6 +360,7 @@ def getTournamentTop( "id" : int(id_or_slug), # If this fails, it's a slug "top": top, }, + query_dir = ROOTDIR / "queries", token = token, proxy = proxy, log = log, @@ -341,6 +373,7 @@ def getTournamentTop( "slug" : id_or_slug, "top": top, }, + query_dir = ROOTDIR / "queries", token = token, proxy = proxy, log = log, @@ -425,6 +458,7 @@ def getTournamentTop( "tournamentId" : int(tournament.id), "entrantIds": [ id for id in top_players.keys() ], }, + query_dir = ROOTDIR / "queries", token = token, proxy = proxy, log = log, @@ -478,3 +512,4 @@ def getTournamentTop( if __name__ == '__main__': rv = main() sys.exit(rv) + diff --git a/lokrez/__main__.py b/lokrez/__main__.py new file mode 100644 index 0000000..d54c4ef --- /dev/null +++ b/lokrez/__main__.py @@ -0,0 +1,14 @@ +import sys + +# Add module parent directory to path if needed +if __package__ is None and not hasattr(sys, "frozen"): + import pathlib + + path = pathlib.Path(__file__).absolute() + sys.path.insert(0, str(path.parent.parent)) + + +import lokrez + +if __name__ == '__main__': + lokrez.main() diff --git a/lokrez/characters_ssbu.py b/lokrez/characters_ssbu.py index 514b8b0..a9d6e8e 100644 --- a/lokrez/characters_ssbu.py +++ b/lokrez/characters_ssbu.py @@ -49,7 +49,7 @@ EVERYONE = [ ], ), SSBUCharacter( - smashggid = 1409, + smashggid = 1539, name = "byleth", codename = "master", spritersurls = [ @@ -609,7 +609,7 @@ EVERYONE = [ ], ), SSBUCharacter( - smashggid = None, + smashggid = 1341, name = "zero suit samus", codename = "szerosuit", spritersurls = [ diff --git a/lokrez/data/playerskinsdb.json b/lokrez/data/playerskinsdb.json new file mode 100644 index 0000000..f5ff9d4 --- /dev/null +++ b/lokrez/data/playerskinsdb.json @@ -0,0 +1,245 @@ +{ + "ad": { + "meta knight": "07" + }, + "altek": { + "kirby": "06", + "pikachu": "06", + "zelda": "03" + }, + "alvis": { + "roy": "06", + "yoshi": "05" + }, + "arima": { + "inkling": "00", + "king k rool": "00", + "little mac": "00", + "lucario": "00", + "pikachu": "00" + }, + "bac": { + "wolf": "06", + "yoshi": "05" + }, + "bastos": { + "wario": "06" + }, + "benj": { + "dark samus": "07" + }, + "bento": { + "pokemon trainer": "07" + }, + "bibliburst": { + "falco": "01", + "yoshi": "06" + }, + "bifasse": { + "yoshi": "07" + }, + "captain": { + "sonic": "04", + "terry": "00" + }, + "captain falcum": { + "joker": "06", + "wolf": "06" + }, + "davianel": { + "luigi": "00", + "olimar": "02", + "sheik": "04" + }, + "debatab": { + "zelda": "01" + }, + "dixar": { + "lucina": "03", + "sheik": "07", + "terry": "00" + }, + "dr. crow": { + "lucina": "03", + "sheik": "05" + }, + "draver ": { + "joker": "02", + "young link": "02" + }, + "dyl": { + "bowser": "00", + "captain falcon": "07", + "sonic": "03", + "wolf": "03" + }, + "estus": { + "mario": "05" + }, + "flynn": { + "ike": "03", + "min min": "01" + }, + "francis": { + "mega man": "02", + "terry": "" + }, + "gd": { + "bowser": "01", + "cloud": "03", + "pac man": "06", + "wolf": "06", + "zss": "01" + }, + "jg": { + "ike": "06" + }, + "jylomaki": { + "mega man": "00" + }, + "l'obez": { + "bowser": "06" + }, + "lertsenem": { + "link": "01", + "incineroar": "00" + }, + "lil marty": { + "pichu": "07" + }, + "linkab / bdl": { + "bayonetta": "00", + "inkling": "07" + }, + "lukrra": { + "robin": "03" + }, + "magic'": { + "mr game & watch": "00" + }, + "mocra": { + "mario": "" + }, + "mushroompunch": { + "samus": "00" + }, + "naskino": { + "marth": "03", + "palutena": "06", + "zelda": "05" + }, + "nekim": { + "joker": "00" + }, + "nemesis": { + "jigglypuff": "03", + "min min": "04", + "pichu": "02" + }, + "nonocolors": { + "pokemon trainer": "03", + "wario": "02", + "wolf": "00" + }, + "oxydion": { + "ganondorf": "00", + "mr game & watch": "02" + }, + "pandaroux": { + "ice climbers": "07", + "inkling": "00" + }, + "pandaroux ": { + "ness": "02" + }, + "personne": { + "inkling": "05" + }, + "pew": { + "ness": "01" + }, + "phoenix": { + "snake": "05" + }, + "phyel": { + "mr game & watch": "06" + }, + "pom ": { + "chrom": "07", + "lucina": "06", + "samus": "06", + "toon link": "04" + }, + "pyoro": { + "isabelle": "07", + "terry": "00", + "zelda": "07" + }, + "raivals": { + "min min": "00", + "peach": "01" + }, + "rob one": { + "peach": "00" + }, + "rohan_doge": { + "meta knight": "00" + }, + "sfar": { + "joker": "00", + "wolf": "00" + }, + "shiko": { + "pac man": "07" + }, + "shishi": { + "isabelle": "06", + "joker": "06" + }, + "snoua": { + "link": "00" + }, + "sourif": { + "bowser jr": "01", + "mr game & watch": "01", + "pokemon trainer": "05", + "ryu": "04", + "wii fit": "06" + }, + "teezy": { + "diddy kong": "00", + "pikachu": "03", + "pokemon trainer": "05", + "wario": "03" + }, + "tomipal": { + "pikachu": "02", + "pokemon trainer": "00" + }, + "tonios": { + "isabelle": "01", + "mario": "00" + }, + "tonios ": { + "bowser": "06" + }, + "underkowe": { + "joker": "03", + "zss": "05" + }, + "vlad": { + "rob": "00" + }, + "yannwatts": { + "ness": "05" + }, + "ykseew": { + "wii fit": "00" + }, + "yogui": { + "daisy": "07" + }, + "zequar": { + "mewtwo": "07" + } +} diff --git a/lokrez/export.py b/lokrez/export.py index 3741c22..9bc0fd7 100644 --- a/lokrez/export.py +++ b/lokrez/export.py @@ -1,5 +1,6 @@ import os import subprocess +import tempfile import jinja2 @@ -10,87 +11,95 @@ def generate_outfile( context, outfilename, log = None, + cachedir = None, ): # Template rendering # ------------------------------------------------------------------------- log.info("Generating SVG using '{}' template".format(templatename)) + log.debug( + "Initializing jinja2 with template dir '{}'" \ + .format(templatesdir) + ) jj2_env = jinja2.Environment( - loader = jinja2.FileSystemLoader( templatesdir ) + loader = jinja2.FileSystemLoader( + str(templatesdir), + ) ) try: jj2_tpl = jj2_env.get_template( - os.path.join( - templatename, - "template.svg.j2", - ) + # Jinja specific path format + "{}/template.svg.j2".format(templatename), ) - except: + except Exception as e: log.error("Could not find template '{}'".format(templatename)) + log.debug(e, exc_info=1) return None - extension = outfilename.split(".")[-1] - # To SVG # ------------------------------------------------------------------------- - if extension == "svg": - jj2_tpl.stream(context).dump( outfilename ) + if outfilename.suffix == ".svg": + jj2_tpl.stream(context).dump( str(outfilename) ) return outfilename # To PNG with inkscape # ------------------------------------------------------------------------- - if extension == "png": + if outfilename.suffix == ".png": - try: - log.info("Exporting to {} using inkscape".format(extension)) - import subprocess + cachedir.mkdir(parents=True, exist_ok=True) - jj2_tpl.stream(context).dump( "tmp.svg" ) - - inkscape_process = subprocess.Popen( - [ - "inkscape", - "tmp.svg", - "--export-filename", - outfilename, - ], - stdout = subprocess.PIPE, - stderr = subprocess.STDOUT, - universal_newlines = True, - ) - - for line_out in iter(inkscape_process.stdout.readline, ""): - log.debug(line_out) - - inkscape_process.stdout.close() - - rv = inkscape_process.wait() - - if rv != 0: - raise Exception( - "Bad inkscape return code '{}'" \ - .format(inkscape_process.returncode) - ) - - os.unlink("tmp.svg") - - return outfilename - - except Exception as e: - log.warning("Failed to export with inkscape") + with tempfile.NamedTemporaryFile( + suffix="svg", + dir = str(cachedir), + ) as tmpsvg: try: - os.unlink("tmp.svg") - except: - pass - log.debug(e) + log.info( + "Exporting to {} using inkscape" \ + .format(outfilename.suffix), + ) + import subprocess + + jj2_tpl.stream(context).dump( tmpsvg.name ) + + inkscape_process = subprocess.Popen( + [ + "inkscape", + tmpsvg.name, + "--export-filename", + str(outfilename), + ], + stdout = subprocess.PIPE, + stderr = subprocess.STDOUT, + universal_newlines = True, + ) + + for line_out in iter(inkscape_process.stdout.readline, ""): + log.debug(line_out) + + inkscape_process.stdout.close() + + rv = inkscape_process.wait() + + if rv != 0: + raise Exception( + "Bad inkscape return code '{}'" \ + .format(inkscape_process.returncode) + ) + + + return outfilename + + except Exception as e: + log.warning("Failed to export with inkscape") + log.debug(e, exc_info=True) # To png, pdf or ps with cairosvg # ------------------------------------------------------------------------- - if extension in [ "png", "pdf", "ps" ]: + if outfilename.suffix in [ ".png", ".pdf", ".ps" ]: - log.info("Exporting to {} using cairosvg".format(extension)) + log.info("Exporting to {} using cairosvg".format(outfilename.suffix)) try: import cairosvg @@ -105,16 +114,16 @@ def generate_outfile( svg_str = jj2_tpl.render(context) - if extension == "png": + if outfilename.suffix == ".png": conversion_fun = cairosvg.svg2png - elif extension == "pdf": + elif outfilename.suffix == ".pdf": conversion_fun = cairosvg.svg2pdf - elif extension == "ps": + elif outfilename.suffix == ".ps": conversion_fun = cairosvg.svg2ps conversion_fun( bytestring = svg_str, - write_to = outfilename, + write_to = str(outfilename), ) return outfilename @@ -125,7 +134,7 @@ def generate_outfile( "Can't export to '{}' : unsupported format '{}'" \ .format( outfilename, - extension, + outfilename.suffix, ) ) return None diff --git a/lokrez/resources.py b/lokrez/resources.py index 66e1068..12ca506 100644 --- a/lokrez/resources.py +++ b/lokrez/resources.py @@ -1,18 +1,19 @@ import io -import os +import pathlib import sys import zipfile import requests -import characters_ssbu +from .characters_ssbu import EVERYONE # ----------------------------------------------------------------------------- -def download_file(url, with_progressbar = True): +def download_file(url, with_progressbar = True, proxy = None): r = requests.get( url, stream = with_progressbar, + proxies = { "https": proxy, "http": proxy }, ) if not with_progressbar: @@ -44,7 +45,7 @@ def download_file(url, with_progressbar = True): return f # ----------------------------------------------------------------------------- -def download_res_ssbu(dstdir, log=None): +def download_res_ssbu(dstdir, proxy = None, log=None): """Downloads SSBU resources from spriters and rename them according to lokrez expectations""" @@ -52,37 +53,50 @@ def download_res_ssbu(dstdir, log=None): # ------------------------------------------------------------------------- # Download stock icons - log.info("Downloading stock icons...") - fstocks = download_file(stock_icons_url) + log.warning("Downloading stock icons...") + fstocks = download_file(stock_icons_url, proxy = proxy) zfstocks = zipfile.ZipFile(fstocks) # Iter over each character - for character in characters_ssbu.EVERYONE: - log.info("Downloading images for {}...".format(character.name)) + for character in EVERYONE: + log.warning("Downloading images for {}...".format(character.name)) # Create directory for this character - chardir = os.path.join( - dstdir, - character.name, - ) + chardir = dstdir / character.name + try: - os.mkdir( chardir ) + chardir.mkdir() except FileExistsError: - log.warning( + log.info( "Directory already exists for {}".format(character.name) ) - if os.listdir( chardir ): + try: + next(chardir.iterdir()) log.warning( "Directory not empty for {}, skipping" \ .format(character.name) ) continue + except StopIteration: + log.info( + "Directory empty, downloading", + ) # Download urls & write image files for url in character.spritersurls: - f = download_file(url) + try: + f = download_file(url, proxy = proxy) + except Exception as e: + try: + log.warning("Download failed ({}), retrying".format(e)) + f = download_file(url, proxy = proxy) + except Exception as e: + log.error("Download failed({})".format(e)) + log.debug(e, exc_info = True) + continue + with zipfile.ZipFile(f) as zfchar: for zf in [zfchar,zfstocks]: for source_filename in zf.namelist(): @@ -90,13 +104,15 @@ def download_res_ssbu(dstdir, log=None): if "No Gamma Fix" in source_filename: continue - if os.path.basename(source_filename) in ["","Tag.txt"]: - continue - if character.codename not in source_filename: continue - target_filename = os.path.basename(source_filename) + target_filename = pathlib.Path(source_filename).name + + if target_filename in ["","Tag.txt"]: + continue + + target_filename = pathlib.Path(source_filename).name target_filename = target_filename.replace( character.codename, @@ -105,12 +121,9 @@ def download_res_ssbu(dstdir, log=None): log.debug("Writing file '{}'".format(target_filename)) - target_filename = os.path.join( - chardir, - target_filename, - ) + target_filename = chardir / target_filename - with open(target_filename, "wb") as tf: + with open(str(target_filename), "wb") as tf: tf.write(zf.read(source_filename)) # ============================================================================= diff --git a/lokrez/smashgg.py b/lokrez/smashgg.py index e7d71f6..994ecf1 100644 --- a/lokrez/smashgg.py +++ b/lokrez/smashgg.py @@ -1,9 +1,10 @@ import json import os, os.path +import pathlib import requests -import characters_ssbu +from . import characters_ssbu # ============================================================================= API_HOST = "api.smash.gg" @@ -15,15 +16,16 @@ API_URL = "{scheme}://{host}/{endpoint}".format( endpoint = API_ENDPOINT, ) +CHARACTERS = { c.smashggid : c.name for c in characters_ssbu.EVERYONE } + +PLAYERSKINS = {} + # ============================================================================= # ----------------------------------------------------------------------------- class Player(): """A Player, as registered by the smash.gg API, and their characters choices and placement in a tournament""" - # TODO fill missing chars - CHARACTERS = { c.smashggid : c.name for c in characters_ssbu.EVERYONE } - # ------------------------------------------------------------------------- def __init__( self, @@ -49,11 +51,20 @@ class Player(): # ------------------------------------------------------------------------- def add_character_selection(self, character, win): - try: - character = (self.CHARACTERS[character], "00") - except KeyError: - if type(character) != tuple: - character = (character, "00") + + if type(character) != tuple: + try: + charname = CHARACTERS[character] + except KeyError: + charname = character # Unknown char -> sgg id + + try: + skin = PLAYERSKINS[self.gamerTag.lower()][charname] + except KeyError: + skin = "00" # default skin + + character = ( charname, skin ) + try: self.chars[character] += ( 1.01 if win else 1.00 ) @@ -165,23 +176,20 @@ def run_query( variables = {}, token = "", proxy = None, - query_dir = "queries", + query_dir = pathlib.Path("queries"), query_extension = "gql", api_url = API_URL, log = None, ): # Load query - query_path = os.path.join( - query_dir, - "{}.{}".format( - query_name, - query_extension, - ) + query_path = query_dir / "{}.{}".format( + query_name, + query_extension, ) query = "" - with open(query_path, 'r') as query_file: + with query_path.open("r") as query_file: query = query_file.read() # Build payload diff --git a/lokrez/templates/rebootlyon/logo.svg.j2 b/lokrez/templates/rebootlyon/logo.svg.j2 deleted file mode 120000 index 5ce3516..0000000 --- a/lokrez/templates/rebootlyon/logo.svg.j2 +++ /dev/null @@ -1 +0,0 @@ -logo_reboot_covid.svg.j2 \ No newline at end of file diff --git a/lokrez/templates/rebootlyon/template.svg.j2 b/lokrez/templates/rebootlyon/template.svg.j2 deleted file mode 100644 index d6bf7a3..0000000 --- a/lokrez/templates/rebootlyon/template.svg.j2 +++ /dev/null @@ -1,1810 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - {{tournament.name|e}} - - - - - - - - - - {% if players[0].get_mains()[1] %} - - {% endif %} - {% if players[0].get_mains()[2] %} - - {% endif %} - - {{players[0].gamerTag|e|e}} - {{players[0].prefix|e}} - - 1. - 1. - - - - - - - - - - {% if players[1].get_mains()[2] %} - - {% endif %} - {% if players[1].get_mains()[1] %} - - {% endif %} - - {{players[1].gamerTag|e}} - {{players[1].prefix|e}} - - 2. - 2. - - - - - - - - - - {% if players[2].get_mains()[1] %} - - {% endif %} - {% if players[2].get_mains()[2] %} - - {% endif %} - - {{players[2].gamerTag|e}} - {{players[2].prefix|e}} - - 3. - 3. - - - - - - - - - - {% if players[3].get_mains()[2] %} - - {% endif %} - {% if players[3].get_mains()[1] %} - - {% endif %} - - {{players[3].gamerTag|e}} - {{players[3].prefix|e}} - - 4. - 4. - - - - - - - - - - {% if players[4].get_mains()[2] %} - - {% endif %} - {% if players[4].get_mains()[1] %} - - {% endif %} - - {{players[4].gamerTag|e}} - {{players[4].prefix|e}} - - 5. - 5. - - - - - - - - - - {% if players[5].get_mains()[2] %} - - {% endif %} - {% if players[5].get_mains()[1] %} - - {% endif %} - - {{players[5].gamerTag|e}} - {{players[5].prefix|e}} - - 5. - 5. - - - - - - - - - - {% if players[6].get_mains()[2] %} - - {% endif %} - {% if players[6].get_mains()[1] %} - - {% endif %} - - {{players[6].gamerTag|e}} - {{players[6].prerfix}} - - 7. - 7. - - - - - - - - - - {% if players[7].get_mains()[2] %} - - {% endif %} - {% if players[7].get_mains()[1] %} - - {% endif %} - - {{players[7].gamerTag|e}} - {{players[7].prefix|e}} - - 7. - 7. - - - - - Entrants - {{tournament.numEntrants}} - Bar Reboot lyon - {{tournament.startAt.strftime('%d/%m/%Y')}} - rebootlyon - - - - - - - - - - - - - - - DESIGN BY POM - SMASH AT LYON - - - @smashatlyon - @PomSSB & @DiXaRTV - - @lertsenem@mastodon.lertsenem.com - - - - diff --git a/lokrez/templates/rebootlyon2/logo.svg.j2 b/lokrez/templates/rebootlyon2/logo.svg.j2 deleted file mode 120000 index 5ce3516..0000000 --- a/lokrez/templates/rebootlyon2/logo.svg.j2 +++ /dev/null @@ -1 +0,0 @@ -logo_reboot_covid.svg.j2 \ No newline at end of file diff --git a/lokrez/templates/rebootlyon2/logo_reboot_covid.svg.j2 b/lokrez/templates/rebootlyon2/logo_reboot_covid.svg.j2 deleted file mode 100644 index 0605cba..0000000 --- a/lokrez/templates/rebootlyon2/logo_reboot_covid.svg.j2 +++ /dev/null @@ -1,748 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lokrez/templates/rebootlyon/logo_reboot.svg.j2 b/lokrez/templates/rebootlyon2019/logo.svg.j2 similarity index 100% rename from lokrez/templates/rebootlyon/logo_reboot.svg.j2 rename to lokrez/templates/rebootlyon2019/logo.svg.j2 diff --git a/lokrez/templates/rebootlyon2/logo_reboot.svg.j2 b/lokrez/templates/rebootlyon2019/logo_reboot.svg.j2 similarity index 100% rename from lokrez/templates/rebootlyon2/logo_reboot.svg.j2 rename to lokrez/templates/rebootlyon2019/logo_reboot.svg.j2 diff --git a/lokrez/templates/rebootlyon/logo_reboot_covid.svg.j2 b/lokrez/templates/rebootlyon2019/logo_reboot_covid.svg.j2 similarity index 100% rename from lokrez/templates/rebootlyon/logo_reboot_covid.svg.j2 rename to lokrez/templates/rebootlyon2019/logo_reboot_covid.svg.j2 diff --git a/lokrez/templates/rebootlyon2/template.svg.j2 b/lokrez/templates/rebootlyon2019/template.svg.j2 similarity index 98% rename from lokrez/templates/rebootlyon2/template.svg.j2 rename to lokrez/templates/rebootlyon2019/template.svg.j2 index 21c841f..ab4488b 100644 --- a/lokrez/templates/rebootlyon2/template.svg.j2 +++ b/lokrez/templates/rebootlyon2019/template.svg.j2 @@ -40,6 +40,30 @@ is_visible="true" id="path-effect5529" effect="envelope" /> + + + + + + + @@ -460,7 +484,7 @@ + id="player1_msk"> + id="player2_msk"> @@ -496,64 +520,73 @@ + id="player3_msk"> + id="player4_msk"> + id="player5a_msk"> + id="player5b_msk"> + id="player7a_msk"> + id="player7b_msk"> + - {% include 'rebootlyon2/logo.svg.j2' %} + {% include 'rebootlyon2019/logo.svg.j2' %} diff --git a/lokrez/templates/rebootlyon2020/logo.svg.j2 b/lokrez/templates/rebootlyon2020/logo.svg.j2 deleted file mode 120000 index 5ce3516..0000000 --- a/lokrez/templates/rebootlyon2020/logo.svg.j2 +++ /dev/null @@ -1 +0,0 @@ -logo_reboot_covid.svg.j2 \ No newline at end of file diff --git a/lokrez/templates/rebootlyon2020/logo.svg.j2 b/lokrez/templates/rebootlyon2020/logo.svg.j2 new file mode 100644 index 0000000..0605cba --- /dev/null +++ b/lokrez/templates/rebootlyon2020/logo.svg.j2 @@ -0,0 +1,748 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lokrez/templates/rebootlyon2020/template.svg.j2 b/lokrez/templates/rebootlyon2020/template.svg.j2 index bc3c314..a6700f7 100644 --- a/lokrez/templates/rebootlyon2020/template.svg.j2 +++ b/lokrez/templates/rebootlyon2020/template.svg.j2 @@ -904,7 +904,7 @@ {% if players[0].get_mains()[1] %} {% endif %} {% if players[1].get_mains()[2] %} {% endif %} {% if players[2].get_mains()[1] %} {% endif %} {% if players[3].get_mains()[2] %} {% endif %} {% if players[4].get_mains()[2] %} {% endif %} {% if players[5].get_mains()[2] %} {% endif %} {% if players[6].get_mains()[2] %} {% endif %} {% if players[7].get_mains()[2] %} {% endif %} - {% include 'rebootlyon2/logo.svg.j2' %} + {% include 'rebootlyon2020/logo.svg.j2' %}