blob: 3ac49c00d61a47e479578b0b309408202ad665d1 [file] [log] [blame]
#**************************************************************
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#**************************************************************
from optparse import OptionParser
from sdf import SdfData
from pseudo import PseudoSet
import sys
import os
import shutil
class AbstractL10nTool:
_options = {}
_args = ""
_resource_type = ""
_source_language = "en-US"
##### Implement these abstract methods
##### Nameing scheme for the output files
def get_outputfile_format_str(self):
# filename,fileNoExt,language,extension,pathPrefix,pathPostFix,path
#return "{path}/{fileNoExt}_{language}.{extension}"
return self._options.pattern
################################# Merge single files ###########################################
##### Merge a single file
def merge_file(self, inputfilename, outputfilename, parsed_file_ref, lang, is_forced_lang, sdfdata):
pass
##### Helper for parse-once-use-often like parsing a xml file is needed implement it here
def parse_file(self, filename):
return None
################### Merge one big file containing all strings in all languages #################
def merge_one_big_file(self, inputfile, outputfilename, parsed_file_ref, lang, sdfdata):
pass
################### Extract a single File ######################################################
def extract_file(self, inputfile):
pass
################################################################################################
def format_outputfile(self, filename, language):
extension = filename[filename.rfind('.')+1:]
file = filename[:filename.rfind('.')]
# Python 2.3.x friendly
return self.get_outputfile_format_str().replace('[', '%(').replace(']',')s') % \
{ 'filename': filename, 'fileNoExt': file, 'language': language, 'extension': extension, 'path_prefix': self._options.path_prefix,
'path_postfix': self._options.path_postfix, 'path': self.get_path() }
#return self.get_outputfile_format_str().replace('[', '{').replace(']','}').format(
# filename=filename, fileNoExt=file, language=language, extension=extension, path_prefix=self._options.path_prefix,
# path_postfix=self._options.path_postfix, path=self.get_path())
def get_path(self):
if self._options.outputfile.find('/') == -1:
return ""
else:
return self._options.outputfile[:self._options.outputfile.rfind('/')]
def merge(self, sdfdata):
langset,forcedset, foundset = PseudoSet(), PseudoSet() , PseudoSet()
if self._options.languages:
langset = PseudoSet(self._options.languages)
if self._options.forcedlanguages:
forcedset = PseudoSet(self._options.forcedlanguages)
if sdfdata.get_languages_found_in_sdf():
foundset = sdfdata.get_languages_found_in_sdf()
if self.has_multi_inputfiles():
filelist = self.read_inputfile_list()
else:
filelist = self._options.inputfile
for inputfile in filelist:
ref = self.parse_file(inputfile)
# Don't write that files if there is no l10n present
if ((langset & foundset) - forcedset): # all langs given and found in sdf without enforced
[self.merge_file(inputfile,self.format_outputfile(inputfile, lang), ref, lang, False, sdfdata) for lang in ((langset & foundset) - forcedset)]
# Always write those files even if there is no l10n available
if forcedset: # all enforced langs
[self.merge_file(inputfile, self.format_outputfile(inputfile, lang), ref, lang, True, sdfdata) for lang in forcedset]
# In case a big file have to be written
if ((langset & foundset) | forcedset): # all langs given ,found in sdf and enforced ones
self.merge_one_big_file(inputfile, self.format_outputfile(inputfile, lang), ref, ((langset & foundset) | forcedset), sdfdata)
def has_multi_inputfiles(self):
return self._options.inputfile[0] == '@'
def copy_file(self, inputfilename, outputfilename):
try:
os.remove(outputfilename)
except:
pass
try:
os.remove(outputfilename)
except:
pass
try:
shutil.copy(inputfilename, outputfilename)
except IOError:
print("ERROR: Can not copy file '" + inputfilename + "' to " + "'" + outputfilename + "'")
sys.exit(-1)
def extract(self):
try:
f = open(self._options.outputfile, "w+")
f.write(self.extract_file(self._options.inputfile))
except IOError:
print("ERROR: Can not write file " + self._options.outputfile)
else:
f.close()
# Parse the common options
def parse_options(self):
parser = OptionParser()
parser.add_option("-i", "--inputfile", dest="inputfile", metavar="FILE", help="resource file to read" )
parser.add_option("-o", "--outputfile", dest="outputfile", metavar="FILE", help="extracted sdf or merged file" )
parser.add_option("-m", "--inputsdffile", dest="input_sdf_file", metavar="FILE", help="merge this sdf file" )
parser.add_option("-x", "--pathprefix", dest="path_prefix", metavar="PATH", help="" )
parser.add_option("-y", "--pathpostfix", dest="path_postfix", metavar="PATH", help="" )
parser.add_option("-p", "--projectname", dest="project_name", metavar="NAME", help="" )
parser.add_option("-r", "--projectroot", dest="project_root", metavar="PATH", help="" )
parser.add_option("-f", "--forcedlanguages", dest="forcedlanguages", metavar="ISOCODE[,ISOCODE]", help="Always merge those langs even if no l10n is available for those langs" )
parser.add_option("-l", "--languages", dest="languages", metavar="ISOCODE[,ISOCODE]", help="Merge those langs if l10n is found for each")
parser.add_option("-s", "--pattern", dest="pattern", metavar="", help="" )
parser.add_option("-q", "--quiet", action="store_true", dest="quietmode", help="",default=False)
(self._options, self.args) = parser.parse_args()
# -l "de,pr,pt-BR" => [ "de" , "pt" , "pt-BR" ]
parse_complex_arg = lambda arg: arg.split(",")
if self._options.forcedlanguages:
self._options.forcedlanguages = parse_complex_arg(self._options.forcedlanguages)
if self._options.languages:
self._options.languages = parse_complex_arg(self._options.languages)
self.test_options()
def __init__(self):
self.parse_options()
if self._options.input_sdf_file != None and len(self._options.input_sdf_file):
sdfdata = SdfData(self._options.input_sdf_file)
sdfdata.read()
self.merge(sdfdata)
else:
self.extract()
def make_dirs(self, filename):
dir = filename[:filename.rfind('/')]
if os.path.exists(dir):
if os.path.isfile(dir):
print("ERROR: There is a file '"+dir+"' where I want create a directory")
sys.exit(-1)
else:
return
else:
try:
os.makedirs(dir)
except IOError:
print("Error: Can not create dir " + dir)
sys.exit(-1)
def test_options(self):
opt = self._options
is_valid = lambda x: x != None and len(x) > 0
return is_valid(opt.project_root) and is_valid(opt.project_name) and is_valid(opt.languages) and \
( is_valid(opt.inputfile) and (( is_valid(opt.path_prefix) and is_valid(opt.path_postfix) ) or is_valid(opt.outputfile)) and \
( ( is_valid(opt.input_sdf_file) and ( is_valid(opt.outputfile) or ( is_valid(opt.path_prefix) and is_valid(opt.path_postfix) ) or \
( is_valid(opt.inputfile) and is_valid(opt.outputFile)) ))))
print("Strange options ...")
sys.exit( -1 )
def read_inputfile_list(self):
if self.has_multi_inputfiles():
lines = []
try:
f = open(self._options.inputfile[1:], "r")
lines = [line.strip('\n') for line in f.readlines()]
except IOError:
print("ERROR: Can not read file list " + self._options.inputfile[2:])
sys.exit(-1)
else:
f.close()
return lines
def get_filename_string(self, inputfile):
absfile = os.path.realpath(os.path.abspath(inputfile))
absroot = os.path.realpath(os.path.abspath(self._options.project_root))
return absfile[len(absroot)+1:].replace('/','\\')