From 181667844fb6862fb0bbfee5e91601188047d7ca Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Thu, 20 Oct 2016 21:51:31 +0200 Subject: Packaging: Support for additional components in WIX installer It's now possible to select specific translations and to choose wether or not to install Python, extensions and dictionaries. (bzr r15244.1.17) --- packaging/wix/files.py | 67 +++++++++++++++++++++++++------- packaging/wix/helpers.py | 42 +++++++++++++++++++- packaging/wix/inkscape.wxs | 96 +++++++++++++++++++++++++++------------------- 3 files changed, 149 insertions(+), 56 deletions(-) diff --git a/packaging/wix/files.py b/packaging/wix/files.py index 8026a5259..7034021ac 100644 --- a/packaging/wix/files.py +++ b/packaging/wix/files.py @@ -3,9 +3,10 @@ from __future__ import print_function import os +import re import uuid -from helpers import get_inkscape_dist_dir +from helpers import get_inkscape_dist_dir, get_inkscape_locales_and_names directory_ids = {} file_ids = {} @@ -13,9 +14,12 @@ file_ids = {} def indent(level): indentstring = '' for i in range(level): - indentstring += ' ' + indentstring += ' ' return indentstring +def valid_id(identifier): + return identifier.replace('@','_') + def directory(root, breadcrumb, level, exclude=[]): """ list all files and directory recursivly @@ -36,7 +40,7 @@ def directory(root, breadcrumb, level, exclude=[]): wxs.write(indent(level + 1)+ "\n") wxs.write(indent(level)+ "\n") # then all directories - + dirs = [ f for f in os.listdir(root) if os.path.isdir(os.path.join(root,f)) ] for dir in dirs: directory_key = breadcrumb + '__' + dir @@ -45,15 +49,32 @@ def directory(root, breadcrumb, level, exclude=[]): wxs.write(indent(level) + "\n") directory(os.path.join(root, dir), directory_key, level + 1) wxs.write(indent(level) + "\n") - - -def ComponentGroup(name, condition, level): + +def test_conditions(value, conditions): + """ + check if "value" fullfills any of the "conditions", where a condition can be + - a string that has to be a substring of "value" + - a compiled regex pattern which has to match in "value" + """ + if not isinstance(conditions, list): + conditions = [conditions] + for condition in conditions: + if isinstance(condition, basestring): + if condition in value: + return True + elif isinstance(condition, type(re.compile(''))): + if re.search(condition, value): + return True + return False + + +def ComponentGroup(name, conditions, level): """ add componentgroup that contain all items from file_ids that match condition remove the matched elements from file_ids """ global file_ids - keys = [k for k in file_ids.keys() if condition in k] + keys = [k for k in file_ids.keys() if test_conditions(k, conditions)] wxs.write(indent(level) + "\n") for component in keys: wxs.write(indent(level + 1) + "\n") @@ -61,9 +82,12 @@ def ComponentGroup(name, condition, level): for key in keys: del file_ids[key] -#get directory containing the inkscape distribution files +# get directory containing the Inkscape distribution files inkscape_dist_dir = get_inkscape_dist_dir() +# get locales currently supported by Inkscape (dict of the form {'de': 'German (de)'}) +locales = get_inkscape_locales_and_names() + with open('files.wxs', 'w') as wxs: wxs.write("\n") wxs.write("\n") @@ -78,18 +102,33 @@ with open('files.wxs', 'w') as wxs: print("found %d files" % len(file_ids.keys())) wxs.write(indent(4) + "\n") wxs.write(indent(3) + "\n") - # link to ProgrmMenu + # link to ProgramMenu wxs.write(indent(3) + "\n") wxs.write(indent(4) + "\n") wxs.write(indent(3) + "\n") wxs.write(indent(3) + "\n") wxs.write(indent(2) + "\n") - ComponentGroup("Examples", 'inkscape\\share\\examples', 2) + + # Python + ComponentGroup("Python", 'inkscape\\python\\', 2) + # translations and localized content + for lang_code in sorted(locales): + ComponentGroup("Translation_" + valid_id(lang_code), ['\\' + lang_code + '\\', + re.compile(r'\.' + lang_code + r'\.[a-z]+$')], 2) + # other components + ComponentGroup("Extensions", 'inkscape\\share\\extensions\\', 2) + ComponentGroup("Examples", 'inkscape\\share\\examples\\', 2) ComponentGroup("Tutorials", 'inkscape\\share\\tutorials\\', 2) - ComponentGroup("Translations", '\\locale\\', 2) + ComponentGroup("Dictionaries", 'inkscape\\lib\\aspell-0.60\\', 2) + # everything that is left (which should be the Inkscape core unless inkscape_dist_dir contains unnecessary files or we defined our components poorly) ComponentGroup("AllOther", '', 2) + + # create a FeatureGroup for translations + wxs.write(indent(2) + "\n") + for lang_code in sorted(locales): + wxs.write(indent(3) + "\n") + wxs.write(indent(4) + "\n") + wxs.write(indent(3) + "\n") + wxs.write(indent(2) + "\n") wxs.write(indent(1) + "\n") wxs.write("\n") - - - diff --git a/packaging/wix/helpers.py b/packaging/wix/helpers.py index 5fe9e6a52..7bd706398 100644 --- a/packaging/wix/helpers.py +++ b/packaging/wix/helpers.py @@ -3,9 +3,11 @@ from __future__ import print_function import os +import re import sys -# check where to look for the inkscape files to bundle + +# check where to look for the Inkscape files to bundle # - btool builds used [root]/inkscape # - cmake builds use [root]/build/inkscape unless "DESTDIR" is specified def get_inkscape_dist_dir(): @@ -20,4 +22,40 @@ def get_inkscape_dist_dir(): if not os.path.isdir(sourcedir): print("could not find inkscape distribution files, please set environment variable 'INKSCAPE_DIST_PATH'") sys.exit(1) - return sourcedir \ No newline at end of file + return sourcedir + + +# get the full list of available Inkscape UI translations (by looking at available .po files in the /po directory) +def get_inkscape_locales(): + files = os.listdir('..\\..\\po') + po_files = [file for file in files if file.endswith('.po')] + locales = [po_file[0:-3] for po_file in po_files if po_file.endswith('.po')] + + return locales + + +# get the list of available Inkscape UI translations (by parsing inkscape-preferences.cpp) +def get_inkscape_locales_and_names(): + re_languages = re.compile(r'Glib::ustring languages\[\] = \{(.+?)\};', re.DOTALL) + re_langValues = re.compile(r'Glib::ustring langValues\[\] = \{(.+?)\};', re.DOTALL) + re_quotes = re.compile(r'"(.*?)"') + + # get the raw array contents from inkscape-preferences.cpp + with open('..\\..\\src\\ui\\dialog\\inkscape-preferences.cpp', 'r') as f: + languages = re.search(re_languages, f.read()) + f.seek(0) + langValues = re.search(re_langValues, f.read()) + + # split array elements and extract strings + if languages and langValues: + languages = languages.group(1).split(',') + langValues = langValues.group(1).split(',') + languages = [re.search(re_quotes, language).group(1) for language in languages] + langValues = [re.search(re_quotes, langValue).group(1) for langValue in langValues] + + # return the results as a dict (remove first element which is "System default") + if languages and langValues: + return dict(zip(langValues[1:], languages[1:])) + else: + print("Could not get the list of Inkscape translations from inkscape-preferences.cpp") + sys.exit(1) diff --git a/packaging/wix/inkscape.wxs b/packaging/wix/inkscape.wxs index 4766ec717..db055a46a 100644 --- a/packaging/wix/inkscape.wxs +++ b/packaging/wix/inkscape.wxs @@ -2,21 +2,21 @@ - + - - + + - - - + + + - - + @@ -47,60 +47,76 @@ - - - - - - + + - - - + + - - + - - + + - - - + + + - - + + + - - + + + + + + + - + + + + + - + -- cgit v1.2.3