#!/usr/bin/env python# -*- coding: utf-8 -*-## ============================================================================# Name : rom.py# Part of : Hb# Description : Hb themes script for generating IBY files# Version : %version: %## Copyright (c) 2008-2010 Nokia. All rights reserved.# This material, including documentation and any related computer# programs, is protected by copyright controlled by Nokia. All# rights are reserved. Copying, including reproducing, storing,# adapting or translating, any or all of this material requires the# prior written consent of Nokia. This material also contains# confidential information which may not be disclosed to others# without the prior written consent of Nokia.# ============================================================================import osimport sysimport fnmatchimport zipfileimport optparseimport posixpathimport ConfigParser# ============================================================================# Globals# ============================================================================VERBOSE = FalseINCLUDE = NoneEXCLUDE = NoneINPUT_DIR = os.getcwd()OUTPUT_DIR = os.getcwd()SOURCE_PREFIX = "ZRESOURCE/hb/themes"TARGET_PREFIX = "RESOURCE_FILES_DIR/hb/themes"EXIT_STATUS = 0# ============================================================================# 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") group = optparse.OptionGroup(self, "Input/output options") group.add_option("-i", "--input", dest="input", metavar="dir", help="specify the input <dir> (default %s)" % INPUT_DIR) group.add_option("-o", "--output", dest="output", metavar="dir", help="specify the output <dir> (default %s)" % OUTPUT_DIR) group.add_option("--include", dest="include", action="append", metavar="pattern", help="specify the include <pattern> (default %s)" % INCLUDE) group.add_option("--exclude", dest="exclude", action="append", metavar="pattern", help="specify the exclude <pattern> (default %s)" % EXCLUDE) self.add_option_group(group) group = optparse.OptionGroup(self, "Prefix options") group.add_option("--source-prefix", dest="sourceprefix", metavar="prefix", help="specify the source <prefix> (default %s)" % SOURCE_PREFIX) group.add_option("--target-prefix", dest="targetprefix", metavar="prefix", help="specify the target <prefix> (default %s)" % TARGET_PREFIX) 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 = relpathdef zip_filelist(filepath): files = list() archive = zipfile.ZipFile(filepath) for entry in archive.namelist(): if not entry.endswith("/"): files.append(entry) return filesclass Theme: def __init__(self, name): self.name = name self.paths = [] self.files = {} self.archives = {} def add_file(self, filepath): if self._include(filepath): filepath = filepath.replace("\\", "/") path = os.path.split(filepath)[0] extension = os.path.splitext(filepath)[1] if extension == ".zip": if path not in self.archives: self.archives[path] = list() if filepath not in self.archives[path]: self.archives[path].append(filepath) else: if path not in self.files: self.files[path] = list() if filepath not in self.files[path]: self.files[path].append(filepath) def initialize(self): for path in self.paths: for root, dirs, files in os.walk(path): for file in files: self.add_file(os.path.join(root, file)) def write_iby(self, ibypath): global SOURCE_PREFIX, 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 <bldvariant.hrh>\n") out.write("\n") out.write("data=%s/%s.themeindex\t%s/%s.themeindex\n" % (SOURCE_PREFIX, self.name, TARGET_PREFIX, self.name)) written_entries = list() for path, files in self.files.iteritems(): relpath = os.path.relpath(path, INPUT_DIR).replace("\\", "/") for filepath in files: filename = os.path.basename(filepath) entry = posixpath.join(relpath, filename) if entry not in written_entries: written_entries.append(filepath) out.write("data=%s/%s\t%s/%s\n" % (SOURCE_PREFIX, entry, 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).replace("\\", "/") for archive in archives: files = zip_filelist(archive) for filepath in files: entry = posixpath.join(relpath, filepath) if entry not in written_entries: written_entries.append(entry) out.write("data=%s/%s\t%s/%s\n" % (SOURCE_PREFIX, entry, 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 write_thx(self, thxpath): global SOURCE_PREFIX, TARGET_PREFIX, EXIT_STATUS outpath = os.path.dirname(thxpath) if not os.path.exists(outpath): os.makedirs(outpath) archive = zipfile.ZipFile(thxpath, "w") os.chdir(INPUT_DIR) written_entries = list() for path, files in self.files.iteritems(): relpath = os.path.relpath(path, INPUT_DIR).replace("\\", "/") for filepath in files: filename = os.path.basename(filepath) entry = posixpath.join(relpath, filename) if entry not in written_entries: written_entries.append(entry) archive.write(entry) else: print "ERROR: %s duplicate entry %s" % (thxpath, entry) EXIT_STATUS = -1 archive.close() def hidden(self): result = False config = ConfigParser.ConfigParser() indexthemepath = INPUT_DIR + '/icons/' + self.name + '/index.theme' if os.path.exists(indexthemepath): config.read(indexthemepath) result = config.getboolean('Icon Theme', 'Hidden') return result 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 resultdef lookup_themes(path): themes = {} if os.path.exists(path): # base: effects, icons... for base in os.listdir(path): basepath = posixpath.join(path, base) if os.path.isdir(basepath): # theme: footheme, bartheme... for theme in os.listdir(basepath): themepath = posixpath.join(basepath, theme) if os.path.isdir(themepath): if theme not in themes: themes[theme] = Theme(theme) themes[theme].paths.append(themepath) # special case: themeindex themeindex = os.path.join(path, theme + ".themeindex") if os.path.exists(themeindex): themes[theme].add_file(themeindex) return themes# ============================================================================# main()# ============================================================================def main(): global VERBOSE, INPUT_DIR, OUTPUT_DIR, INCLUDE, EXCLUDE, SOURCE_PREFIX, TARGET_PREFIX parser = OptionParser() (options, args) = parser.parse_args() if options.verbose != None: VERBOSE = options.verbose if options.input != None: INPUT_DIR = options.input if options.output != None: OUTPUT_DIR = options.output if options.include != None: INCLUDE = options.include if options.exclude != None: EXCLUDE = options.exclude if options.sourceprefix != None: SOURCE_PREFIX = options.sourceprefix if options.targetprefix != None: TARGET_PREFIX = options.targetprefix themes = lookup_themes(INPUT_DIR) for name, theme in themes.iteritems(): theme.initialize() if theme.hidden(): print "Generating: %s.iby" % name theme.write_iby(posixpath.join(OUTPUT_DIR, "%s.iby" % name)) else: print "Generating: %s.thx" % name theme.write_thx(posixpath.join(OUTPUT_DIR, "%s.thx" % name)) return EXIT_STATUSif __name__ == "__main__": sys.exit(main())