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