1#
2# Copyright 2002-2009 Zuza Software Foundation
3#
4# This file is part of the Translate Toolkit.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, see <http://www.gnu.org/licenses/>.
18
19"""Convert XLIFF localization files to Gettext PO localization files.
20
21See: http://docs.translatehouse.org/projects/translate-toolkit/en/latest/commands/xliff2po.html
22for examples and usage instructions.
23"""
24
25from translate.storage import po, xliff
26
27
28class xliff2po:
29    def converttransunit(self, transunit):
30        """makes a pounit from the given transunit"""
31        thepo = po.pounit()
32
33        # Header
34        if transunit.getrestype() == "x-gettext-domain-header":
35            thepo.source = ""
36        else:
37            thepo.source = transunit.source
38        thepo.target = transunit.target
39
40        # Location comments
41        locations = transunit.getlocations()
42        if locations:
43            thepo.addlocations(locations)
44
45        # NOTE: Supporting both <context> and <note> tags in xliff files
46        # for comments
47        # Translator comments
48        trancomments = transunit.getnotes("translator")
49        if trancomments:
50            thepo.addnote(trancomments, origin="translator")
51
52        # Automatic and Developer comments
53        autocomments = transunit.getnotes("developer")
54        if autocomments:
55            thepo.addnote(autocomments, origin="developer")
56
57        # See 5.6.1 of the spec. We should not check fuzzyness, but approved
58        # attribute
59        if transunit.isfuzzy():
60            thepo.markfuzzy(True)
61
62        return thepo
63
64    def convertstore(self, inputfile, duplicatestyle="msgctxt"):
65        """Converts a .xliff file to .po format"""
66        XliffFile = xliff.xlifffile.parsestring(inputfile)
67        thetargetfile = po.pofile()
68        targetheader = thetargetfile.header()
69        # TODO: support multiple files
70        for transunit in XliffFile.units:
71            if transunit.isheader():
72                thetargetfile.updateheader(add=True, **XliffFile.parseheader())
73                if transunit.getnotes("translator"):
74                    targetheader.addnote(
75                        transunit.getnotes("translator"),
76                        origin="translator",
77                        position="replace",
78                    )
79                if transunit.getnotes("developer"):
80                    targetheader.addnote(
81                        transunit.getnotes("developer"),
82                        origin="developer",
83                        position="replace",
84                    )
85                targetheader.markfuzzy(transunit.isfuzzy())
86                continue
87            thepo = self.converttransunit(transunit)
88            thetargetfile.addunit(thepo)
89        thetargetfile.removeduplicates(duplicatestyle)
90        return thetargetfile
91
92
93def convertxliff(inputfile, outputfile, templates, duplicatestyle="msgctxt"):
94    """reads in stdin using fromfileclass, converts using convertorclass,
95    writes to stdout
96    """
97    convertor = xliff2po()
98    outputstore = convertor.convertstore(inputfile, duplicatestyle)
99    if outputstore.isempty():
100        return 0
101    outputstore.serialize(outputfile)
102    return 1
103
104
105def main(argv=None):
106    from translate.convert import convert
107
108    formats = {
109        "xlf": ("po", convertxliff),
110        "xliff": ("po", convertxliff),
111    }
112    parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
113    parser.add_duplicates_option()
114    parser.run(argv)
115