|
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() |