Merge master && bump version

master
Lertsenem 2020-07-23 10:08:41 +02:00
commit e1eab031ae
23 changed files with 1547 additions and 2769 deletions

8
.gitignore vendored
View File

@ -1,8 +1,12 @@
venv
lokrez/res/ssbu
*.bkp *.bkp
*.test *.test
venv
res
build
dist
*.egg-info
# final products # final products
*.png *.png
*.svg *.svg

21
LICENSE Normal file
View File

@ -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.

View File

@ -20,14 +20,20 @@ Requirements
------------ ------------
=== Modules === 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 - *cairosvg* can be used for some rasterized exports (see corresponding
section) section)
=== Templates === 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). 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 === Exports
The default and preferred output format is *SVG*. 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. the *SVG* output.
To export in *PNG*, lokrez will first try to use *Inkscape* command line. If 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 that fails (inkscape is not installed, or lokrez can't find it in your PATH),
will try to use the *cairosvg* module (which can create artefacts for some SVG it will try to use the *cairosvg* module (which can create artefacts for some
objects). SVG objects).
To export in *PDF* or *PS*, lokrez will try to use the *cairosvg* module. To export in *PDF* or *PS*, lokrez will try to use the *cairosvg* module.
=== Images === Images
The SSBU characters images are not included (since this is both copyrighted 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 work and a lot of heavy bitmaps). The +init+ command is designed to download
put them in a +res/ssbu/chars+ directory. They should be named like so : 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 {charactername}/chara_{formatnumber}_{charactername}_{skinnumber}.png
----- -----
where: 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 - +formatnumber+ indicates what kind of image it is
* +0+ is a 128x128 head crop * +0+ is a 128x128 head crop
* +1+ is a 512x512 bust crop * +1+ is a 512x512 bust crop
@ -68,7 +80,7 @@ Annexes
------- -------
=== SSBU Characters names === SSBU Characters names
These are the string uised to name SSBU characters. These are the string used to name SSBU characters.
- +banjo & kazooie+ - +banjo & kazooie+
- +bayonetta+ - +bayonetta+

View File

@ -2,44 +2,49 @@ import argparse
import configparser import configparser
import datetime import datetime
import html import html
import json
import logging import logging
import os, os.path import pathlib
import sys import sys
import export import appdirs
import resources
import smashgg
import version
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(): def main():
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser(
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
)
subparsers = parser.add_subparsers( subparsers = parser.add_subparsers(
dest = "command", dest = "command",
help = "commands", 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( parser.add_argument(
"--rootdir", "-RD", "--proxy", "-p",
default = None, default = None,
help = "The directories containing this script, defaults to '.'", help = "the proxy to use",
) )
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
init_parser = subparsers.add_parser( init_parser = subparsers.add_parser(
"init", "init",
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
) )
init_parser.add_argument( init_parser.add_argument(
@ -50,13 +55,15 @@ def main():
init_parser.add_argument( init_parser.add_argument(
"--imgdir", "-ID", "--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", help = "The directory we should download the resources to",
) )
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
top8_parser = subparsers.add_parser( top8_parser = subparsers.add_parser(
"top8", "top8",
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
) )
top8_parser.add_argument( top8_parser.add_argument(
@ -64,35 +71,52 @@ def main():
default = None, default = None,
help = "The tournament slug or id", help = "The tournament slug or id",
) )
top8_parser.add_argument(
"--token", "-t",
default = None,
help = "the authentication token to use",
)
top8_parser.add_argument( top8_parser.add_argument(
"--imgdir", "-ID", "--imgdir", "-ID",
default = "res/ssbu", type = pathlib.Path,
help = "The directories containing images", 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( top8_parser.add_argument(
"--templatesdir", "-TD", "--templatesdir", "-TD",
default = "templates", type = pathlib.Path,
default = ROOTDIR / "templates",
help = "The local result templates directory", help = "The local result templates directory",
) )
top8_parser.add_argument( top8_parser.add_argument(
"--template", "-T", "--template", "-T",
default = "rebootlyon", default = "rebootlyon2020",
help = "The local result template to use", help = "The local result template to use",
) )
top8_parser.add_argument( top8_parser.add_argument(
"--lkrz-file", "-f", "--lkrz-file", "-f",
type = pathlib.Path,
default = None, default = None,
help = "The lkrz file in which the results are stored ; if it " \ help = "The lkrz file in which the results are stored ; if it " \
"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( top8_parser.add_argument(
"--outfile", "-o", "--outfile", "-o",
type = pathlib.Path,
default = None, default = None,
help = "The SVG local result file to output to ; defaults to " \ help = "The SVG or PNG local result file to output to ; if it's " \
"./tournament-slug.svg", "not specified, it will use the tournament slug as name",
) )
top8_parser.add_argument( top8_parser.add_argument(
"--name-seo-delimiter", "--name-seo-delimiter",
default = None, default = None,
@ -144,12 +168,6 @@ def main():
print(version.VERSION_NAME) print(version.VERSION_NAME)
return 0 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" ]: if args.command not in [ "init", "top8" ]:
parser.print_help() parser.print_help()
@ -157,20 +175,29 @@ def main():
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
if args.command == "init": if args.command == "init":
args.imgdir.mkdir(parents=True, exist_ok=True)
resources.download_res_ssbu( resources.download_res_ssbu(
dstdir = args.imgdir, dstdir = args.imgdir,
proxy = args.proxy,
log = log, log = log,
) )
return 0 return 0
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
if args.command == "top8": 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 tournament = None
top_players = {} top_players = {}
try: if args.lkrz_file is not None:
lkrz = configparser.ConfigParser() lkrz = configparser.ConfigParser()
lkrz.read(args.lkrz_file) lkrz.read(str(args.lkrz_file))
log.info("Loading data from '{}'".format(args.lkrz_file)) log.info("Loading data from '{}'".format(args.lkrz_file))
@ -210,9 +237,7 @@ def main():
top_players[player.gamerTag] = player top_players[player.gamerTag] = player
except Exception as e: else:
log.warning(e)
# Get infos from smash.gg and write the config file # Get infos from smash.gg and write the config file
tournament, top_players = getTournamentTop( tournament, top_players = getTournamentTop(
@ -236,27 +261,32 @@ def main():
) )
if args.lkrz_file is None: 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) f.write(lkrz_data)
# Default outfile is 'tournament-slug.svg' # Default outfile is 'tournament-slug.svg'
if args.outfile is None: 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 # 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 = { context = {
"tournament": tournament.clean_name(args.name_seo_delimiter), "tournament": tournament.clean_name(args.name_seo_delimiter),
"players" : sorted( "players" : sorted(
top_players.values(), top_players.values(),
key = lambda p: p.placement, key = lambda p: p.placement,
), ),
"dir_root": args.rootdir, "dir_res_ssbu": dir_res_ssbu,
"dir_res_ssbu": os.path.join(
args.imgdir,
"chars",
),
} }
rv = export.generate_outfile( rv = export.generate_outfile(
@ -264,7 +294,8 @@ def main():
args.template, args.template,
context, context,
args.outfile, args.outfile,
log, log = log,
cachedir = pathlib.Path(APPDIRS.user_cache_dir),
) )
if rv is None: if rv is None:
@ -329,6 +360,7 @@ def getTournamentTop(
"id" : int(id_or_slug), # If this fails, it's a slug "id" : int(id_or_slug), # If this fails, it's a slug
"top": top, "top": top,
}, },
query_dir = ROOTDIR / "queries",
token = token, token = token,
proxy = proxy, proxy = proxy,
log = log, log = log,
@ -341,6 +373,7 @@ def getTournamentTop(
"slug" : id_or_slug, "slug" : id_or_slug,
"top": top, "top": top,
}, },
query_dir = ROOTDIR / "queries",
token = token, token = token,
proxy = proxy, proxy = proxy,
log = log, log = log,
@ -425,6 +458,7 @@ def getTournamentTop(
"tournamentId" : int(tournament.id), "tournamentId" : int(tournament.id),
"entrantIds": [ id for id in top_players.keys() ], "entrantIds": [ id for id in top_players.keys() ],
}, },
query_dir = ROOTDIR / "queries",
token = token, token = token,
proxy = proxy, proxy = proxy,
log = log, log = log,
@ -478,3 +512,4 @@ def getTournamentTop(
if __name__ == '__main__': if __name__ == '__main__':
rv = main() rv = main()
sys.exit(rv) sys.exit(rv)

14
lokrez/__main__.py Normal file
View File

@ -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()

View File

@ -49,7 +49,7 @@ EVERYONE = [
], ],
), ),
SSBUCharacter( SSBUCharacter(
smashggid = 1409, smashggid = 1539,
name = "byleth", name = "byleth",
codename = "master", codename = "master",
spritersurls = [ spritersurls = [
@ -609,7 +609,7 @@ EVERYONE = [
], ],
), ),
SSBUCharacter( SSBUCharacter(
smashggid = None, smashggid = 1341,
name = "zero suit samus", name = "zero suit samus",
codename = "szerosuit", codename = "szerosuit",
spritersurls = [ spritersurls = [

View File

@ -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"
}
}

View File

@ -1,5 +1,6 @@
import os import os
import subprocess import subprocess
import tempfile
import jinja2 import jinja2
@ -10,51 +11,64 @@ def generate_outfile(
context, context,
outfilename, outfilename,
log = None, log = None,
cachedir = None,
): ):
# Template rendering # Template rendering
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
log.info("Generating SVG using '{}' template".format(templatename)) log.info("Generating SVG using '{}' template".format(templatename))
log.debug(
"Initializing jinja2 with template dir '{}'" \
.format(templatesdir)
)
jj2_env = jinja2.Environment( jj2_env = jinja2.Environment(
loader = jinja2.FileSystemLoader( templatesdir ) loader = jinja2.FileSystemLoader(
str(templatesdir),
)
) )
try: try:
jj2_tpl = jj2_env.get_template( jj2_tpl = jj2_env.get_template(
os.path.join( # Jinja specific path format
templatename, "{}/template.svg.j2".format(templatename),
"template.svg.j2",
) )
) except Exception as e:
except:
log.error("Could not find template '{}'".format(templatename)) log.error("Could not find template '{}'".format(templatename))
log.debug(e, exc_info=1)
return None return None
extension = outfilename.split(".")[-1]
# To SVG # To SVG
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
if extension == "svg": if outfilename.suffix == ".svg":
jj2_tpl.stream(context).dump( outfilename ) jj2_tpl.stream(context).dump( str(outfilename) )
return outfilename return outfilename
# To PNG with inkscape # To PNG with inkscape
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
if extension == "png": if outfilename.suffix == ".png":
cachedir.mkdir(parents=True, exist_ok=True)
with tempfile.NamedTemporaryFile(
suffix="svg",
dir = str(cachedir),
) as tmpsvg:
try: try:
log.info("Exporting to {} using inkscape".format(extension)) log.info(
"Exporting to {} using inkscape" \
.format(outfilename.suffix),
)
import subprocess import subprocess
jj2_tpl.stream(context).dump( "tmp.svg" ) jj2_tpl.stream(context).dump( tmpsvg.name )
inkscape_process = subprocess.Popen( inkscape_process = subprocess.Popen(
[ [
"inkscape", "inkscape",
"tmp.svg", tmpsvg.name,
"--export-filename", "--export-filename",
outfilename, str(outfilename),
], ],
stdout = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.STDOUT, stderr = subprocess.STDOUT,
@ -74,23 +88,18 @@ def generate_outfile(
.format(inkscape_process.returncode) .format(inkscape_process.returncode)
) )
os.unlink("tmp.svg")
return outfilename return outfilename
except Exception as e: except Exception as e:
log.warning("Failed to export with inkscape") log.warning("Failed to export with inkscape")
try: log.debug(e, exc_info=True)
os.unlink("tmp.svg")
except:
pass
log.debug(e)
# To png, pdf or ps with cairosvg # 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: try:
import cairosvg import cairosvg
@ -105,16 +114,16 @@ def generate_outfile(
svg_str = jj2_tpl.render(context) svg_str = jj2_tpl.render(context)
if extension == "png": if outfilename.suffix == ".png":
conversion_fun = cairosvg.svg2png conversion_fun = cairosvg.svg2png
elif extension == "pdf": elif outfilename.suffix == ".pdf":
conversion_fun = cairosvg.svg2pdf conversion_fun = cairosvg.svg2pdf
elif extension == "ps": elif outfilename.suffix == ".ps":
conversion_fun = cairosvg.svg2ps conversion_fun = cairosvg.svg2ps
conversion_fun( conversion_fun(
bytestring = svg_str, bytestring = svg_str,
write_to = outfilename, write_to = str(outfilename),
) )
return outfilename return outfilename
@ -125,7 +134,7 @@ def generate_outfile(
"Can't export to '{}' : unsupported format '{}'" \ "Can't export to '{}' : unsupported format '{}'" \
.format( .format(
outfilename, outfilename,
extension, outfilename.suffix,
) )
) )
return None return None

View File

@ -1,18 +1,19 @@
import io import io
import os import pathlib
import sys import sys
import zipfile import zipfile
import requests 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( r = requests.get(
url, url,
stream = with_progressbar, stream = with_progressbar,
proxies = { "https": proxy, "http": proxy },
) )
if not with_progressbar: if not with_progressbar:
@ -44,7 +45,7 @@ def download_file(url, with_progressbar = True):
return f 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 """Downloads SSBU resources from spriters and rename them according to
lokrez expectations""" lokrez expectations"""
@ -52,37 +53,50 @@ def download_res_ssbu(dstdir, log=None):
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Download stock icons # Download stock icons
log.info("Downloading stock icons...") log.warning("Downloading stock icons...")
fstocks = download_file(stock_icons_url) fstocks = download_file(stock_icons_url, proxy = proxy)
zfstocks = zipfile.ZipFile(fstocks) zfstocks = zipfile.ZipFile(fstocks)
# Iter over each character # Iter over each character
for character in characters_ssbu.EVERYONE: for character in EVERYONE:
log.info("Downloading images for {}...".format(character.name)) log.warning("Downloading images for {}...".format(character.name))
# Create directory for this character # Create directory for this character
chardir = os.path.join( chardir = dstdir / character.name
dstdir,
character.name,
)
try: try:
os.mkdir( chardir ) chardir.mkdir()
except FileExistsError: except FileExistsError:
log.warning( log.info(
"Directory already exists for {}".format(character.name) "Directory already exists for {}".format(character.name)
) )
if os.listdir( chardir ): try:
next(chardir.iterdir())
log.warning( log.warning(
"Directory not empty for {}, skipping" \ "Directory not empty for {}, skipping" \
.format(character.name) .format(character.name)
) )
continue continue
except StopIteration:
log.info(
"Directory empty, downloading",
)
# Download urls & write image files # Download urls & write image files
for url in character.spritersurls: 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: with zipfile.ZipFile(f) as zfchar:
for zf in [zfchar,zfstocks]: for zf in [zfchar,zfstocks]:
for source_filename in zf.namelist(): for source_filename in zf.namelist():
@ -90,13 +104,15 @@ def download_res_ssbu(dstdir, log=None):
if "No Gamma Fix" in source_filename: if "No Gamma Fix" in source_filename:
continue continue
if os.path.basename(source_filename) in ["","Tag.txt"]:
continue
if character.codename not in source_filename: if character.codename not in source_filename:
continue 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( target_filename = target_filename.replace(
character.codename, character.codename,
@ -105,12 +121,9 @@ def download_res_ssbu(dstdir, log=None):
log.debug("Writing file '{}'".format(target_filename)) log.debug("Writing file '{}'".format(target_filename))
target_filename = os.path.join( target_filename = chardir / 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)) tf.write(zf.read(source_filename))
# ============================================================================= # =============================================================================

View File

@ -1,9 +1,10 @@
import json import json
import os, os.path import os, os.path
import pathlib
import requests import requests
import characters_ssbu from . import characters_ssbu
# ============================================================================= # =============================================================================
API_HOST = "api.smash.gg" API_HOST = "api.smash.gg"
@ -15,15 +16,16 @@ API_URL = "{scheme}://{host}/{endpoint}".format(
endpoint = API_ENDPOINT, endpoint = API_ENDPOINT,
) )
CHARACTERS = { c.smashggid : c.name for c in characters_ssbu.EVERYONE }
PLAYERSKINS = {}
# ============================================================================= # =============================================================================
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
class Player(): class Player():
"""A Player, as registered by the smash.gg API, and their characters """A Player, as registered by the smash.gg API, and their characters
choices and placement in a tournament""" choices and placement in a tournament"""
# TODO fill missing chars
CHARACTERS = { c.smashggid : c.name for c in characters_ssbu.EVERYONE }
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
def __init__( def __init__(
self, self,
@ -49,11 +51,20 @@ class Player():
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
def add_character_selection(self, character, win): def add_character_selection(self, character, win):
try:
character = (self.CHARACTERS[character], "00")
except KeyError:
if type(character) != tuple: if type(character) != tuple:
character = (character, "00") 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: try:
self.chars[character] += ( 1.01 if win else 1.00 ) self.chars[character] += ( 1.01 if win else 1.00 )
@ -165,23 +176,20 @@ def run_query(
variables = {}, variables = {},
token = "", token = "",
proxy = None, proxy = None,
query_dir = "queries", query_dir = pathlib.Path("queries"),
query_extension = "gql", query_extension = "gql",
api_url = API_URL, api_url = API_URL,
log = None, log = None,
): ):
# Load query # Load query
query_path = os.path.join( query_path = query_dir / "{}.{}".format(
query_dir,
"{}.{}".format(
query_name, query_name,
query_extension, query_extension,
) )
)
query = "" query = ""
with open(query_path, 'r') as query_file: with query_path.open("r") as query_file:
query = query_file.read() query = query_file.read()
# Build payload # Build payload

View File

@ -1 +0,0 @@
logo_reboot_covid.svg.j2

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 135 KiB

View File

@ -1 +0,0 @@
logo_reboot_covid.svg.j2

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -40,6 +40,30 @@
is_visible="true" is_visible="true"
id="path-effect5529" id="path-effect5529"
effect="envelope" /> effect="envelope" />
<linearGradient
inkscape:collect="always"
id="progressiveMskGradient">
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="0"
id="stop1253" />
<stop
id="stop1255"
offset="0.14473191"
style="stop-color:#ffffff;stop-opacity:1" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="0.71604538"
id="stop1257" />
<stop
id="stop1298"
offset="0.8651849"
style="stop-color:#ffffff;stop-opacity:0.34995934" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop1259" />
</linearGradient>
<linearGradient <linearGradient
id="gradient_playerbg" id="gradient_playerbg"
inkscape:collect="always"> inkscape:collect="always">
@ -460,7 +484,7 @@
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3172-5"> id="player1_msk">
<path <path
inkscape:label="#player_img_msk" inkscape:label="#player_img_msk"
transform="matrix(1,0,-0.26989745,0.96288907,0,0)" transform="matrix(1,0,-0.26989745,0.96288907,0,0)"
@ -477,9 +501,9 @@
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3176-2"> id="player2_msk">
<path <path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.0746712px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.0746712px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 60.665101,164.31506 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z" d="m 60.665101,164.31506 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z"
id="path3178-9" id="path3178-9"
inkscape:label="#player_img_msk" /> inkscape:label="#player_img_msk" />
@ -496,64 +520,73 @@
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3383-1"> id="player3_msk">
<path <path
inkscape:label="#player_img_msk" inkscape:label="#player_img_msk"
id="path3385-2" id="path3385-2"
d="m 60.665101,203.4735 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z" d="m 60.665101,203.4735 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3319-7"> id="player4_msk">
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 60.665101,243.69019 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z" d="m 60.665101,243.69019 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z"
id="path3321-0" id="path3321-0"
inkscape:label="#player_img_msk" /> inkscape:label="#player_img_msk" />
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3323-9"> id="player5a_msk">
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 60.665101,283.90691 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z" d="m 60.665101,283.90691 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z"
id="path3325-3" id="path3325-3"
inkscape:label="#player_img_msk" /> inkscape:label="#player_img_msk" />
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3327-6"> id="player5b_msk">
<path <path
inkscape:label="#player_img_msk" inkscape:label="#player_img_msk"
id="path3329-0" id="path3329-0"
d="m 60.665101,323.59444 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z" d="m 60.665101,323.59444 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3331-6"> id="player7a_msk">
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 60.665101,363.81116 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z" d="m 60.665101,363.81116 -9.332627,33.07292 H 164.22136 l 9.33263,-33.07292 z"
id="path3333-2" id="path3333-2"
inkscape:label="#player_img_msk" /> inkscape:label="#player_img_msk" />
</mask> </mask>
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask3335-6"> id="player7b_msk">
<path <path
inkscape:label="#player_img_msk" inkscape:label="#player_img_msk"
id="path3337-1" id="path3337-1"
d="m 60.665101,404.55702 -9.332627,33.07291 H 164.22136 l 9.33263,-33.07291 z" d="m 60.665101,404.55702 -9.332627,33.07291 H 164.22136 l 9.33263,-33.07291 z"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:url(#linearGradientMsk);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
</mask> </mask>
<linearGradient
y2="179.5889"
x2="147.80486"
y1="179.5889"
x1="72.269859"
gradientUnits="userSpaceOnUse"
id="linearGradientMsk"
xlink:href="#progressiveMskGradient"
inkscape:collect="always" />
</defs> </defs>
<sodipodi:namedview <sodipodi:namedview
inkscape:document-rotation="0" inkscape:document-rotation="0"
@ -702,7 +735,7 @@
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
id="player1_img" id="player1_img"
mask="url(#mask3172-5)" mask="url(#player1_msk)"
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
<text <text
id="player1_tag" id="player1_tag"
@ -833,7 +866,7 @@
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
id="player2_img" id="player2_img"
mask="url(#mask3176-2)" mask="url(#player2_msk)"
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
<text <text
inkscape:label="#playertag" inkscape:label="#playertag"
@ -964,7 +997,7 @@
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
id="player3_img" id="player3_img"
mask="url(#mask3383-1)" mask="url(#player3_msk)"
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
<text <text
id="player3_tag" id="player3_tag"
@ -1088,7 +1121,7 @@
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[3].get_mains()[0][0]}}/chara_6_{{players[3].get_mains()[0][0]}}_{{players[3].get_mains()[0][1]}}.png" xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[3].get_mains()[0][0]}}/chara_6_{{players[3].get_mains()[0][0]}}_{{players[3].get_mains()[0][1]}}.png"
mask="url(#mask3319-7)" mask="url(#player4_msk)"
id="player4_img" id="player4_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1226,7 +1259,7 @@
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
id="player5a_img" id="player5a_img"
mask="url(#mask3323-9)" mask="url(#player5a_msk)"
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
<text <text
id="player5a_tag" id="player5a_tag"
@ -1350,7 +1383,7 @@
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[5].get_mains()[0][0]}}/chara_6_{{players[5].get_mains()[0][0]}}_{{players[5].get_mains()[0][1]}}.png" xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[5].get_mains()[0][0]}}/chara_6_{{players[5].get_mains()[0][0]}}_{{players[5].get_mains()[0][1]}}.png"
mask="url(#mask3327-6)" mask="url(#player5b_msk)"
id="player5b_img" id="player5b_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1488,7 +1521,7 @@
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
id="player7a_img" id="player7a_img"
mask="url(#mask3331-6)" mask="url(#player7a_msk)"
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
<text <text
id="player7a_tag" id="player7a_tag"
@ -1612,7 +1645,7 @@
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[7].get_mains()[0][0]}}/chara_6_{{players[7].get_mains()[0][0]}}_{{players[7].get_mains()[0][1]}}.png" xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[7].get_mains()[0][0]}}/chara_6_{{players[7].get_mains()[0][0]}}_{{players[7].get_mains()[0][1]}}.png"
mask="url(#mask3335-6)" mask="url(#player7b_msk)"
id="player7b_img" id="player7b_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1884,7 +1917,7 @@
transform="matrix(0.25154508,0,0,0.25154508,139.92955,6.0612125)" transform="matrix(0.25154508,0,0,0.25154508,139.92955,6.0612125)"
id="logo" id="logo"
inkscape:label="logo"> inkscape:label="logo">
{% include 'rebootlyon2/logo.svg.j2' %} {% include 'rebootlyon2019/logo.svg.j2' %}
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View File

@ -1 +0,0 @@
logo_reboot_covid.svg.j2

Before

Width:  |  Height:  |  Size: 24 B

After

Width:  |  Height:  |  Size: 110 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 24 B

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -904,7 +904,7 @@
</g> </g>
{% if players[0].get_mains()[1] %} {% if players[0].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[0].get_mains()[1][0]}}/chara_2_{{players[0].get_mains()[1][0]}}_{{players[0].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[0].get_mains()[1][0]}}/chara_2_{{players[0].get_mains()[1][0]}}_{{players[0].get_mains()[1][1]}}.png"
inkscape:svg-dpi="1" inkscape:svg-dpi="1"
id="player1_2_img" id="player1_2_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
@ -916,7 +916,7 @@
{% endif %} {% endif %}
{% if players[0].get_mains()[2] %} {% if players[0].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[0].get_mains()[2][0]}}/chara_2_{{players[0].get_mains()[2][0]}}_{{players[0].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[0].get_mains()[2][0]}}/chara_2_{{players[0].get_mains()[2][0]}}_{{players[0].get_mains()[2][1]}}.png"
y="141.06041" y="141.06041"
x="158.4778" x="158.4778"
width="14.324512" width="14.324512"
@ -927,7 +927,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[0].get_mains()[0][0]}}/chara_3_{{players[0].get_mains()[0][0]}}_{{players[0].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[0].get_mains()[0][0]}}/chara_3_{{players[0].get_mains()[0][0]}}_{{players[0].get_mains()[0][1]}}.png"
y="104.07462" y="104.07462"
x="15.232052" x="15.232052"
width="200" width="200"
@ -1035,7 +1035,7 @@
</g> </g>
{% if players[1].get_mains()[2] %} {% if players[1].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[1].get_mains()[2][0]}}/chara_2_{{players[1].get_mains()[2][0]}}_{{players[1].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[1].get_mains()[2][0]}}/chara_2_{{players[1].get_mains()[2][0]}}_{{players[1].get_mains()[2][1]}}.png"
id="player2_3_img" id="player2_3_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1047,7 +1047,7 @@
{% endif %} {% endif %}
{% if players[1].get_mains()[1] %} {% if players[1].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[1].get_mains()[1][0]}}/chara_2_{{players[1].get_mains()[1][0]}}_{{players[1].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[1].get_mains()[1][0]}}/chara_2_{{players[1].get_mains()[1][0]}}_{{players[1].get_mains()[1][1]}}.png"
y="165.56485" y="165.56485"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1058,7 +1058,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[1].get_mains()[0][0]}}/chara_6_{{players[1].get_mains()[0][0]}}_{{players[1].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[1].get_mains()[0][0]}}/chara_6_{{players[1].get_mains()[0][0]}}_{{players[1].get_mains()[0][1]}}.png"
y="160.70035" y="160.70035"
x="69.902924" x="69.902924"
width="78.628876" width="78.628876"
@ -1166,7 +1166,7 @@
</g> </g>
{% if players[2].get_mains()[1] %} {% if players[2].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[2].get_mains()[1][0]}}/chara_2_{{players[2].get_mains()[1][0]}}_{{players[2].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[2].get_mains()[1][0]}}/chara_2_{{players[2].get_mains()[1][0]}}_{{players[2].get_mains()[1][1]}}.png"
y="204.72319" y="204.72319"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1178,7 +1178,7 @@
{% endif %} {% endif %}
{% if players[2].get_mains()[2] %} {% if players[2].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[2].get_mains()[2][0]}}/chara_2_{{players[2].get_mains()[2][0]}}_{{players[2].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[2].get_mains()[2][0]}}/chara_2_{{players[2].get_mains()[2][0]}}_{{players[2].get_mains()[2][1]}}.png"
id="player3_3_img" id="player3_3_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1189,7 +1189,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[2].get_mains()[0][0]}}/chara_6_{{players[2].get_mains()[0][0]}}_{{players[2].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[2].get_mains()[0][0]}}/chara_6_{{players[2].get_mains()[0][0]}}_{{players[2].get_mains()[0][1]}}.png"
y="200.77824" y="200.77824"
x="69.902924" x="69.902924"
width="78.628876" width="78.628876"
@ -1297,7 +1297,7 @@
</g> </g>
{% if players[3].get_mains()[2] %} {% if players[3].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[3].get_mains()[2][0]}}/chara_2_{{players[3].get_mains()[2][0]}}_{{players[3].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[3].get_mains()[2][0]}}/chara_2_{{players[3].get_mains()[2][0]}}_{{players[3].get_mains()[2][1]}}.png"
id="player4_3_img" id="player4_3_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1309,7 +1309,7 @@
{% endif %} {% endif %}
{% if players[3].get_mains()[1] %} {% if players[3].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[3].get_mains()[1][0]}}/chara_2_{{players[3].get_mains()[1][0]}}_{{players[3].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[3].get_mains()[1][0]}}/chara_2_{{players[3].get_mains()[1][0]}}_{{players[3].get_mains()[1][1]}}.png"
y="244.93987" y="244.93987"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1320,7 +1320,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[3].get_mains()[0][0]}}/chara_6_{{players[3].get_mains()[0][0]}}_{{players[3].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[3].get_mains()[0][0]}}/chara_6_{{players[3].get_mains()[0][0]}}_{{players[3].get_mains()[0][1]}}.png"
mask="url(#player4_msk)" mask="url(#player4_msk)"
id="player4_img" id="player4_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
@ -1428,7 +1428,7 @@
</g> </g>
{% if players[4].get_mains()[2] %} {% if players[4].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[4].get_mains()[2][0]}}/chara_2_{{players[4].get_mains()[2][0]}}_{{players[4].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[4].get_mains()[2][0]}}/chara_2_{{players[4].get_mains()[2][0]}}_{{players[4].get_mains()[2][1]}}.png"
y="300.23517" y="300.23517"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1440,7 +1440,7 @@
{% endif %} {% endif %}
{% if players[4].get_mains()[1] %} {% if players[4].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[4].get_mains()[1][0]}}/chara_2_{{players[4].get_mains()[1][0]}}_{{players[4].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[4].get_mains()[1][0]}}/chara_2_{{players[4].get_mains()[1][0]}}_{{players[4].get_mains()[1][1]}}.png"
id="player5a_2_img" id="player5a_2_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1451,7 +1451,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[4].get_mains()[0][0]}}/chara_6_{{players[4].get_mains()[0][0]}}_{{players[4].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[4].get_mains()[0][0]}}/chara_6_{{players[4].get_mains()[0][0]}}_{{players[4].get_mains()[0][1]}}.png"
y="281.36505" y="281.36505"
x="69.902924" x="69.902924"
width="78.628876" width="78.628876"
@ -1559,7 +1559,7 @@
</g> </g>
{% if players[5].get_mains()[2] %} {% if players[5].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[5].get_mains()[2][0]}}/chara_2_{{players[5].get_mains()[2][0]}}_{{players[5].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[5].get_mains()[2][0]}}/chara_2_{{players[5].get_mains()[2][0]}}_{{players[5].get_mains()[2][1]}}.png"
id="player5b_3_img" id="player5b_3_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1571,7 +1571,7 @@
{% endif %} {% endif %}
{% if players[5].get_mains()[1] %} {% if players[5].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[5].get_mains()[1][0]}}/chara_2_{{players[5].get_mains()[1][0]}}_{{players[5].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[5].get_mains()[1][0]}}/chara_2_{{players[5].get_mains()[1][0]}}_{{players[5].get_mains()[1][1]}}.png"
y="324.84415" y="324.84415"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1582,7 +1582,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[5].get_mains()[0][0]}}/chara_6_{{players[5].get_mains()[0][0]}}_{{players[5].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[5].get_mains()[0][0]}}/chara_6_{{players[5].get_mains()[0][0]}}_{{players[5].get_mains()[0][1]}}.png"
mask="url(#player5b_msk)" mask="url(#player5b_msk)"
id="player5b_img" id="player5b_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
@ -1690,7 +1690,7 @@
</g> </g>
{% if players[6].get_mains()[2] %} {% if players[6].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[6].get_mains()[2][0]}}/chara_2_{{players[6].get_mains()[2][0]}}_{{players[6].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[6].get_mains()[2][0]}}/chara_2_{{players[6].get_mains()[2][0]}}_{{players[6].get_mains()[2][1]}}.png"
y="380.1394" y="380.1394"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1702,7 +1702,7 @@
{% endif %} {% endif %}
{% if players[6].get_mains()[1] %} {% if players[6].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[6].get_mains()[1][0]}}/chara_2_{{players[6].get_mains()[1][0]}}_{{players[6].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[6].get_mains()[1][0]}}/chara_2_{{players[6].get_mains()[1][0]}}_{{players[6].get_mains()[1][1]}}.png"
id="player7a_2_img" id="player7a_2_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1713,7 +1713,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[6].get_mains()[0][0]}}/chara_6_{{players[6].get_mains()[0][0]}}_{{players[6].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[6].get_mains()[0][0]}}/chara_6_{{players[6].get_mains()[0][0]}}_{{players[6].get_mains()[0][1]}}.png"
y="362.8566" y="362.8566"
x="69.902924" x="69.902924"
width="78.628876" width="78.628876"
@ -1821,7 +1821,7 @@
</g> </g>
{% if players[7].get_mains()[2] %} {% if players[7].get_mains()[2] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[7].get_mains()[2][0]}}/chara_2_{{players[7].get_mains()[2][0]}}_{{players[7].get_mains()[2][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[7].get_mains()[2][0]}}/chara_2_{{players[7].get_mains()[2][0]}}_{{players[7].get_mains()[2][1]}}.png"
id="player7b_3_img" id="player7b_3_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
preserveAspectRatio="xMidYMid" preserveAspectRatio="xMidYMid"
@ -1833,7 +1833,7 @@
{% endif %} {% endif %}
{% if players[7].get_mains()[1] %} {% if players[7].get_mains()[1] %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[7].get_mains()[1][0]}}/chara_2_{{players[7].get_mains()[1][0]}}_{{players[7].get_mains()[1][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[7].get_mains()[1][0]}}/chara_2_{{players[7].get_mains()[1][0]}}_{{players[7].get_mains()[1][1]}}.png"
y="405.8067" y="405.8067"
x="158.4778" x="158.4778"
width="14.324511" width="14.324511"
@ -1844,7 +1844,7 @@
inkscape:svg-dpi="1" /> inkscape:svg-dpi="1" />
{% endif %} {% endif %}
<image <image
xlink:href="{{dir_root}}/{{dir_res_ssbu}}/{{players[7].get_mains()[0][0]}}/chara_6_{{players[7].get_mains()[0][0]}}_{{players[7].get_mains()[0][1]}}.png" xlink:href="{{dir_res_ssbu}}/{{players[7].get_mains()[0][0]}}/chara_6_{{players[7].get_mains()[0][0]}}_{{players[7].get_mains()[0][1]}}.png"
mask="url(#player7b_msk)" mask="url(#player7b_msk)"
id="player7b_img" id="player7b_img"
style="display:inline;image-rendering:optimizeQuality" style="display:inline;image-rendering:optimizeQuality"
@ -2010,7 +2010,7 @@
transform="matrix(0.22624853,0,0,0.22624853,139.92955,9.2362127)" transform="matrix(0.22624853,0,0,0.22624853,139.92955,9.2362127)"
id="logo_reboot" id="logo_reboot"
inkscape:label="logo_reboot"> inkscape:label="logo_reboot">
{% include 'rebootlyon2/logo.svg.j2' %} {% include 'rebootlyon2020/logo.svg.j2' %}
</g> </g>
<g <g
style="display:inline;opacity:1" style="display:inline;opacity:1"

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View File

@ -1,7 +1,15 @@
NAME = "lokrez" NAME = "lokrez"
DESCRIPTION = "Smash.gg-connected top8 graphics generator for Super Smash " \
"Bros Ultimate tournaments"
URL = "https://git.lertsenem.com/lertsenem/ssbu_lokrez"
AUTHOR = "Lertsenem"
ENTITY = "Smash@Lyon"
AUTHOR_EMAIL = "lertsenem@lertsenem.com"
ENTITY_EMAIL = "dev@smashatlyon.com"
VERSION_MAJOR = 1 VERSION_MAJOR = 1
VERSION_MINOR = 0 VERSION_MINOR = 1
VERSION_PATCH = 0 VERSION_PATCH = 0
__version__ = "{}.{}.{}".format( __version__ = "{}.{}.{}".format(
@ -14,3 +22,5 @@ VERSION_NAME = "{} - {}".format(
NAME, NAME,
__version__, __version__,
) )
__license__ = "MIT"

104
setup.py Normal file
View File

@ -0,0 +1,104 @@
import distutils, distutils.util
import os
import setuptools
import sys
import lokrez, lokrez.version
# Load README for long_description
with open("README.adoc", "r") as fh:
long_description = fh.read()
# Windows build
if os.name == "nt":
import cx_Freeze
arch = distutils.util.get_platform().split("-")[-1]
build_exe_options = {
"packages": ["os"],
"include_msvcr": True,
"include_files": [ "lokrez/data", "lokrez/templates", "lokrez/queries" ],
"includes": ["idna.idnadata"], # Because of cx-freeze bug
}
bdist_msi_options = {
"upgrade_code": "{123456789-1337-8483-ABCD-DEADBEEFCAFE}",
"add_to_path": True,
"initial_target_dir": r"[LocalAppDataFolder]\{}\{}" \
.format(
lokrez.version.ENTITY,
lokrez.version.NAME,
),
}
base = None
cx_Freeze.setup(
name = lokrez.version.NAME,
version = lokrez.version.__version__.replace("dev", "1337"),
author = lokrez.version.AUTHOR,
author_email = lokrez.version.AUTHOR_EMAIL,
description = lokrez.version.DESCRIPTION,
install_requires = [
"jinja2",
"requests",
"appdirs",
],
options = {
"build_exe": build_exe_options,
"bdist_msi": bdist_msi_options,
},
executables = [
cx_Freeze.Executable(
script = "lokrez/__main__.py",
targetName = "{}.exe".format(lokrez.version.NAME),
base = base,
),
],
)
sys.exit(0)
# Linux build
if os.name == "posix":
setuptools.setup(
name = lokrez.version.NAME,
version = lokrez.__version__,
author = lokrez.version.AUTHOR,
author_email = lokrez.version.AUTHOR_EMAIL,
description = lokrez.version.DESCRIPTION,
long_description = long_description,
long_description_content_type = "text/asciidoc",
url = lokrez.version.URL,
packages = ["lokrez"],
install_requires = [
"jinja2",
"requests",
"appdirs",
],
license = lokrez.version.__license__,
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Intended Audience :: Smash Bros Ultimate Players",
],
python_requires = ">=3.5",
keywords = "smash ultimate local results esport smashgg",
# data_files = ("res", ["res/playerskinsdb.json"])
package_data = {
"lokrez": [
"data/*.json",
"queries/*.gql",
"templates/*/*.j2",
],
},
entry_points = {
"console_scripts": [
"lokrez = lokrez:main",
],
},
)

83
setup_noadmin.py Normal file
View File

@ -0,0 +1,83 @@
import distutils, distutils.util
import msilib
import pathlib
import lokrez, lokrez.version
# -----------------------------------------------------------------------------
arch = distutils.util.get_platform().split("-")[-1]
msi_filepath = pathlib.Path(
"dist",
"{}-{}-{}.msi" \
.format(
lokrez.version.NAME,
lokrez.version.__version__.replace("dev", "1337"),
arch,
),
)
# -----------------------------------------------------------------------------
# Modifications to allow for a non-admin-required msi
print("modifying final msi '{}' for standard user installation" \
.format(msi_filepath))
if not msi_filepath.exists():
print("msi file does not exist")
else:
try:
db = msilib.OpenDatabase(
str(msi_filepath),
msilib.MSIDBOPEN_TRANSACT,
)
si = db.GetSummaryInformation(20)
cur_wc = si.GetProperty(msilib.PID_WORDCOUNT)
si.SetProperty(
msilib.PID_WORDCOUNT,
cur_wc | 0b1000,
)
si.SetProperty(
msilib.PID_AUTHOR,
"{} - {}" \
.format(
lokrez.version.ENTITY,
lokrez.version.AUTHOR,
),
)
si.Persist()
# Install for the current user only
vi = db.OpenView(
"DELETE FROM `Property` WHERE `Property`.`Property` = 'ALLUSERS'"
)
vi.Execute(None)
vi.Close()
# Add the manufacturer name
vi = db.OpenView(
"UPDATE `Property` SET `Property`.`Value`='{} - {}' WHERE " \
"`Property`.`Property` = 'Manufacturer'" \
.format(
lokrez.version.ENTITY,
lokrez.version.AUTHOR,
),
)
vi.Execute(None)
vi.Close()
# Update Path env variable for the user only
vi = db.OpenView(
"UPDATE `Environment` SET `Environment`.`Name`='=-Path' " \
"WHERE `Environment`.`Environment` = 'E_PATH'",
)
vi.Execute(None)
vi.Close()
db.Commit()
db.Close()
except Exception as e:
print("fail")
print(str(e))
print(e.args)
raise