From 1272a64d546937c07e81c80dab56feed21a1c57e Mon Sep 17 00:00:00 2001 From: Lertsenem Date: Thu, 9 Jul 2020 14:31:22 +0200 Subject: [PATCH] Add export submodule to handle output This submodule will handle saving the outfile to whatever format you want. For now, it can save in svg (default), png using inkscape, png, pdf or ps using cairosvg. --- lokrez/__init__.py | 48 ++++++++--------- lokrez/export.py | 129 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 24 deletions(-) create mode 100644 lokrez/export.py diff --git a/lokrez/__init__.py b/lokrez/__init__.py index cea4f5b..78351d2 100644 --- a/lokrez/__init__.py +++ b/lokrez/__init__.py @@ -5,8 +5,7 @@ import logging import os, os.path import sys -import jinja2 - +import export import smashgg import version @@ -113,16 +112,22 @@ def main(): # ------------------------------------------------------------------------- if args.version: print(version.VERSION_NAME) - sys.exit(0) + return 0 + # Set default arguments # ------------------------------------------------------------------------- + # Default rootdir is "." if args.rootdir is None: args.rootdir = "." # TODO compute script root? + # Default outfile is 'tournament-slug.svg' + if args.outfile is None: + args.outfile = "{}.svg".format(tournament.slug) + # ------------------------------------------------------------------------- if args.command not in [ "top8" ]: parser.print_help() - sys.exit(1) + return 1 # ------------------------------------------------------------------------- if args.command == "top8": @@ -145,7 +150,7 @@ def main(): if tournament is None or top_players is None: log.error("Could not load data from smash.gg") - sys.exit(1) + return 1 lkrz_data = "\n".join( [ tournament.conf() ] \ @@ -161,20 +166,7 @@ def main(): with open(args.lkrz_file, "w", encoding="utf8") as f: f.write(lkrz_data) - # Template rendering - log.info("Génération du SVG en utilisant le template") - - jj2_env = jinja2.Environment( - loader = jinja2.FileSystemLoader( args.templatesdir ) - ) - - jj2_tpl = jj2_env.get_template( - os.path.join( - args.template, - "template.svg.j2", - ) - ) - + # Build the context which will be passed to the template context = { "tournament": tournament, "players" : sorted( @@ -188,13 +180,20 @@ def main(): ), } + rv = export.generate_outfile( + args.templatesdir, + args.template, + context, + args.outfile, + log, + ) - if args.outfile is None: - args.outfile = "{}.svg".format(tournament.slug) - # TODO add png export + if rv is None: + return 1 - jj2_tpl.stream(context).dump( args.outfile ) + log.info("Successfully saved outfile as '{}'".format(rv)) + return 0 # ----------------------------------------------------------------------------- def getTournamentTop( @@ -398,4 +397,5 @@ def getTournamentTop( # ============================================================================= if __name__ == '__main__': - main() + rv = main() + sys.exit(rv) diff --git a/lokrez/export.py b/lokrez/export.py new file mode 100644 index 0000000..5b0870b --- /dev/null +++ b/lokrez/export.py @@ -0,0 +1,129 @@ +import os +import subprocess + +import jinja2 + +# ============================================================================= +def generate_outfile( + templatesdir, + templatename, + context, + outfilename, + log = None, + ): + + # Template rendering + # ------------------------------------------------------------------------- + log.info("Generating SVG using '{}' template".format(templatename)) + + jj2_env = jinja2.Environment( + loader = jinja2.FileSystemLoader( templatesdir ) + ) + + try: + jj2_tpl = jj2_env.get_template( + os.path.join( + templatename, + "template.svg.j2", + ) + ) + except: + log.error("Could not find template '{}'".format(templatename)) + return None + + extension = outfilename.split(".")[-1] + + # To SVG + # ------------------------------------------------------------------------- + if extension == "svg": + jj2_tpl.stream(context).dump( outfilename ) + return outfilename + + # To PNG with inkscape + # ------------------------------------------------------------------------- + if extension == "png": + + try: + log.info("Exporting to {} using inkscape".format(extension)) + import subprocess + + 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) + ) + + return outfilename + + except Exception as e: + log.warning("Failed to export with inkscape") + try: + os.unlink("tmp.svg") + except: + pass + log.debug(e) + + # To png, pdf or ps with cairosvg + # ------------------------------------------------------------------------- + if extension in [ "png", "pdf", "ps" ]: + + log.info("Exporting to {} using cairosvg".format(extension)) + + try: + import cairosvg + except ImportError as e: + log.error( + "Failed to export to '{}' with cairosvg" \ + .format( + outfilename, + ) + ) + log.debug(e) + + svg_str = jj2_tpl.render(context) + + if extension == "png": + conversion_fun = cairosvg.svg2png + elif extension == "pdf": + conversion_fun = cairosvg.svg2pdf + elif extension == "ps": + conversion_fun = cairosvg.svg2ps + + conversion_fun( + bytestring = svg_str, + write_to = outfilename, + ) + + return outfilename + + # To unsupported format + # ------------------------------------------------------------------------- + log.error( + "Can't export to '{}' : unsupported format '{}'" \ + .format( + outfilename, + extension, + ) + ) + return None