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