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