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