|
1 #============================================================================ |
|
2 #Name : generate_iby_32.py |
|
3 #Part of : Helium |
|
4 |
|
5 #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
6 #All rights reserved. |
|
7 #This component and the accompanying materials are made available |
|
8 #under the terms of the License "Eclipse Public License v1.0" |
|
9 #which accompanies this distribution, and is available |
|
10 #at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
11 # |
|
12 #Initial Contributors: |
|
13 #Nokia Corporation - initial contribution. |
|
14 # |
|
15 #Contributors: |
|
16 # |
|
17 #Description: |
|
18 #=============================================================================== |
|
19 |
|
20 """ Helper script to generate S60 3.2 help IBY. |
|
21 """ |
|
22 import os |
|
23 import sys |
|
24 import re |
|
25 import optparse |
|
26 import logging |
|
27 import pathaddition.match |
|
28 |
|
29 logging.basicConfig() |
|
30 logger = logging.getLogger('integration.help32') |
|
31 logger.setLevel(logging.INFO) |
|
32 |
|
33 # Adding hiddenness testing function. |
|
34 try: |
|
35 import win32api |
|
36 import win32con |
|
37 USE_WIN32 = 1 |
|
38 except: |
|
39 USE_WIN32 = 0 |
|
40 |
|
41 def is_hidden(filename): |
|
42 """ Return True if a file is hidden, False otherwise. """ |
|
43 if USE_WIN32: |
|
44 try: |
|
45 if bool(win32api.GetFileAttributes(filename) & win32con.FILE_ATTRIBUTE_HIDDEN): |
|
46 return True |
|
47 except Exception, e: |
|
48 logger.error(e) |
|
49 else: |
|
50 if filename[0] == '.': |
|
51 return True |
|
52 return False |
|
53 |
|
54 class Basket: |
|
55 """ |
|
56 This class represents a basket which will contains the list of files |
|
57 that will be added the the IBY. |
|
58 """ |
|
59 def __init__(self, rootdir, tag='', excludes=None): |
|
60 if excludes is None: |
|
61 excludes = [] |
|
62 self.rootdir = rootdir |
|
63 self.common = [] |
|
64 self.language = {} |
|
65 self.tag = tag |
|
66 self.excludes = excludes |
|
67 self.content_scanner(rootdir) |
|
68 |
|
69 def add_content(self, filename, language): |
|
70 """ Add a file to the basket. """ |
|
71 if language == None: |
|
72 self.common.append(filename) |
|
73 else: |
|
74 if not self.language.has_key(language): |
|
75 self.language[language] = [] |
|
76 self.language[language].append(filename) |
|
77 |
|
78 def content_scanner(self, rootdir, path="", language=None): |
|
79 """ Parse the help delivery to get content. """ |
|
80 for name in os.listdir(rootdir): |
|
81 abspath = os.path.abspath(os.path.join(rootdir, name)) |
|
82 # Skipping hidden file and folders. |
|
83 if is_hidden(abspath): |
|
84 continue |
|
85 if name.startswith('.'): |
|
86 continue |
|
87 if os.path.isdir(abspath): |
|
88 logger.debug("Analysing directory: %s" % abspath) |
|
89 # only check language if it not yet found, found something that start with numbers |
|
90 if language == None and re.match(r'^\d+', name) != None: |
|
91 result = re.match(r'^(\d+)(?:%s)?$' % self.tag, name, re.I) |
|
92 if result != None: |
|
93 logger.debug("Language directory detected: %s" % name) |
|
94 self.content_scanner(abspath, os.path.join(path, name), result.group(1)) |
|
95 else: |
|
96 logger.info("Prunning %s directory, because it doesn't match %s tag." % (name, self.tag)) |
|
97 elif language == None: |
|
98 logger.debug("Directory considered a languageless %s" % name) |
|
99 self.content_scanner(abspath, os.path.join(path, name)) |
|
100 |
|
101 elif language != None: |
|
102 logger.debug("Adding directory %s to %s language" % (name, language)) |
|
103 self.content_scanner(abspath, os.path.join(path, name), language) |
|
104 else: |
|
105 if not self.__is_excluded(os.path.join(path, name)): |
|
106 logger.debug("Adding file %s to %s language" % (name, language)) |
|
107 self.add_content(os.path.join(path, name), language) |
|
108 else: |
|
109 logger.info("Excluding file %s" % (os.path.join(path, name))) |
|
110 |
|
111 |
|
112 def __is_excluded(self, filename): |
|
113 for exc in self.excludes: |
|
114 if pathaddition.match.ant_match(filename, exc, False): |
|
115 return True |
|
116 return False |
|
117 |
|
118 def generate_iby(self, ibyfilename, rootdest=None): |
|
119 """ Generates the IBY that should be included by the rom image creation process. """ |
|
120 if rootdest == None: |
|
121 rootdest = self.rootdir |
|
122 out = open(ibyfilename, "w") |
|
123 out.write("// Generated file please DO NOT MODIFY!\n") |
|
124 out.write("#ifndef __PRODUCT_HELPS__\n") |
|
125 out.write("#define __PRODUCT_HELPS__\n\n") |
|
126 out.write("\n//Common content.\n") |
|
127 for filename in self.common: |
|
128 out.write("data=%s RESOURCE_FILES_DIR\\%s\n" % (os.path.join(rootdest, filename), filename)) |
|
129 out.write("\n//Language specific content.\n") |
|
130 for language in self.language.keys(): |
|
131 # support EE language |
|
132 cond = "" |
|
133 if language == "01": |
|
134 cond = " || defined(__LOCALES_SC_IBY__)" |
|
135 |
|
136 out.write("#if defined(__LOCALES_%s_IBY__)%s\n" % (language, cond)) |
|
137 regex = re.compile(r"^(.*[\\/])?%s%s([\\/])" % (language, self.tag), re.I) |
|
138 for filename in self.language[language]: |
|
139 destfilename = regex.sub(r"\g<1>%s\g<2>" % language, filename, 1) |
|
140 out.write("data=%s RESOURCE_FILES_DIR\\%s\n" % (os.path.join(rootdest, filename), destfilename)) |
|
141 out.write("#endif // defined(__LOCALES_%s_IBY__)%s\n\n" % (language, cond)) |
|
142 out.write("#endif // __PRODUCT_HELPS__\n") |
|
143 |
|
144 def main(): |
|
145 """ Application entry point. """ |
|
146 parser = optparse.OptionParser() |
|
147 parser.add_option("-o", "--output", dest="output", |
|
148 help="Output filename", metavar="OUTPUT") |
|
149 parser.add_option("--rootdest", dest="rootdest", |
|
150 help="Root destintation directory", metavar="ROOTDEST") |
|
151 parser.add_option("-t", "--tag", dest="tag", |
|
152 help="Tag", metavar="TAG") |
|
153 parser.add_option("-e", "--exclude", dest="excludes", action="append", |
|
154 help="Exclude pattern", metavar="EXCLUDES") |
|
155 |
|
156 options = parser.parse_args()[0] |
|
157 logger.info("Setting output to '%s'" % options.output) |
|
158 ibyfilename = options.output |
|
159 |
|
160 rootdest = None |
|
161 if options.rootdest != None: |
|
162 logger.info("Setting rootdest to '%s'" % options.rootdest) |
|
163 rootdest = options.rootdest |
|
164 |
|
165 tag = '' |
|
166 if options.tag != None: |
|
167 logger.info("Setting tag to '%s'" % options.tag) |
|
168 tag = options.tag |
|
169 |
|
170 excludes = [] |
|
171 if options.excludes != None: |
|
172 excludes = options.excludes |
|
173 logger.info("Exclude patterns: [%s]" % (", ".join(excludes))) |
|
174 |
|
175 datadir = os.path.splitdrive(os.path.abspath("../data"))[1] |
|
176 basket = Basket(datadir, tag, excludes=excludes) |
|
177 basket.generate_iby(ibyfilename, rootdest) |
|
178 |
|
179 if __name__ == "__main__": |
|
180 main() |