1#
2# Copyright 2002-2013 Zuza Software Foundation
3#
4# This file is part of translate.
5#
6# translate 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# translate 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 PHP localization files to Gettext PO localization files.
20
21See: http://docs.translatehouse.org/projects/translate-toolkit/en/latest/commands/php2po.html
22for examples and usage instructions.
23"""
24
25from translate.convert import convert
26from translate.storage import php, po
27
28
29class php2po:
30    """Convert one or two PHP files to a single PO file."""
31
32    SourceStoreClass = php.phpfile
33    TargetStoreClass = po.pofile
34    TargetUnitClass = po.pounit
35
36    def __init__(
37        self,
38        input_file,
39        output_file,
40        template_file=None,
41        blank_msgstr=False,
42        duplicate_style="msgctxt",
43    ):
44        """Initialize the converter."""
45        self.blank_msgstr = blank_msgstr
46        self.duplicate_style = duplicate_style
47
48        self.extraction_msg = None
49        self.output_file = output_file
50        self.source_store = self.SourceStoreClass(input_file)
51        self.target_store = self.TargetStoreClass()
52        self.template_store = None
53
54        if template_file is not None:
55            self.template_store = self.SourceStoreClass(template_file)
56
57    def convert_unit(self, unit):
58        """Convert a source format unit to a target format unit."""
59        target_unit = self.TargetUnitClass(encoding="UTF-8")
60        target_unit.addlocation("".join(unit.getlocations()))
61        target_unit.addnote(unit.getnotes("developer"), "developer")
62        target_unit.source = unit.source
63        target_unit.target = ""
64        return target_unit
65
66    def convert_store(self):
67        """Convert a single source format file to a target format file."""
68        self.extraction_msg = "extracted from %s" % self.source_store.filename
69
70        for source_unit in self.source_store.units:
71            self.target_store.addunit(self.convert_unit(source_unit))
72
73    def merge_stores(self):
74        """Convert two source format files to a target format file."""
75        self.extraction_msg = "extracted from {}, {}".format(
76            self.template_store.filename,
77            self.source_store.filename,
78        )
79
80        self.source_store.makeindex()
81        for template_unit in self.template_store.units:
82            target_unit = self.convert_unit(template_unit)
83
84            add_translation = (
85                not self.blank_msgstr
86                and template_unit.name in self.source_store.locationindex
87            )
88            if add_translation:
89                source_unit = self.source_store.locationindex[template_unit.name]
90                target_unit.target = source_unit.source
91            self.target_store.addunit(target_unit)
92
93    def run(self):
94        """Run the converter."""
95        if self.template_store is None:
96            self.convert_store()
97        else:
98            self.merge_stores()
99
100        if self.extraction_msg:
101            self.target_store.header().addnote(self.extraction_msg, "developer")
102
103        self.target_store.removeduplicates(self.duplicate_style)
104
105        if self.target_store.isempty():
106            return 0
107
108        self.target_store.serialize(self.output_file)
109        return 1
110
111
112def run_converter(
113    input_file, output_file, template_file=None, pot=False, duplicatestyle="msgctxt"
114):
115    """Wrapper around converter."""
116    return php2po(
117        input_file,
118        output_file,
119        template_file,
120        blank_msgstr=pot,
121        duplicate_style=duplicatestyle,
122    ).run()
123
124
125formats = {
126    "php": ("po", run_converter),
127    ("php", "php"): ("po", run_converter),
128    "html": ("po", run_converter),
129    ("html", "html"): ("po", run_converter),
130}
131
132
133def main(argv=None):
134    parser = convert.ConvertOptionParser(
135        formats, usetemplates=True, usepots=True, description=__doc__
136    )
137    parser.add_duplicates_option()
138    parser.passthrough.append("pot")
139    parser.run(argv)
140
141
142if __name__ == "__main__":
143    main()
144