bin/sync.py
changeset 0 4ee42872ac7b
child 1 28e8d4c0e55e
equal deleted inserted replaced
-1:000000000000 0:4ee42872ac7b
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 #
       
     4 # ============================================================================
       
     5 #  Name        : sync.py
       
     6 #  Part of     : Hb
       
     7 #  Description : Hb themes sync script
       
     8 #  Version     : %version: 1 %
       
     9 #
       
    10 #  Copyright (c) 2008-2009 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 shutil
       
    22 import zipfile
       
    23 import optparse
       
    24 
       
    25 # ============================================================================
       
    26 # Globals
       
    27 # ============================================================================
       
    28 VERBOSE = False
       
    29 EXTRACT = False
       
    30 ARCHIVES = False
       
    31 INPUT_DIR = os.getcwd()
       
    32 OUTPUT_DIR = os.getcwd()
       
    33 IBY_SOURCE_PREFIX = "ZRESOURCE/hb/themes"
       
    34 IBY_TARGET_PREFIX = "RESOURCE_FILES_DIR/hb/themes"
       
    35 BLD_TARGET_PREFIX = "/epoc32/data/z/resource/hb/themes"
       
    36 BLD_2ND_TARGET_PREFIX = "/epoc32/winscw/c/resource/hb/themes"
       
    37 
       
    38 # ============================================================================
       
    39 # OptionParser
       
    40 # ============================================================================
       
    41 class OptionParser(optparse.OptionParser):
       
    42     def __init__(self):
       
    43         optparse.OptionParser.__init__(self)
       
    44         self.add_option("-v", "--verbose", action="store_true", dest="verbose",
       
    45                         help="print verbose information about each step of the sync process")
       
    46         self.add_option("-q", "--quiet", action="store_false", dest="verbose",
       
    47                         help="do not print information about each step of the sync process")
       
    48 
       
    49         group = optparse.OptionGroup(self, "Input/output options")
       
    50         self.add_option("-i", "--input", dest="input", metavar="dir",
       
    51                         help="specify the input <dir> (default %s)" % INPUT_DIR)
       
    52         self.add_option("-o", "--output", dest="output", metavar="dir",
       
    53                         help="specify the output <dir> (default %s)" % OUTPUT_DIR)
       
    54         self.add_option("-e", "--extract", action="store_true", dest="extract",
       
    55                         help="extract archives for installation (default %s)" % EXTRACT)
       
    56         self.add_option("-a", "--archives", action="store_true", dest="archives",
       
    57                         help="export/install archives (default %s)" % ARCHIVES)
       
    58         self.add_option_group(group)
       
    59 
       
    60         group = optparse.OptionGroup(self, "Prefix options")
       
    61         self.add_option("--iby-source-prefix", dest="ibysourceprefix", metavar="prefix",
       
    62                         help="specify the iby source <prefix> (default %s)" % IBY_SOURCE_PREFIX)
       
    63         self.add_option("--iby-target-prefix", dest="ibytargetprefix", metavar="prefix",
       
    64                         help="specify the iby target <prefix> (default %s)" % IBY_TARGET_PREFIX)
       
    65         self.add_option("--bld-target-prefix", dest="bldtargetprefix", metavar="prefix",
       
    66                         help="specify the bld target <prefix> (default %s)" % BLD_TARGET_PREFIX)
       
    67         self.add_option_group(group)
       
    68 
       
    69 # ============================================================================
       
    70 # Utils
       
    71 # ============================================================================
       
    72 if not hasattr(os.path, "relpath"):
       
    73     def relpath(path, start=os.curdir):
       
    74         abspath = os.path.abspath(path)
       
    75         absstart = os.path.abspath(start)
       
    76         if abspath == absstart:
       
    77             return "."
       
    78         i = len(absstart)
       
    79         if not absstart.endswith(os.path.sep):
       
    80             i += len(os.path.sep)
       
    81         if not abspath.startswith(absstart):
       
    82             i = 0
       
    83         return abspath[i:]
       
    84     os.path.relpath = relpath
       
    85 
       
    86 def extract(path, filepath):
       
    87     if not os.path.exists(path):
       
    88         os.makedirs(path)
       
    89     
       
    90     files = list()
       
    91     if VERBOSE:
       
    92         if EXTRACT:
       
    93             print "Extracting: %s" % filepath
       
    94         else:
       
    95             print "Reading: %s" % filepath
       
    96     archive = zipfile.ZipFile(filepath)
       
    97     for entry in archive.namelist():
       
    98         if entry.endswith("/"):
       
    99             if EXTRACT:
       
   100                 out = os.path.join(path, entry)
       
   101                 if not os.path.exists(out):
       
   102                     os.makedirs(out)
       
   103         else:
       
   104             files.append(entry)
       
   105             if EXTRACT:
       
   106                 out = open(os.path.join(path, entry), "w")
       
   107                 out.write(archive.read(entry))
       
   108                 out.close()
       
   109     return files
       
   110 
       
   111 class Theme:
       
   112     def __init__(self, name):
       
   113         self.name = name
       
   114         self.paths = []
       
   115         self.archives = []
       
   116         self.verbatims = []
       
   117         self.sources = {}
       
   118         self.targets = {}
       
   119 
       
   120     def initialize(self):
       
   121         for path in self.paths:
       
   122             for root, dirs, files in os.walk(path):
       
   123                 for file in files:
       
   124                     filepath = os.path.join(root, file)
       
   125                     extension = os.path.splitext(filepath)[1]
       
   126                     if os.path.isfile(filepath) and extension == ".zip":
       
   127                         self.archives.append(filepath)
       
   128                     if os.path.isfile(filepath) and (extension in ['.css', '.theme']):
       
   129                         self.verbatims.append(filepath)
       
   130                         if VERBOSE:
       
   131                             print "Found: %s" % filepath
       
   132         for archive in self.archives:
       
   133             path = os.path.dirname(archive)
       
   134             if path not in self.sources:
       
   135                 self.sources[path] = list()
       
   136             self.sources[path] += extract(path, archive)
       
   137         for verbatim in self.verbatims:
       
   138             path = os.path.dirname(verbatim)
       
   139             if path not in self.sources:
       
   140                 self.sources[path] = list()
       
   141             file = os.path.split(verbatim)[1]
       
   142             filelist = list()
       
   143             filelist.append(file)
       
   144             self.sources[path] += filelist
       
   145         for path, files in self.sources.iteritems():
       
   146             relpath = os.path.relpath(path, INPUT_DIR)
       
   147             if relpath not in self.targets:
       
   148                 self.targets[relpath] = list()
       
   149             self.targets[relpath] = files
       
   150 
       
   151     def write_iby(self, filepath):
       
   152         global IBY_SOURCE_PREFIX, IBY_TARGET_PREFIX
       
   153         out = open(filepath, "w")
       
   154         out.write("#ifndef __%s_IBY__\n" % self.name.upper())
       
   155         out.write("#define __%s_IBY__\n" % self.name.upper())
       
   156         out.write("\n")
       
   157         out.write("#include <bldvariant.hrh>\n")
       
   158         out.write("\n")
       
   159         for path, entries in self.targets.iteritems():
       
   160             for entry in entries:
       
   161                 entry = os.path.join(path, entry)
       
   162                 out.write("data=%s/%s\t%s/%s\n" % (IBY_SOURCE_PREFIX, entry, IBY_TARGET_PREFIX, entry))
       
   163         out.write("\n")
       
   164         out.write("#endif __%s_IBY__\n" % self.name.upper())
       
   165         out.close()
       
   166 
       
   167 def lookup_themes(path):
       
   168     themes = {}
       
   169     # base: effects, icons...
       
   170     for base in os.listdir(path):
       
   171         basepath = os.path.join(path, base)
       
   172         if os.path.isdir(basepath):
       
   173             # theme: footheme, bartheme...
       
   174             for theme in os.listdir(basepath):
       
   175                 themepath = os.path.join(basepath, theme)
       
   176                 if os.path.isdir(themepath):
       
   177                     if theme not in themes:
       
   178                         themes[theme] = Theme(theme)
       
   179                     themes[theme].paths.append(themepath)
       
   180     return themes
       
   181 
       
   182 def write_pri(filepath, themes):
       
   183     out = open(filepath, "w")
       
   184     out.write("symbian {\n")
       
   185     out.write("\tBLD_INF_RULES.prj_exports += \"$${LITERAL_HASH}include <platform_paths.hrh>\"\n")
       
   186     for name, theme in themes.iteritems():
       
   187         ibyfile = "%s.iby" % name
       
   188         out.write("\tBLD_INF_RULES.prj_exports += \"%s\tCORE_MW_LAYER_IBY_EXPORT_PATH(%s)\"\n" % (ibyfile, ibyfile))
       
   189         for verbatim in theme.verbatims:
       
   190             filename = os.path.basename(verbatim)
       
   191             relpath = os.path.relpath(os.path.dirname(verbatim), INPUT_DIR)
       
   192             verbatim = os.path.splitdrive(verbatim)[1]
       
   193             out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (verbatim, BLD_TARGET_PREFIX, os.path.join(relpath, filename)))
       
   194             out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (verbatim, BLD_2ND_TARGET_PREFIX, os.path.join(relpath, filename)))
       
   195         for archive in theme.archives:
       
   196             filename = os.path.basename(archive)
       
   197             relpath = os.path.relpath(os.path.dirname(archive), INPUT_DIR)
       
   198             archive = os.path.splitdrive(archive)[1]
       
   199             if ARCHIVES:
       
   200                 out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (archive, BLD_TARGET_PREFIX, os.path.join(relpath, filename)))
       
   201                 out.write("\tBLD_INF_RULES.prj_exports += \"%s\t%s/%s\"\n" % (archive, BLD_2ND_TARGET_PREFIX, os.path.join(relpath, filename)))
       
   202             else:
       
   203                 out.write("\tBLD_INF_RULES.prj_exports += \":zip %s\t%s/%s\"\n" % (archive, BLD_TARGET_PREFIX, relpath))
       
   204                 out.write("\tBLD_INF_RULES.prj_exports += \":zip %s\t%s/%s\"\n" % (archive, BLD_2ND_TARGET_PREFIX, relpath))
       
   205     out.write("} else {\n")
       
   206     for name, theme in themes.iteritems():
       
   207         if ARCHIVES:
       
   208             i = 1
       
   209             for archive in theme.archives:
       
   210                 relpath = os.path.relpath(os.path.dirname(archive), INPUT_DIR)
       
   211                 out.write("\t%s%i.path = $$(HB_THEMES_DIR)/themes/%s\n" % (name, i, relpath))
       
   212                 out.write("\t%s%i.files += %s\n" % (name, i, archive))
       
   213                 out.write("\tINSTALLS += %s%i\n" % (name, i))
       
   214                 i += 1
       
   215         else:
       
   216             i = 1
       
   217             for path, files in theme.sources.iteritems():
       
   218                 relpath = os.path.relpath(path, INPUT_DIR)
       
   219                 out.write("\t%s%i.path = $$(HB_THEMES_DIR)/themes/%s\n" % (name, i, relpath))
       
   220                 for file in files:
       
   221                     out.write("\t%s%i.files += %s\n" % (name, i, os.path.join(path, file)))
       
   222                 out.write("\tINSTALLS += %s%i\n" % (name, i))
       
   223                 i += 1
       
   224     out.write("}\n")
       
   225     out.close()
       
   226 
       
   227 # ============================================================================
       
   228 # main()
       
   229 # ============================================================================
       
   230 def main():
       
   231     global VERBOSE, EXTRACT, ARCHIVES, INPUT_DIR, OUTPUT_DIR
       
   232     global IBY_SOURCE_PREFIX, IBY_TARGET_PREFIX, BLD_TARGET_PREFIX
       
   233 
       
   234     parser = OptionParser()
       
   235     (options, args) = parser.parse_args()
       
   236 
       
   237     if options.verbose:
       
   238         VERBOSE = options.verbose
       
   239     if options.extract:
       
   240         EXTRACT = options.extract
       
   241     if options.archives:
       
   242         ARCHIVES = options.archives
       
   243     if options.input:
       
   244         INPUT_DIR = options.input
       
   245     if options.output:
       
   246         OUTPUT_DIR = options.output
       
   247     if options.ibysourceprefix:
       
   248         IBY_SOURCE_PREFIX = options.ibysourceprefix
       
   249     if options.ibytargetprefix:
       
   250         IBY_TARGET_PREFIX = options.ibytargetprefix
       
   251     if options.bldtargetprefix:
       
   252         BLD_TARGET_PREFIX = options.bldtargetprefix
       
   253 
       
   254     themes = lookup_themes(INPUT_DIR)
       
   255     for name, theme in themes.iteritems():
       
   256         theme.initialize()
       
   257         if VERBOSE:
       
   258             print "Writing: %s.iby" % name
       
   259         theme.write_iby(os.path.join(OUTPUT_DIR, "%s.iby" % name))
       
   260 
       
   261     if VERBOSE:
       
   262         print "Writing: themes.pri"
       
   263     write_pri(os.path.join(OUTPUT_DIR, "themes.pri"), themes)
       
   264 
       
   265 if __name__ == "__main__":
       
   266     main()