source: devtools/metadata_extract_locale2po/metadata_xml2po.py

Last change on this file was 6465, checked in by Juanma, 22 months ago

add firefox customizer

  • Property svn:executable set to *
File size: 7.6 KB
Line 
1#!/usr/bin/env python3
2#metadata_xml2po.py
3#This shell has two work modes:
4# - Reads a folder and its subfolders and generates a .po file with all the descriptions, summaries..etc.. founded on the metainfo folders
5# - Updates the xml files of a folder (and its subfolders) with a given po
6
7import os
8import sys
9import xml.etree.ElementTree as ET
10import polib as PO
11
12def _debug(msg):
13        global dbg
14        if dbg==1:
15                print(str(msg))
16
17def usage_help():
18        print ("Usage:")
19        print (sys.argv[0]+" --export|-e path_to_dirs" )
20        print (sys.argv[0]+" --import|-i path_to_dirs path_to_po" )
21        print("Options:")
22        print("\t --debug|-d -> Enables debug mode")
23        print("\t --xmlfix|-x -> When exporting fixes the original texts from xml files replacing \" with \' and \\n with spaces")
24        print("\t --suffix|-s [suffix] -> Appends \"suffix\" to generated files")
25        print("")
26        exit(1)
27#def usage_help
28
29def parse_arguments():
30        global mode
31        global wrkDir
32        global poFile
33        global suffix
34        global xmlFix
35        sfx=0
36        argList={"--export":"export","-e":"export","--import":"import","-i":"import","-d":"debug","--debug":"debug","--suffix":"suffix","-s":"suffix","-x":"xmlfix","--xmlfix":"correct"}
37        args=sys.argv[1:]
38        for arg in args:
39                if sfx:
40                        suffix=arg
41                        sfx=0
42                elif arg in argList.keys():
43                        if argList[arg]=='debug':
44                                global dbg
45                                dbg=1
46                                _debug("Debug enabled")
47                        elif argList[arg]=='suffix':
48                                sfx=1
49                        elif argList[arg]=='xmlfix':
50                                xmlFix=1
51                        else:
52                                mode=argList[arg]
53                elif os.path.isdir(arg):
54                        wrkDir=arg
55                elif os.path.isfile(arg):
56                        poFile=arg
57        if ((not mode or not wrkDir) or (mode=="import" and not poFile)):
58                usage_help()
59#def parse_arguments
60
61def get_package_dirs(path):
62        candidatePaths=[]
63        for basedir, dirs, files in os.walk(path):
64                for subdir in dirs:
65                        if subdir.endswith("metainfo") and "fuentes/llx-resources" in basedir:
66                                _debug(("Adding %s to listdir")%(basedir+'/'+subdir))
67                                #Look for the xml
68                                candidatePaths.append(basedir+"/"+subdir)
69        return candidatePaths
70#def get_package_dirs
71
72def generate_tmp_po(candidatePaths):
73        global xmlFix
74        for path in candidatePaths:
75                dirContent = os.listdir(path)
76                for xmlFile in dirContent:
77                        if not xmlFile.endswith(".xml"):
78                                continue
79                        try:
80                                xml = ET.parse(path+'/'+xmlFile)
81                                xmlRoot=xml.getroot()
82                                tagList=['name','summary','description']
83                                for tag in tagList:
84                                        for element in xmlRoot.iter(tag):
85                                                if tag=='description':
86                                                        for xmlDesc in element:
87                                                                if not (xmlDesc.attrib):
88                                                                        msgid=str(xmlDesc.text).replace("\"","\'")
89                                                                        msgid=str(msgid).replace("\n"," ")
90                                                                        xmlDesc.text=msgid
91                                                                        msgIdList.append(msgid)
92                                                                else:
93                                                                        save_locale(xmlDesc.attrib['{http://www.w3.org/XML/1998/namespace}lang'],msgid,xmlDesc.text)
94                                                else:
95                                                        if not (element.attrib):
96                                                                msgid=str(element.text).replace("\"","\'")
97                                                                msgid=str(msgid).replace("\n"," ")
98                                                                element.text=msgid
99                                                                msgIdList.append(msgid)
100                                                        else:
101                                                                save_locale(element.attrib['{http://www.w3.org/XML/1998/namespace}lang'],msgid,element.text)
102                                #Fixes the xml replacing " with ' and \n with spaces
103                                if xmlFix:
104                                        _debug(("Attempting to fix the xmlFile %s")%(xmlFile))
105                                        xml.write(path+'/'+xmlFile)
106                        except Exception as e:
107                                print(str(e))
108                                print (xmlFile)
109#def generate_tmp_po
110
111def save_locale(locale,msgid,msgstr=None):
112        poString=str(msgstr).replace("\"","\'")
113        poString=poString.replace("\n"," ")
114        if "valencia" in locale or "qcv" in locale:
115                locale="ca_ES.UTF-8@valencia"
116        if locale in poDict.keys():
117                poDict[locale].update({msgid:poString})
118        else:
119                poDict[locale]={msgid:poString}
120        localeSet.append(locale)
121#def save_locale
122
123def print_locale(outputFile):
124        global suffix
125        for msgId in msgIdList:
126                #Open locale po and append the info
127                for localization in localeSet:
128                        f=open(outputFile+"_"+localization+".po"+suffix,'a')
129                        if f.tell()==0:
130                                f.write("msgid \"\"\nmsgstr \"\"\n\"Content-Type: text/plain; charset=utf-8\"\n")
131                        f.write("msgid \""+     msgId+"\"\n")
132                        if msgId in poDict[localization]:
133                                f.write("msgstr \""+poDict[localization][msgId]+"\"\n")
134                        else:
135                                f.write("msgstr \"\"\n")
136                        f.close
137#def print_locale
138
139def get_locale_from_po(poFile):
140        locale=os.path.basename(poFile)
141        locale=locale.replace('catalogue_','')
142        locale=locale.replace('.po','')
143        if "valencia" in locale or "qcv" in locale:
144                locale="ca_ES.UTF-8@valencia"
145        _debug("Locale set to "+locale)
146        return(locale)
147#def get_locale_from_po
148
149def load_po(poFile,locale):
150        global poDict
151        global fileEncoding
152        fileEncoding=PO.detect_encoding(poFile)
153        poDict={}
154        _debug(("Loading po %s with %s encoding")%(poFile,fileEncoding))
155        po = PO.pofile(poFile,encoding=fileEncoding)
156        for entry in po:
157                if entry.msgid in poDict.keys():
158                        poDict[entry.msgid].update({locale:entry.msgstr})
159                else:
160                        poDict[entry.msgid]={locale:entry.msgstr}
161#def load_po
162
163def get_translations(msgid):
164        translationDict={}
165        _debug("Searching translations for " + msgid)
166        if msgid in poDict.keys():
167                translationDict=poDict[msgid].copy()
168        _debug("Get "+str(translationDict))
169        return translationDict
170#def get_translations
171
172def merge_translations(candidatePaths,locale):
173        global suffix
174        for path in candidatePaths:
175                dirContent = os.listdir(path)
176                for xmlFile in dirContent:
177                        if not xmlFile.endswith(".xml"):
178                                continue
179                        xml = ET.parse(path+'/'+xmlFile)
180                        xmlRoot=xml.getroot()
181                        tagList=['name','summary','description']
182                        for tag in tagList:
183                                for element in xmlRoot.iter(tag):
184                                        if tag=='description':
185                                                #1st loop, get the msgid
186                                                for xmlDesc in element:
187                                                        if not (xmlDesc.attrib):
188                                                                translationDict=get_translated_msgid(xmlDesc)
189                                                                break
190                                                #2dn loop, modify translations for descriptions
191                                                for xmlDesc in element:
192                                                        if not (xmlDesc.attrib):
193                                                                continue
194                                                        modify_translation(xmlDesc,translationDict)
195                                                #Generate new translations
196                                                for locale,translation in translationDict.items():
197                                                        add_new_translation(element,'p',translation)
198                                        else:
199                                                if not (element.attrib):
200                                                        translationDict=get_translated_msgid(element)
201                                                else:
202                                                        modify_translation(element,translationDict)
203                                #Generate new translations
204                                for locale,translation in translationDict.items():
205                                        if tag=='description':
206                                                continue
207                                        add_new_translation(xmlRoot,tag,translation)
208                        xml.write(path+'/'+xmlFile+suffix,encoding=fileEncoding,xml_declaration=True)
209
210def get_translated_msgid(element):
211        msgid=str(element.text).replace("\"","\'")
212        msgid=str(msgid).replace("\n"," ")
213        translationDict=get_translations(msgid)
214        return translationDict
215#def get_translated_msgid
216
217def modify_translation(element,translationDict):
218        _debug(("Modifying %s translation")%(locale))
219        translation=element.text
220        localeTrans=element.attrib['{http://www.w3.org/XML/1998/namespace}lang']
221        if localeTrans in translationDict.keys():
222                translation=translationDict[localeTrans]
223                if translation:
224                        element.text=translation
225                del translationDict[localeTrans]
226        return (translation)
227#def modify_translation
228
229def add_new_translation(element,tag,text):
230        if text!='':
231                newDesc=ET.SubElement(element, tag)
232                newDesc.tail="\n"
233                newDesc.set('xml:lang',locale)
234                newDesc.text=text
235                _debug(("Added new tag %s with %s translation")%(tag,locale))
236#def add_new_translation
237
238#### MAIN PROGRAM ####
239dbg=0
240xmlFix=0
241suffix=''
242fileEncoding=''
243mode=''
244wrkDir=''
245poFile=''
246parse_arguments()
247print(("Analyzing %s for action %s") % (wrkDir,mode))
248poDict={}
249pathList=get_package_dirs(wrkDir)
250if mode=='export':
251        localeSet=[]
252        msgIdList=[]
253        outputFile="catalogue"
254        generate_tmp_po(pathList)
255        localeSet=set(localeSet)
256        print_locale(outputFile)
257        print("Po files generated for "+str(localeSet))
258else:
259        locale=get_locale_from_po(poFile)
260        load_po(poFile,locale)
261        merge_translations(pathList,locale)
262        print("Updated metadata xml in "+str(pathList))
Note: See TracBrowser for help on using the repository browser.