|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # Helper script for running CentRepConv.exe to convert .txt files to |
|
16 # .cre files. The script is given a drive where an S60 environment is |
|
17 # substed and it handles all necessary input/output file moving and |
|
18 # command running to do the conversion. |
|
19 # |
|
20 # The .txt files for which the conversion fails are reported at the end |
|
21 # of the conversion. |
|
22 # |
|
23 |
|
24 import sys, os, subprocess, shutil, re |
|
25 import logging |
|
26 from optparse import OptionParser, OptionGroup |
|
27 |
|
28 log = logging.getLogger() |
|
29 |
|
30 # Paths to the temporary directories on the environment level |
|
31 TEMP_INPUT_DIR = r'\epoc32\WINSCW\C\cenrepconv_temp\input' |
|
32 TEMP_OUTPUT_DIR = r'\epoc32\WINSCW\C\cenrepconv_temp\output' |
|
33 |
|
34 # The same temporary directories in the form the emulator sees them |
|
35 TEMP_INPUT_DIR_EMULATOR = r'C:\cenrepconv_temp\input' |
|
36 TEMP_OUTPUT_DIR_EMULATOR = r'C:\cenrepconv_temp\output' |
|
37 |
|
38 def recreate_dir(dir): |
|
39 if os.path.exists(dir): |
|
40 shutil.rmtree(dir) |
|
41 os.makedirs(dir) |
|
42 |
|
43 def find_cenrep_txt_files(dir): |
|
44 """ |
|
45 Find all CenRep txt files in the given directory. |
|
46 @return: List of absolute paths to the files. |
|
47 """ |
|
48 pattern = re.compile(r'^[a-fA-F0-9]{8}\.txt$') |
|
49 dir = os.path.abspath(dir) |
|
50 |
|
51 result = [] |
|
52 for root, dirs, files in os.walk(dir): |
|
53 for file in files: |
|
54 if pattern.match(file) is not None: |
|
55 result.append(os.path.join(root, file)) |
|
56 return result |
|
57 |
|
58 def convert_txt_to_cre(file_path, output_dir): |
|
59 """ |
|
60 Convert a CenRep .txt file into a .cre file using CentRepConv.exe. |
|
61 @param file_path: Path to the .txt file. |
|
62 @param output_dir: Directory where the resulting .cre file will be copied. |
|
63 If None, the output file will not be copied anywhere. |
|
64 @return: True if conversion was OK and the corresponding .cre file was |
|
65 created, False if not. |
|
66 """ |
|
67 output_dir = os.path.abspath(output_dir) |
|
68 file_path = os.path.abspath(file_path) |
|
69 filename = os.path.basename(file_path) |
|
70 filename_out = filename[:-4] + '.cre' |
|
71 |
|
72 # Copy the input file into place |
|
73 temp_input_file = os.path.join(TEMP_INPUT_DIR, filename) |
|
74 shutil.copy2(file_path, temp_input_file) |
|
75 |
|
76 # Run the conversion |
|
77 cmd = r'\epoc32\release\WINSCW\udeb\centrepconv.exe -dNoGui -dtextshell -Mconsole -- -o %s %s' \ |
|
78 % (os.path.join(TEMP_OUTPUT_DIR_EMULATOR, filename_out), os.path.join(TEMP_INPUT_DIR_EMULATOR, filename)) |
|
79 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) |
|
80 out, err = p.communicate() |
|
81 if p.returncode != 0: |
|
82 log.debug("Failed to execute command: %s" % cmd) |
|
83 log.debug("Command output:\n%s", out) |
|
84 return False |
|
85 |
|
86 temp_output_file = os.path.join(TEMP_OUTPUT_DIR, filename_out) |
|
87 if not os.path.exists(temp_output_file): |
|
88 log.debug("Expected output file '%s' does not exist" % temp_output_file) |
|
89 return False |
|
90 |
|
91 # Copy to output if necessary |
|
92 if output_dir: |
|
93 if not os.path.exists(output_dir): |
|
94 os.makedirs(output_dir) |
|
95 output_file = os.path.join(output_dir, os.path.basename(temp_output_file)) |
|
96 log.debug("Copying output file to '%s'" % output_file) |
|
97 shutil.copy2(temp_output_file, output_file) |
|
98 |
|
99 log.debug("Removing temp output file '%s'" % temp_output_file) |
|
100 os.remove(temp_output_file) |
|
101 return True |
|
102 |
|
103 def main(): |
|
104 parser = OptionParser() |
|
105 |
|
106 parser.add_option("--env-drive", |
|
107 help="Specifies the drive where the S60 environment containing CentRepConv.exe is located. Note that the drive needs to be writable, since input/output files need to be moved there in order to make the conversion work. Example: 'X:'", |
|
108 metavar="DRIVE") |
|
109 |
|
110 parser.add_option("--input-file", |
|
111 help="Specifies a single CenRep .txt file to convert.", |
|
112 metavar="FILE") |
|
113 |
|
114 parser.add_option("--input-dir", |
|
115 help="Specifies a directory containing the CenRep .txt files to convert. Only CenRep .txt files converted.", |
|
116 metavar="FILE") |
|
117 |
|
118 parser.add_option("--output", |
|
119 help="The directory where the resulting .cre files are generated", |
|
120 metavar="DIR") |
|
121 |
|
122 parser.add_option("--validate", |
|
123 action="store_true", |
|
124 help="Don't copy output files to --output, only check if a .cre file is generated for each .txt file.", |
|
125 default=False) |
|
126 |
|
127 parser.add_option("-v", "--verbose", |
|
128 action="store_true", |
|
129 help="Show debug information", |
|
130 default=False) |
|
131 |
|
132 (options, args) = parser.parse_args() |
|
133 |
|
134 if not options.env_drive: |
|
135 parser.error("--env-drive must be specified") |
|
136 if re.match('^[A-Za-z]:$', options.env_drive) is None: |
|
137 parser.error("Invalid --env-drive '%s', should be e.g. 'X:'" % options.env_drive) |
|
138 if not os.path.exists(options.env_drive): |
|
139 parser.error("Specified --env-drive '%s' does not exist" % options.env_drive) |
|
140 |
|
141 if not options.input_file and not options.input_dir: |
|
142 parser.error("--input-file or --input-dir must be specified") |
|
143 if options.input_file and options.input_dir: |
|
144 parser.error("Only one for --input-file and --input-dir may be specified") |
|
145 if options.input_file and not os.path.isfile(options.input_file): |
|
146 parser.error("Specified --input-file does not exist or is not a file") |
|
147 if options.input_dir and not os.path.isdir(options.input_dir): |
|
148 parser.error("Specified --input-dir does not exist or is not a directory") |
|
149 |
|
150 if not options.output and not options.validate: |
|
151 parser.error("Either --output or --validate must be specified") |
|
152 |
|
153 if options.verbose: log_level = logging.DEBUG |
|
154 else: log_level = logging.INFO |
|
155 logging.basicConfig(format="%(levelname)-8s: %(message)s", stream=sys.stdout, level=log_level) |
|
156 |
|
157 if options.output: output_dir = os.path.abspath(options.output) |
|
158 else: output_dir = None |
|
159 |
|
160 # Find input files |
|
161 log.info("Determining input files") |
|
162 if options.input_file: |
|
163 input_files = [os.path.abspath(options.input_file)] |
|
164 else: |
|
165 input_files = find_cenrep_txt_files(options.input_dir) |
|
166 log.info("%d input file(s)" % len(input_files)) |
|
167 |
|
168 if len(input_files) == 0: |
|
169 log.info("No input files") |
|
170 return |
|
171 |
|
172 log.debug("Changing working directory to '%s'" % options.env_drive) |
|
173 os.chdir(options.env_drive) |
|
174 |
|
175 log.debug("Creating/cleaning temporary output directory '%s'" % TEMP_OUTPUT_DIR) |
|
176 recreate_dir(TEMP_OUTPUT_DIR) |
|
177 log.debug("Creating/cleaning temporary input directory '%s'" % TEMP_INPUT_DIR) |
|
178 recreate_dir(TEMP_INPUT_DIR) |
|
179 |
|
180 log.info("Running conversion") |
|
181 failed_files = [] |
|
182 PROGRESS_STEP_PERCENTAGE = 5.0 |
|
183 ratio = 100.0 / float(len(input_files)) |
|
184 last_percentage = 0 |
|
185 for i, file in enumerate(input_files): |
|
186 percentage = ratio * float(i) |
|
187 if percentage - last_percentage > PROGRESS_STEP_PERCENTAGE: |
|
188 log.info("%d%%" % percentage) |
|
189 last_percentage = percentage |
|
190 |
|
191 log.debug("Converting '%s'" % file) |
|
192 ok = convert_txt_to_cre(file, output_dir) |
|
193 if not ok: |
|
194 log.debug("Conversion of '%s' failed" % file) |
|
195 failed_files.append(file) |
|
196 |
|
197 if failed_files: |
|
198 print "Conversion failed for %d file(s)" % len(failed_files) |
|
199 prefix = os.path.commonprefix(failed_files) |
|
200 print "Common prefix: %s" % prefix |
|
201 for file in failed_files: |
|
202 print file[len(prefix):] |
|
203 |
|
204 if __name__ == "__main__": |
|
205 main() |