bin/rom.py
changeset 8 02a1dd166f2b
child 9 a03989fb355a
equal deleted inserted replaced
7:2c88b93869a6 8:02a1dd166f2b
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 #
       
     4 # ============================================================================
       
     5 #  Name        : rom.py
       
     6 #  Part of     : Hb
       
     7 #  Description : Hb themes script for generating IBY files
       
     8 #  Version     : %version: %
       
     9 #
       
    10 #  Copyright (c) 2008-2010 Nokia.  All rights reserved.
       
    11 #  This material, including documentation and any related computer
       
    12 #  programs, is protected by copyright controlled by Nokia.  All
       
    13 #  rights are reserved.  Copying, including reproducing, storing,
       
    14 #  adapting or translating, any or all of this material requires the
       
    15 #  prior written consent of Nokia.  This material also contains
       
    16 #  confidential information which may not be disclosed to others
       
    17 #  without the prior written consent of Nokia.
       
    18 # ============================================================================
       
    19 
       
    20 import os
       
    21 import sys
       
    22 import fnmatch
       
    23 import zipfile
       
    24 import optparse
       
    25 import posixpath
       
    26 
       
    27 # ============================================================================
       
    28 # Globals
       
    29 # ============================================================================
       
    30 VERBOSE = False
       
    31 INCLUDE = None
       
    32 EXCLUDE = None
       
    33 INPUT_DIR = os.getcwd()
       
    34 OUTPUT_DIR = os.getcwd()
       
    35 SOURCE_PREFIX = "ZRESOURCE/hb/themes"
       
    36 TARGET_PREFIX = "RESOURCE_FILES_DIR/hb/themes"
       
    37 EXIT_STATUS = 0
       
    38 
       
    39 # ============================================================================
       
    40 # OptionParser
       
    41 # ============================================================================
       
    42 class OptionParser(optparse.OptionParser):
       
    43     def __init__(self):
       
    44         optparse.OptionParser.__init__(self)
       
    45         self.add_option("-v", "--verbose", action="store_true", dest="verbose",
       
    46                         help="print verbose information about each step of the sync process")
       
    47         self.add_option("-q", "--quiet", action="store_false", dest="verbose",
       
    48                         help="do not print information about each step of the sync process")
       
    49 
       
    50         group = optparse.OptionGroup(self, "Input/output options")
       
    51         group.add_option("-i", "--input", dest="input", metavar="dir",
       
    52                          help="specify the input <dir> (default %s)" % INPUT_DIR)
       
    53         group.add_option("-o", "--output", dest="output", metavar="dir",
       
    54                          help="specify the output <dir> (default %s)" % OUTPUT_DIR)
       
    55         group.add_option("--include", dest="include", action="append", metavar="pattern",
       
    56                          help="specify the include <pattern> (default %s)" % INCLUDE)
       
    57         group.add_option("--exclude", dest="exclude", action="append", metavar="pattern",
       
    58                          help="specify the exclude <pattern> (default %s)" % EXCLUDE)
       
    59         self.add_option_group(group)
       
    60 
       
    61         group = optparse.OptionGroup(self, "Prefix options")
       
    62         group.add_option("--source-prefix", dest="sourceprefix", metavar="prefix",
       
    63                          help="specify the source <prefix> (default %s)" % SOURCE_PREFIX)
       
    64         group.add_option("--target-prefix", dest="targetprefix", metavar="prefix",
       
    65                          help="specify the target <prefix> (default %s)" % TARGET_PREFIX)
       
    66         self.add_option_group(group)
       
    67 
       
    68 # ============================================================================
       
    69 # Utils
       
    70 # ============================================================================
       
    71 if not hasattr(os.path, "relpath"):
       
    72     def relpath(path, start=os.curdir):
       
    73         abspath = os.path.abspath(path)
       
    74         absstart = os.path.abspath(start)
       
    75         if abspath == absstart:
       
    76             return "."
       
    77         i = len(absstart)
       
    78         if not absstart.endswith(os.path.sep):
       
    79             i += len(os.path.sep)
       
    80         if not abspath.startswith(absstart):
       
    81             i = 0
       
    82         return abspath[i:]
       
    83     os.path.relpath = relpath
       
    84 
       
    85 def zip_filelist(filepath):
       
    86     files = list()
       
    87     archive = zipfile.ZipFile(filepath)
       
    88     for entry in archive.namelist():
       
    89         if not entry.endswith("/"):
       
    90             files.append(entry)
       
    91     return files
       
    92 
       
    93 class Theme:
       
    94     def __init__(self, name):
       
    95         self.name = name
       
    96         self.paths = []
       
    97         self.files = {}
       
    98         self.archives = {}
       
    99 
       
   100     def initialize(self):
       
   101         for path in self.paths:
       
   102             for root, dirs, files in os.walk(path):
       
   103                 for file in files:
       
   104                     filepath = posixpath.join(root, file).replace("\\", "/")
       
   105                     if self._include(filepath):
       
   106                         extension = os.path.splitext(filepath)[1]
       
   107                         if extension == ".zip":
       
   108                             if root not in self.archives:
       
   109                                 self.archives[root] = list()
       
   110                             self.archives[root].append(filepath)
       
   111                         else:
       
   112                             if root not in self.files:
       
   113                                 self.files[root] = list()
       
   114                             self.files[root].append(filepath)
       
   115 
       
   116     def write_iby(self, ibypath):
       
   117         global SOURCE_PREFIX, TARGET_PREFIX, EXIT_STATUS
       
   118         outpath = os.path.dirname(ibypath)
       
   119         if not os.path.exists(outpath):
       
   120             os.makedirs(outpath)
       
   121         out = open(ibypath, "w")
       
   122         out.write("#ifndef __%s_IBY__\n" % self.name.upper())
       
   123         out.write("#define __%s_IBY__\n" % self.name.upper())
       
   124         out.write("\n")
       
   125         out.write("#include <bldvariant.hrh>\n")
       
   126         out.write("\n")
       
   127         out.write("data=%s/%s.themeindex\t%s/%s.themeindex\n" % (SOURCE_PREFIX, self.name, TARGET_PREFIX, self.name))
       
   128         written_entries = list()
       
   129         for path, files in self.files.iteritems():
       
   130             relpath = os.path.relpath(path, INPUT_DIR).replace("\\", "/")
       
   131             for filepath in files:
       
   132                 filename = os.path.basename(filepath)
       
   133                 entry = posixpath.join(relpath, filename)
       
   134                 if entry not in written_entries:
       
   135                     written_entries.append(filepath)
       
   136                     out.write("data=%s/%s\t%s/%s\n" % (SOURCE_PREFIX, entry, TARGET_PREFIX, entry))
       
   137                 else:
       
   138                     print "ERROR: %s duplicate entry %s" % (ibypath, entry)
       
   139                     EXIT_STATUS = -1
       
   140         for path, archives in self.archives.iteritems():
       
   141             relpath = os.path.relpath(path, INPUT_DIR).replace("\\", "/")
       
   142             for archive in archives:
       
   143                 files = zip_filelist(archive)
       
   144                 for filepath in files:
       
   145                     entry = posixpath.join(relpath, filepath)
       
   146                     if entry not in written_entries:
       
   147                         written_entries.append(entry)
       
   148                         out.write("data=%s/%s\t%s/%s\n" % (SOURCE_PREFIX, entry, TARGET_PREFIX, entry))
       
   149                     else:
       
   150                         print "ERROR: %s duplicate entry %s" % (ibypath, entry)
       
   151                         EXIT_STATUS = -1
       
   152         out.write("\n")
       
   153         out.write("#endif __%s_IBY__\n" % self.name.upper())
       
   154         out.close()
       
   155 
       
   156     def _include(self, filepath):
       
   157         result = True
       
   158         if INCLUDE != None:
       
   159             for pattern in INCLUDE:
       
   160                 if not fnmatch.fnmatch(filepath, pattern):
       
   161                     result = False
       
   162         if EXCLUDE != None:
       
   163             for pattern in EXCLUDE:
       
   164                 if fnmatch.fnmatch(filepath, pattern):
       
   165                     result = False
       
   166         return result
       
   167 
       
   168 def lookup_themes(path):
       
   169     themes = {}
       
   170     if os.path.exists(path):
       
   171         # base: effects, icons...
       
   172         for base in os.listdir(path):
       
   173             basepath = posixpath.join(path, base)
       
   174             if os.path.isdir(basepath):
       
   175                 # theme: footheme, bartheme...
       
   176                 for theme in os.listdir(basepath):
       
   177                     themepath = posixpath.join(basepath, theme)
       
   178                     if os.path.isdir(themepath):
       
   179                         if theme not in themes:
       
   180                             themes[theme] = Theme(theme)
       
   181                         themes[theme].paths.append(themepath)
       
   182     return themes
       
   183 
       
   184 # ============================================================================
       
   185 # main()
       
   186 # ============================================================================
       
   187 def main():
       
   188     global VERBOSE, INPUT_DIR, OUTPUT_DIR, INCLUDE, EXCLUDE, SOURCE_PREFIX, TARGET_PREFIX
       
   189 
       
   190     parser = OptionParser()
       
   191     (options, args) = parser.parse_args()
       
   192 
       
   193     if options.verbose != None:
       
   194         VERBOSE = options.verbose
       
   195     if options.input != None:
       
   196         INPUT_DIR = options.input
       
   197     if options.output != None:
       
   198         OUTPUT_DIR = options.output
       
   199     if options.include != None:
       
   200         INCLUDE = options.include
       
   201     if options.exclude != None:
       
   202         EXCLUDE = options.exclude
       
   203     if options.sourceprefix != None:
       
   204         SOURCE_PREFIX = options.sourceprefix
       
   205     if options.targetprefix != None:
       
   206         TARGET_PREFIX = options.targetprefix
       
   207 
       
   208     themes = lookup_themes(INPUT_DIR)
       
   209     for name, theme in themes.iteritems():
       
   210         theme.initialize()
       
   211         print "Generating: %s.iby" % name
       
   212         theme.write_iby(posixpath.join(OUTPUT_DIR, "%s.iby" % name))
       
   213 
       
   214     return EXIT_STATUS
       
   215 
       
   216 if __name__ == "__main__":
       
   217     sys.exit(main())