diff -r 28e8d4c0e55e -r ee79fe77b3c7 bin/sync.py --- a/bin/sync.py Mon Apr 19 14:02:15 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,481 +0,0 @@ -# -# Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: Hb themes sync script -# - -import os -import re -import sys -import time -import shutil -import fnmatch -import zipfile -import optparse -import tempfile -if sys.version_info[0] == 2 and sys.version_info[1] < 4: - # for scratchbox compatibility - import popen2 -else: - import subprocess - -# ============================================================================ -# Globals -# ============================================================================ -VERBOSE = False -ARCHIVES = False -INCLUDE = None -EXCLUDE = None -INPUT_DIR = os.getcwd() -OUTPUT_DIR = os.getcwd() -IBY_SOURCE_PREFIX = "ZRESOURCE/hb/themes" -IBY_TARGET_PREFIX = "RESOURCE_FILES_DIR/hb/themes" -BLD_HW_TARGET_PREFIX = "/epoc32/data/z/resource/hb/themes" -BLD_EMU_TARGET_PREFIX = "/epoc32/winscw/c/resource/hb/themes" -BLD_TARGET_PREFIXES = [] -SYMBIAN = False -EXIT_STATUS = 0 -NAME = "themes" -THEME_COMMON = "themecommon" -THEME_SETTINGS_FILE = "theme.theme" -ENCODER = "SVGTBinEncode.exe" -NVG = False - -# ============================================================================ -# OptionParser -# ============================================================================ -class OptionParser(optparse.OptionParser): - def __init__(self): - optparse.OptionParser.__init__(self) - self.add_option("-v", "--verbose", action="store_true", dest="verbose", - help="print verbose information about each step of the sync process") - self.add_option("-q", "--quiet", action="store_false", dest="verbose", - help="do not print information about each step of the sync process") - self.add_option("-n", "--name", dest="name", metavar="name", - help="specify the package (default %s)" % NAME) - self.add_option("--symbian", action="store_true", dest="symbian", - help="work in Symbian mode") - self.add_option("--nvg", action="store_true", dest="nvg", - help="do convert svg to nvg") - self.add_option("--no-nvg", action="store_false", dest="nvg", - help="do not convert svg to nvg") - - group = optparse.OptionGroup(self, "Input/output options") - self.add_option("-i", "--input", dest="input", metavar="dir", - help="specify the input (default %s)" % INPUT_DIR) - self.add_option("-o", "--output", dest="output", metavar="dir", - help="specify the output (default %s)" % OUTPUT_DIR) - self.add_option("-a", "--archives", action="store_true", dest="archives", - help="export/install archives (default %s)" % ARCHIVES) - self.add_option("--include", dest="include", action="append", metavar="pattern", - help="specify the include (default %s)" % INCLUDE) - self.add_option("--exclude", dest="exclude", action="append", metavar="pattern", - help="specify the exclude (default %s)" % EXCLUDE) - self.add_option_group(group) - - group = optparse.OptionGroup(self, "Prefix options") - self.add_option("--iby-source-prefix", dest="ibysourceprefix", metavar="prefix", - help="specify the iby source (default %s)" % IBY_SOURCE_PREFIX) - self.add_option("--iby-target-prefix", dest="ibytargetprefix", metavar="prefix", - help="specify the iby target (default %s)" % IBY_TARGET_PREFIX) - self.add_option("--bld-hw-target-prefix", dest="bldhwtargetprefix", metavar="prefix", - help="specify the bld harware target (default %s)" % BLD_HW_TARGET_PREFIX) - self.add_option("--bld-emu-target-prefix", dest="bldemutargetprefix", metavar="prefix", - help="specify the bld emulator target (default %s)" % BLD_EMU_TARGET_PREFIX) - self.add_option("--bld-target-prefix", dest="bldtargetprefixes", action="append", metavar="prefix", - help="specify an additional bld target ") - self.add_option_group(group) - -# ============================================================================ -# Utils -# ============================================================================ -if not hasattr(os.path, "relpath"): - def relpath(path, start=os.curdir): - abspath = os.path.abspath(path) - absstart = os.path.abspath(start) - if abspath == absstart: - return "." - i = len(absstart) - if not absstart.endswith(os.path.sep): - i += len(os.path.sep) - if not abspath.startswith(absstart): - i = 0 - return abspath[i:] - os.path.relpath = relpath - -def run_process(command, cwd=None): - code = 0 - output = "" - try: - if cwd != None: - oldcwd = os.getcwd() - os.chdir(cwd) - if sys.version_info[0] == 2 and sys.version_info[1] < 4: - process = popen2.Popen4(command) - code = process.wait() - output = process.fromchild.read() - else: - process = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - (stdout, stderr) = process.communicate() - code = process.returncode - output = stdout + stderr - if cwd != None: - os.chdir(oldcwd) - except Exception, e: - print(e) - code = -1 - return [code, output] - -def make_target(path): - # generate a compatible make target name from path - target = os.path.splitdrive(path)[1].strip("\\/") - return "_".join(re.split("[\\\/]+", target)) - -class Theme: - def __init__(self, name): - self.name = name - self.paths = [] - self.files = {} - self.archives = {} - - def initialize(self): - for path in self.paths: - for root, dirs, files in os.walk(path): - for file in files: - filepath = os.path.join(root, file) - if self._include(filepath): - extension = os.path.splitext(filepath)[1] - if extension == ".zip": - if root not in self.archives: - self.archives[root] = list() - self.archives[root].append(filepath) - else: - if root not in self.files: - self.files[root] = list() - self.files[root].append(filepath) - - def _write_zip_entry(self, archive, filepath): - path, filename = os.path.split(filepath) - oldcwd = os.getcwd() - os.chdir(path) - archive.write(filename) - os.chdir(oldcwd) - - def encode(self): - print "Encoding: %s" % self.name - for path, archives in self.archives.iteritems(): - relpath = os.path.relpath(path, INPUT_DIR) - if not relpath.startswith("icons"): - continue - for archive in archives: - # ensure that output dir exists - outpath = os.path.join(OUTPUT_DIR, relpath) - if not os.path.exists(outpath): - os.makedirs(outpath) - - # extract to a temp dir - tempdir = tempfile.mkdtemp() - zip = zipfile.ZipFile(archive) - for name in zip.namelist(): - file = open(os.path.join(tempdir, name),'w') - file.write(zip.read(name)) - file.close() - - # convert & re-archive - total = 0 - converted = 0 - tmpfile, tmpfilepath = tempfile.mkstemp(".zip") - tmparchive = zipfile.ZipFile(tmpfilepath, 'w') - for root, dirs, files in os.walk(tempdir): - for file in files: - filepath = os.path.join(root, file) - basepath, extension = os.path.splitext(filepath) - if extension == ".svg": - total += 1 - res = run_process([ENCODER, "-v", "6", filepath, "-e", ".nvg"])[0] - exists = os.path.exists(basepath + ".nvg") - if not exists: - self._write_zip_entry(tmparchive, filepath) - else: - converted += 1 - self._write_zip_entry(tmparchive, basepath + ".nvg") - - # cleanup - tmparchive.close() - os.close(tmpfile) - if converted > 0: - shutil.move(tmpfilepath, os.path.join(outpath, os.path.basename(archive))) - else: - os.remove(tmpfilepath) - shutil.rmtree(tempdir, True) - print " %s (%s/%s)" % (os.path.join(relpath, os.path.basename(archive)), converted, total) - - def write_iby(self, ibypath): - global IBY_SOURCE_PREFIX, IBY_TARGET_PREFIX, EXIT_STATUS - outpath = os.path.dirname(ibypath) - if not os.path.exists(outpath): - os.makedirs(outpath) - out = open(ibypath, "w") - out.write("#ifndef __%s_IBY__\n" % self.name.upper()) - out.write("#define __%s_IBY__\n" % self.name.upper()) - out.write("\n") - out.write("#include \n") - out.write("\n") - out.write("data=%s/%s.themeindex\t%s/%s.themeindex\n" % (IBY_SOURCE_PREFIX, self.name, IBY_TARGET_PREFIX, self.name)) - written_entries = list() - for path, files in self.files.iteritems(): - relpath = os.path.relpath(path, INPUT_DIR) - for filepath in files: - filename = os.path.basename(filepath) - entry = os.path.join(relpath, filename) - if entry not in written_entries: - written_entries.append(filepath) - out.write("data=%s/%s\t%s/%s\n" % (IBY_SOURCE_PREFIX, entry, IBY_TARGET_PREFIX, entry)) - else: - print "ERROR: %s duplicate entry %s" % (ibypath, entry) - EXIT_STATUS = -1 - for path, archives in self.archives.iteritems(): - relpath = os.path.relpath(path, INPUT_DIR) - for archive in archives: - files = self._list_files(archive) - for filepath in files: - entry = os.path.join(relpath, filepath) - if entry not in written_entries: - written_entries.append(entry) - out.write("data=%s/%s\t%s/%s\n" % (IBY_SOURCE_PREFIX, entry, IBY_TARGET_PREFIX, entry)) - else: - print "ERROR: %s duplicate entry %s" % (ibypath, entry) - EXIT_STATUS = -1 - out.write("\n") - out.write("#endif __%s_IBY__\n" % self.name.upper()) - out.close() - - def _list_files(self, filepath): - files = list() - archive = zipfile.ZipFile(filepath) - for entry in archive.namelist(): - if not entry.endswith("/"): - files.append(entry) - return files - - def _include(self, filepath): - result = True - if INCLUDE != None: - for pattern in INCLUDE: - if not fnmatch.fnmatch(filepath, pattern): - result = False - if EXCLUDE != None: - for pattern in EXCLUDE: - if fnmatch.fnmatch(filepath, pattern): - result = False - return result - -def lookup_themes(path): - themes = {} - # base: effects, icons... - for base in os.listdir(path): - basepath = os.path.join(path, base) - if os.path.isdir(basepath): - # theme: footheme, bartheme... - for theme in os.listdir(basepath): - themepath = os.path.join(basepath, theme) - if os.path.isdir(themepath): - if theme not in themes: - themes[theme] = Theme(theme) - themes[theme].paths.append(themepath) - return themes - -def write_txt(filepath, themes, prefixes): - outpath = os.path.dirname(filepath) - if not os.path.exists(outpath): - os.makedirs(outpath) - out = open(filepath, "w") - for name, theme in themes.iteritems(): - for prefix in prefixes: - path = os.path.normpath("%s/icons/%s" % (prefix, name)) - out.write("%s %s %s\n" % (name, path, prefix)) - out.close() - -def write_pri(filepath, themes, settingsfile_exists): - outpath = os.path.dirname(filepath) - if not os.path.exists(outpath): - os.makedirs(outpath) - outpath = os.path.splitdrive(OUTPUT_DIR)[1] - out = open(filepath, "w") - out.write("symbian {\n") - out.write("\tBLD_INF_RULES.prj_exports += \"$${LITERAL_HASH}include \"\n") - # TODO: temp workaround to include pre-generated .themeindex files - rompath = os.path.join(os.getcwd(), "rom") - for entry in os.listdir(rompath): - filepath = os.path.join(rompath, entry) - if os.path.isfile(filepath) and os.path.splitext(filepath)[1] == ".themeindex": - filepath = os.path.splitdrive(filepath)[1] - filename = os.path.basename(filepath) - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (filepath, BLD_HW_TARGET_PREFIX, filename)) - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (filepath, BLD_EMU_TARGET_PREFIX, filename)) - - if settingsfile_exists: - # exporting theme settings file - settingsPath = os.path.splitdrive(os.path.join(INPUT_DIR,THEME_SETTINGS_FILE))[1] - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (settingsPath, BLD_HW_TARGET_PREFIX, THEME_SETTINGS_FILE)) - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (settingsPath, BLD_EMU_TARGET_PREFIX, THEME_SETTINGS_FILE)) - out.write("\tBLD_INF_RULES.prj_exports += \"%s.iby\tCORE_MW_LAYER_IBY_EXPORT_PATH(%s.iby)\"\n" % (os.path.join(outpath, THEME_COMMON), THEME_COMMON)) - - for name, theme in themes.iteritems(): - ibyfile = "%s.iby" % name - out.write("\tBLD_INF_RULES.prj_exports += \"%s\tCORE_MW_LAYER_IBY_EXPORT_PATH(%s)\"\n" % (os.path.join(outpath, ibyfile), ibyfile)) - for path, files in theme.files.iteritems(): - relpath = os.path.relpath(path, INPUT_DIR) - for filepath in files: - filepath = os.path.splitdrive(filepath)[1] - filename = os.path.basename(filepath) - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (filepath, BLD_HW_TARGET_PREFIX, os.path.join(relpath, filename))) - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (filepath, BLD_EMU_TARGET_PREFIX, os.path.join(relpath, filename))) - for path, archives in theme.archives.iteritems(): - relpath = os.path.relpath(path, INPUT_DIR) - for filepath in archives: - filepath = os.path.splitdrive(filepath)[1] - filename = os.path.basename(filepath) - if ARCHIVES: - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (filepath, BLD_HW_TARGET_PREFIX, os.path.join(relpath, filename))) - out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (filepath, BLD_EMU_TARGET_PREFIX, os.path.join(relpath, filename))) - else: - out.write("\tBLD_INF_RULES.prj_exports += \":zip %s\t%s/%s\"\n" % (filepath, BLD_HW_TARGET_PREFIX, relpath)) - out.write("\tBLD_INF_RULES.prj_exports += \":zip %s\t%s/%s\"\n" % (filepath, BLD_EMU_TARGET_PREFIX, relpath)) - out.write("} else {\n") - out.write("\tisEmpty(QMAKE_UNZIP):QMAKE_UNZIP = unzip -u -o\n") - - if settingsfile_exists: - # installing theme settings file - settingsPath = os.path.join(INPUT_DIR,THEME_SETTINGS_FILE) - out.write("\t%s.path += $$(HB_THEMES_DIR)/themes\n" % THEME_COMMON) - out.write("\t%s.files += %s\n" % (THEME_COMMON, settingsPath)) - out.write("\tINSTALLS += %s\n" % THEME_COMMON) - - for name, theme in themes.iteritems(): - for path, files in theme.files.iteritems(): - target = make_target(path) - relpath = os.path.relpath(path, INPUT_DIR) - out.write("\t%s.path += $$(HB_THEMES_DIR)/themes/%s\n" % (target, relpath)) - out.write("\t%s.files += %s\n" % (target, " ".join(files))) - out.write("\tINSTALLS += %s\n" % target) - for path, archives in theme.archives.iteritems(): - target = make_target(path) - relpath = os.path.relpath(path, INPUT_DIR) - out.write("\t%s_zip.path += $$(HB_THEMES_DIR)/themes/%s\n" % (target, relpath)) - if ARCHIVES: - out.write("\t%s_zip.files += %s\n" % (target, " ".join(archives))) - else: - commands = [] - for archive in archives: - commands.append("$$QMAKE_UNZIP %s -d $$(HB_THEMES_DIR)/themes/%s" % (archive, relpath)) - out.write("\t%s_zip.commands += %s\n" % (target, " && ".join(commands))) - out.write("\tINSTALLS += %s_zip\n" % target) - out.write("}\n") - out.close() - - -def write_common_iby(path): - global VERBOSE, IBY_SOURCE_PREFIX, IBY_TARGET_PREFIX, OUTPUT_DIR, INPUT_DIR - global THEME_COMMON, THEME_SETTINGS_FILE - - # Create iby file for theme.theme if it is there - theme_theme = os.path.join(INPUT_DIR,THEME_SETTINGS_FILE) - if os.path.isfile(theme_theme): - if VERBOSE: - print "Writing: %s.iby" % THEME_COMMON - ibypath = os.path.join(OUTPUT_DIR, THEME_COMMON + ".iby") - outpath = os.path.dirname(ibypath) - if not os.path.exists(outpath): - os.makedirs(outpath) - out = open(ibypath, "w") - out.write("#ifndef __%s_IBY__\n" % THEME_COMMON.upper()) - out.write("#define __%s_IBY__\n" % THEME_COMMON.upper()) - out.write("\n") - out.write("#include \n") - out.write("\n") - out.write("data=%s/%s\t%s/%s\n" % (IBY_SOURCE_PREFIX, THEME_SETTINGS_FILE, IBY_TARGET_PREFIX, THEME_SETTINGS_FILE)) - out.write("\n") - out.write("#endif __%s_IBY__\n" % THEME_COMMON.upper()) - return True - - # theme common iby not written, return false - return False - -# ============================================================================ -# main() -# ============================================================================ -def main(): - global VERBOSE, ARCHIVES, INPUT_DIR, OUTPUT_DIR, INCLUDE, EXCLUDE, SYMBIAN, NAME, NVG - global IBY_SOURCE_PREFIX, IBY_TARGET_PREFIX - global BLD_HW_TARGET_PREFIX, BLD_EMU_TARGET_PREFIX, BLD_TARGET_PREFIXES - - parser = OptionParser() - (options, args) = parser.parse_args() - - if options.verbose != None: - VERBOSE = options.verbose - if options.symbian != None: - SYMBIAN = options.symbian - if options.nvg != None: - NVG = options.nvg - if options.name != None: - NAME = options.name - if options.archives != None: - ARCHIVES = options.archives - if options.include != None: - INCLUDE = options.include - if options.exclude != None: - EXCLUDE = options.exclude - if options.input != None: - INPUT_DIR = options.input - if options.output != None: - OUTPUT_DIR = options.output - if options.ibysourceprefix != None: - IBY_SOURCE_PREFIX = options.ibysourceprefix - if options.ibytargetprefix != None: - IBY_TARGET_PREFIX = options.ibytargetprefix - if options.bldhwtargetprefix != None: - BLD_HW_TARGET_PREFIX = options.bldhwtargetprefix - if options.bldemutargetprefix != None: - BLD_EMU_TARGET_PREFIX = options.bldemutargetprefix - if options.bldtargetprefixes != None: - BLD_TARGET_PREFIXES = options.bldtargetprefixes - - settingsfile_exists = write_common_iby(INPUT_DIR) - - themes = lookup_themes(INPUT_DIR) - for name, theme in themes.iteritems(): - theme.initialize() - if SYMBIAN and NVG: - theme.encode() - if VERBOSE: - print "Writing: %s.iby" % name - theme.write_iby(os.path.join(OUTPUT_DIR, "%s.iby" % name)) - - if VERBOSE: - print "Writing: %s.pri" % NAME - write_pri(os.path.join(OUTPUT_DIR, "%s.pri" % NAME), themes, settingsfile_exists) - if VERBOSE: - print "Writing: %s.txt" % NAME - if SYMBIAN: - prefixes = [BLD_HW_TARGET_PREFIX, BLD_EMU_TARGET_PREFIX] - prefixes += BLD_TARGET_PREFIXES - write_txt(os.path.join(OUTPUT_DIR, "%s.txt" % NAME), themes, prefixes) - else: - write_txt(os.path.join(OUTPUT_DIR, "%s.txt" % NAME), themes, [os.path.join(os.environ["HB_THEMES_DIR"], "themes")]) - - return EXIT_STATUS - -if __name__ == "__main__": - sys.exit(main())