1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20#************************************************************** 21 22from optparse import OptionParser 23from sdf import SdfData 24from pseudo import PseudoSet 25 26import sys 27import os 28import shutil 29 30class AbstractL10nTool: 31 _options = {} 32 _args = "" 33 _resource_type = "" 34 _source_language = "en-US" 35 36 ##### Implement these abstract methods 37 38 ##### Nameing scheme for the output files 39 def get_outputfile_format_str(self): 40 # filename,fileNoExt,language,extension,pathPrefix,pathPostFix,path 41 #return "{path}/{fileNoExt}_{language}.{extension}" 42 return self._options.pattern 43 44 ################################# Merge single files ########################################### 45 46 ##### Merge a single file 47 def merge_file(self, inputfilename, outputfilename, parsed_file_ref, lang, is_forced_lang, sdfdata): 48 pass 49 50 ##### Helper for parse-once-use-often like parsing a xml file is needed implement it here 51 def parse_file(self, filename): 52 return None 53 54 ################### Merge one big file containing all strings in all languages ################# 55 def merge_one_big_file(self, inputfile, outputfilename, parsed_file_ref, lang, sdfdata): 56 pass 57 58 ################### Extract a single File ###################################################### 59 def extract_file(self, inputfile): 60 pass 61 62 ################################################################################################ 63 64 def format_outputfile(self, filename, language): 65 extension = filename[filename.rfind('.')+1:] 66 file = filename[:filename.rfind('.')] 67 # Python 2.3.x friendly 68 return self.get_outputfile_format_str().replace('[', '%(').replace(']',')s') % \ 69 { 'filename': filename, 'fileNoExt': file, 'language': language, 'extension': extension, 'path_prefix': self._options.path_prefix, 70 'path_postfix': self._options.path_postfix, 'path': self.get_path() } 71 72 #return self.get_outputfile_format_str().replace('[', '{').replace(']','}').format( 73 # filename=filename, fileNoExt=file, language=language, extension=extension, path_prefix=self._options.path_prefix, 74 # path_postfix=self._options.path_postfix, path=self.get_path()) 75 76 def get_path(self): 77 if self._options.outputfile.find('/') == -1: 78 return "" 79 else: 80 return self._options.outputfile[:self._options.outputfile.rfind('/')] 81 82 def merge(self, sdfdata): 83 langset,forcedset, foundset = PseudoSet(), PseudoSet() , PseudoSet() 84 85 if self._options.languages: 86 langset = PseudoSet(self._options.languages) 87 if self._options.forcedlanguages: 88 forcedset = PseudoSet(self._options.forcedlanguages) 89 if sdfdata.get_languages_found_in_sdf(): 90 foundset = sdfdata.get_languages_found_in_sdf() 91 92 if self.has_multi_inputfiles(): 93 filelist = self.read_inputfile_list() 94 else: 95 filelist = self._options.inputfile 96 97 for inputfile in filelist: 98 ref = self.parse_file(inputfile) 99 # Don't write that files if there is no l10n present 100 if ((langset & foundset) - forcedset): # all langs given and found in sdf without enforced 101 [self.merge_file(inputfile,self.format_outputfile(inputfile, lang), ref, lang, False, sdfdata) for lang in ((langset & foundset) - forcedset)] 102 # Always write those files even if there is no l10n available 103 if forcedset: # all enforced langs 104 [self.merge_file(inputfile, self.format_outputfile(inputfile, lang), ref, lang, True, sdfdata) for lang in forcedset] 105 # In case a big file have to be written 106 if ((langset & foundset) | forcedset): # all langs given ,found in sdf and enforced ones 107 self.merge_one_big_file(inputfile, self.format_outputfile(inputfile, lang), ref, ((langset & foundset) | forcedset), sdfdata) 108 109 def has_multi_inputfiles(self): 110 return self._options.inputfile[0] == '@' 111 112 def copy_file(self, inputfilename, outputfilename): 113 try: 114 os.remove(outputfilename) 115 except: 116 pass 117 118 try: 119 os.remove(outputfilename) 120 except: 121 pass 122 123 try: 124 shutil.copy(inputfilename, outputfilename) 125 except IOError: 126 print("ERROR: Can not copy file '" + inputfilename + "' to " + "'" + outputfilename + "'") 127 sys.exit(-1) 128 129 def extract(self): 130 try: 131 f = open(self._options.outputfile, "w+") 132 f.write(self.extract_file(self._options.inputfile)) 133 except IOError: 134 print("ERROR: Can not write file " + self._options.outputfile) 135 else: 136 f.close() 137 138 # Parse the common options 139 def parse_options(self): 140 parser = OptionParser() 141 parser.add_option("-i", "--inputfile", dest="inputfile", metavar="FILE", help="resource file to read" ) 142 parser.add_option("-o", "--outputfile", dest="outputfile", metavar="FILE", help="extracted sdf or merged file" ) 143 parser.add_option("-m", "--inputsdffile", dest="input_sdf_file", metavar="FILE", help="merge this sdf file" ) 144 parser.add_option("-x", "--pathprefix", dest="path_prefix", metavar="PATH", help="" ) 145 parser.add_option("-y", "--pathpostfix", dest="path_postfix", metavar="PATH", help="" ) 146 parser.add_option("-p", "--projectname", dest="project_name", metavar="NAME", help="" ) 147 parser.add_option("-r", "--projectroot", dest="project_root", metavar="PATH", help="" ) 148 parser.add_option("-f", "--forcedlanguages", dest="forcedlanguages", metavar="ISOCODE[,ISOCODE]", help="Always merge those langs even if no l10n is available for those langs" ) 149 parser.add_option("-l", "--languages", dest="languages", metavar="ISOCODE[,ISOCODE]", help="Merge those langs if l10n is found for each") 150 parser.add_option("-s", "--pattern", dest="pattern", metavar="", help="" ) 151 parser.add_option("-q", "--quiet", action="store_true", dest="quietmode", help="",default=False) 152 (self._options, self.args) = parser.parse_args() 153 154 # -l "de,pr,pt-BR" => [ "de" , "pt" , "pt-BR" ] 155 parse_complex_arg = lambda arg: arg.split(",") 156 157 if self._options.forcedlanguages: 158 self._options.forcedlanguages = parse_complex_arg(self._options.forcedlanguages) 159 if self._options.languages: 160 self._options.languages = parse_complex_arg(self._options.languages) 161 self.test_options() 162 163 def __init__(self): 164 self.parse_options() 165 if self._options.input_sdf_file != None and len(self._options.input_sdf_file): 166 sdfdata = SdfData(self._options.input_sdf_file) 167 sdfdata.read() 168 self.merge(sdfdata) 169 else: 170 self.extract() 171 172 def make_dirs(self, filename): 173 dir = filename[:filename.rfind('/')] 174 if os.path.exists(dir): 175 if os.path.isfile(dir): 176 print("ERROR: There is a file '"+dir+"' where I want create a directory") 177 sys.exit(-1) 178 else: 179 return 180 else: 181 try: 182 os.makedirs(dir) 183 except IOError: 184 print("Error: Can not create dir " + dir) 185 sys.exit(-1) 186 187 def test_options(self): 188 opt = self._options 189 is_valid = lambda x: x != None and len(x) > 0 190 return is_valid(opt.project_root) and is_valid(opt.project_name) and is_valid(opt.languages) and \ 191 ( is_valid(opt.inputfile) and (( is_valid(opt.path_prefix) and is_valid(opt.path_postfix) ) or is_valid(opt.outputfile)) and \ 192 ( ( is_valid(opt.input_sdf_file) and ( is_valid(opt.outputfile) or ( is_valid(opt.path_prefix) and is_valid(opt.path_postfix) ) or \ 193 ( is_valid(opt.inputfile) and is_valid(opt.outputFile)) )))) 194 print("Strange options ...") 195 sys.exit( -1 ) 196 197 def read_inputfile_list(self): 198 if self.has_multi_inputfiles(): 199 lines = [] 200 try: 201 f = open(self._options.inputfile[1:], "r") 202 lines = [line.strip('\n') for line in f.readlines()] 203 except IOError: 204 print("ERROR: Can not read file list " + self._options.inputfile[2:]) 205 sys.exit(-1) 206 else: 207 f.close() 208 return lines 209 210 def get_filename_string(self, inputfile): 211 absfile = os.path.realpath(os.path.abspath(inputfile)) 212 absroot = os.path.realpath(os.path.abspath(self._options.project_root)) 213 return absfile[len(absroot)+1:].replace('/','\\') 214