diff --git a/nuvolasdk/__init__.py b/nuvolasdk/__init__.py index 811f2a3..62ffe8d 100644 --- a/nuvolasdk/__init__.py +++ b/nuvolasdk/__init__.py @@ -1,5 +1,5 @@ """ -Copyright 2016 Jiří Janoušek +Copyright 2016-2018 Jiří Janoušek Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -35,6 +35,7 @@ import nuvolasdk.datadir import nuvolasdk.appdata import nuvolasdk.addondata +import nuvolasdk.createscreenshots def print_help(prog): print('Help') @@ -59,6 +60,9 @@ def print_help(prog): print('\nCreate addon data XML') print('====================\n') nuvolasdk.addondata.create_arg_parser(prog + " create-addondata").print_help() + print('\nCreate combined screenshots') + print('===========================\n') + nuvolasdk.createscreenshots.create_arg_parser(prog + " create-screenshots").print_help() def run(wd, argv): prog = os.path.basename(argv[0]) @@ -79,6 +83,8 @@ def run(wd, argv): return nuvolasdk.appdata.run(wd, prog + " " + cmd, argv[2:]) or 0 if cmd == "create-addondata": return nuvolasdk.addondata.run(wd, prog + " " + cmd, argv[2:]) or 0 + if cmd == "create-screenshots": + return nuvolasdk.createscreenshots.run(wd, prog + " " + cmd, argv[2:]) or 0 if cmd == "data-dir": return nuvolasdk.datadir.run(wd, prog + " " + cmd, argv[2:]) or 0 if cmd in ('-h', '--help', 'help'): diff --git a/nuvolasdk/createscreenshots.py b/nuvolasdk/createscreenshots.py new file mode 100644 index 0000000..6e39297 --- /dev/null +++ b/nuvolasdk/createscreenshots.py @@ -0,0 +1,62 @@ +""" +Copyright 2014-2018 Jiří Janoušek + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +import argparse +import datetime + +from nuvolasdk.shkit import * +from nuvolasdk import defaults +from nuvolasdk import imaging +from nuvolasdk import screenshots +from nuvolasdk import utils + +def create_arg_parser(prog): + parser = argparse.ArgumentParser( + prog = prog, + description = 'Creates combined screenshots.' + ) + parser.add_argument("--kind", help='The kind the app belongs to (e.g. audio, video, other).', type=str) + parser.add_argument("--fill", help='The fill color for areas not covered by the web view snapshot."', type=str) + parser.add_argument('-o', "--output-dir", help='The output directory to place screenshots to.', type=str) + parser.add_argument('-i', "--input", help='The input web view screenshot.', type=str, required=True) + return parser + +def run(directory, prog, argv): + args = create_arg_parser(prog).parse_args(argv) + output_dir = abspath(args.output_dir or directory) + kind = args.kind or 'other' + web_view_screenshot = abspath(args.input) + screenshots_dir = utils.get_sdk_data_dir('screenshots') + mkdirs(output_dir) + for base, bounds, fill in screenshots.BASE_SCREENSHOTS[kind]: + input_path = joinpath(screenshots_dir, base) + output_path = joinpath(output_dir, base) + print("'%s' → '%s'" % (input_path, output_path)) + img = imaging.combine_images(input_path, web_view_screenshot, bounds, args.fill or fill) + img.save(output_path, 'PNG', optimize=True) + + path = joinpath(output_dir, defaults.SCREENSHOTS_DIR_TIMESTAMP) + print("Timestamp file: '%s'" % path) + fwrite(path, datetime.datetime.now().isoformat()) + return 0 diff --git a/nuvolasdk/data/screenshots/pantheon.png b/nuvolasdk/data/screenshots/pantheon.png new file mode 100644 index 0000000..974c372 Binary files /dev/null and b/nuvolasdk/data/screenshots/pantheon.png differ diff --git a/nuvolasdk/data/screenshots/unity.png b/nuvolasdk/data/screenshots/unity.png new file mode 100644 index 0000000..92f522a Binary files /dev/null and b/nuvolasdk/data/screenshots/unity.png differ diff --git a/nuvolasdk/defaults.py b/nuvolasdk/defaults.py index 352501f..4e53519 100644 --- a/nuvolasdk/defaults.py +++ b/nuvolasdk/defaults.py @@ -1,5 +1,5 @@ """ -Copyright 2014-2016 Jiří Janoušek +Copyright 2014-2018 Jiří Janoušek Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -37,7 +37,7 @@ ] } -GITIGNORE = "Makefile\nmetadata.json\nicons\n" +GITIGNORE = "Makefile\nmetadata.json\nicons\n/screenshots/\n" METADATA_IN_JSON = OrderedDict(( ("id", "happy_songs"), @@ -56,3 +56,7 @@ )) CONFIGURE_SCRIPT = "#!/usr/bin/env python3\nimport nuvolasdk\nnuvolasdk.gen_makefile(\"%s\")\n" % VERSION + +WEB_VIEW_IMAGE = 'src/webview.png' + +SCREENSHOTS_DIR_TIMESTAMP = 'timestamp.txt' diff --git a/nuvolasdk/genmakefile.py b/nuvolasdk/genmakefile.py index 27f7b87..054c2a1 100644 --- a/nuvolasdk/genmakefile.py +++ b/nuvolasdk/genmakefile.py @@ -39,6 +39,7 @@ def gen_makefile(required_version=VERSION): genuine = False metadata = readjson("metadata.in.json") build_json = metadata.get("build", {}) + build_screenshots = isfile(defaults.WEB_VIEW_IMAGE) major, minor, micro, revision = utils.compute_version_from_git( metadata["version_major"], metadata.get("version_minor", 0), metadata.get("version_micro", 0)) @@ -152,6 +153,9 @@ def gen_makefile(required_version=VERSION): )) uninstall.append('\trm -fv $(DESTDIR)$(DATADIR)/metainfo/nuvola-app-$(APP_ID_DASHED).metainfo.xml\n') + if build_screenshots: + all_files.append('screenshots/%s' % defaults.SCREENSHOTS_DIR_TIMESTAMP) + icons_spec = build_json.get("icons", defaults.BUILD_JSON["icons"]) icons = [ '$(ICONS_DIR):\n', @@ -222,6 +226,13 @@ def gen_makefile(required_version=VERSION): ' $< > $@\n', )) + if build_screenshots: + makefile.extend(( + 'screenshots/%s: %s\n' % (defaults.SCREENSHOTS_DIR_TIMESTAMP, defaults.WEB_VIEW_IMAGE), + '\tpython3 -m nuvolasdk create-screenshots -o screenshots -i $<\n', + )) + all_files.append('screenshots/%s' % defaults.SCREENSHOTS_DIR_TIMESTAMP) + makefile.extend(icons) makefile.extend(install) makefile.extend(uninstall) @@ -235,6 +246,7 @@ def gen_makefile(required_version=VERSION): '\trm -fv $(APP_ID_DBUS).service\n' if flatpak_build else "", '\trm -fv $(APP_ID).tar.gz\n' if flatpak_build else "", "\trm -rvf icons\n", + "\trm -rvf screenshots\n" if build_screenshots else "", "distclean: clean\n", "\trm -vf Makefile metadata.json\n" )); diff --git a/nuvolasdk/imaging.py b/nuvolasdk/imaging.py new file mode 100644 index 0000000..49c6ad9 --- /dev/null +++ b/nuvolasdk/imaging.py @@ -0,0 +1,45 @@ +""" +Copyright 2018 Jiří Janoušek + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +try: + from PIL import Image +except ImportError as e: + Image = e + +def combine_images(outer, inner, bounds, fill=None): + if isinstance(Image, ImportError): + raise Image + if not isinstance(outer, Image.Image): + outer = Image.open(outer) + if not isinstance(inner, Image.Image): + inner = Image.open(inner) + if isinstance(bounds, str): + bounds = tuple(int(i) for i in bounds.replace('+', ',').split(',')) + result = Image.new('RGB', outer.size, fill) + x, y, width, height = bounds + x_offset = int((width - inner.size[0]) / 2) + y_offset = int((height - inner.size[1]) / 2) + result.paste(inner, (x + x_offset, y + y_offset), inner if inner.mode == 'RGBA' else None) + result.paste(outer, (0, 0), outer if outer.mode == 'RGBA' else None) + return result diff --git a/nuvolasdk/screenshots.py b/nuvolasdk/screenshots.py index 0bc0568..bb91ee1 100644 --- a/nuvolasdk/screenshots.py +++ b/nuvolasdk/screenshots.py @@ -54,3 +54,11 @@ "Enable and configure available features." ), ] + +BASE_SCREENSHOTS = { + 'other': [ + ('pantheon.png', '104,69+1080,600', '#c1c1c1'), + ('unity.png', '132,106+1080,600', '#c1c1c1'), + ] +} + diff --git a/work-files/screenshots/pantheon.xcf b/work-files/screenshots/pantheon.xcf new file mode 100644 index 0000000..e5841ed Binary files /dev/null and b/work-files/screenshots/pantheon.xcf differ diff --git a/work-files/screenshots/unity.xcf b/work-files/screenshots/unity.xcf new file mode 100644 index 0000000..4fce6b0 Binary files /dev/null and b/work-files/screenshots/unity.xcf differ