1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """Fill localization files with suggested translations based on
22 translation memory and existing translations.
23 """
24
25 from translate.storage import factory
26 from translate.storage import xliff
27 from translate.search import match
28
29
30 tmmatcher = None
31
32 -def memory(tmfiles, max_candidates=1, min_similarity=75, max_length=1000):
33 """Returns the TM store to use. Only initialises on first call."""
34 global tmmatcher
35
36 if tmmatcher is None:
37 if isinstance(tmfiles, list):
38 tmstore = [factory.getobject(tmfile) for tmfile in tmfiles]
39 else:
40 tmstore = factory.getobject(tmfiles)
41 tmmatcher = match.matcher(tmstore, max_candidates=max_candidates, min_similarity=min_similarity, max_length=max_length)
42 return tmmatcher
43
44
45 -def pretranslate_file(input_file, output_file, template_file, tm=None, min_similarity=75, fuzzymatching=True):
46 """Pretranslate any factory supported file with old translations and translation memory."""
47 input_store = factory.getobject(input_file)
48 template_store = None
49 if template_file is not None:
50 template_store = factory.getobject(template_file)
51
52 output = pretranslate_store(input_store, template_store, tm, min_similarity, fuzzymatching)
53 output_file.write(str(output))
54 return 1
55
56
58 """Returns a matching unit from a template."""
59
60
61
62 locations = input_unit.getlocations()
63 if not locations or ":" in locations[0]:
64
65 matching_units = template_store.findunits(input_unit.source)
66 if matching_units:
67 for unit in matching_units:
68 if unit.getcontext() == input_unit.getcontext():
69 return unit
70
71 else:
72
73
74
75 for location in locations:
76 matching_unit = template_store.locationindex.get(location, None)
77
78 if matching_unit is not None and matching_unit.source == input_unit.source and matching_unit.gettargetlen() > 0:
79 return matching_unit
80
81
83 """Return a fuzzy match from a queue of matchers."""
84 for matcher in matchers:
85 fuzzycandidates = matcher.matches(input_unit.source)
86 if fuzzycandidates:
87 return fuzzycandidates[0]
88
89
91 """Pretranslate a unit or return unchanged if no translation was found."""
92
93 matching_unit = None
94
95 if template_store:
96 matching_unit = match_template_id(input_unit, template_store)
97
98 if matching_unit and matching_unit.gettargetlen() > 0:
99 input_unit.merge(matching_unit, authoritative=True)
100 elif matchers:
101
102 matching_unit = match_fuzzy(input_unit, matchers)
103 if matching_unit and matching_unit.gettargetlen() > 0:
104
105 if isinstance(input_unit, xliff.xliffunit):
106
107 input_unit.addalttrans(matching_unit.target, origin="fish", sourcetxt=matching_unit.source)
108 else:
109 input_unit.merge(matching_unit, authoritative=True)
110
111
112
113 if mark_reused and matching_unit and template_store:
114 original_unit = template_store.findunit(matching_unit.source)
115 if original_unit is not None:
116 original_unit.reused = True
117
118 return input_unit
119
121 """PO format specific template preparation logic."""
122
123 for unit in template_store.units:
124 if unit.isobsolete():
125 unit.resurrect()
126
127 -def pretranslate_store(input_store, template_store, tm=None, min_similarity=75, fuzzymatching=True):
128 """Do the actual pretranslation of a whole store."""
129
130 matchers = []
131
132 if template_store is not None:
133 template_store.makeindex()
134
135 prepare_template = "prepare_template_%s" % template_store.__class__.__name__
136 if globals().has_key(prepare_template):
137 globals()[prepare_template](template_store)
138
139 if fuzzymatching:
140
141
142 matcher = match.matcher(template_store, max_candidates=1, min_similarity=min_similarity, max_length=3000, usefuzzy=True)
143 matcher.addpercentage = False
144 matchers.append(matcher)
145
146
147
148 if tm and fuzzymatching:
149
150 matcher = memory(tm, max_candidates=1, min_similarity=min_similarity, max_length=1000)
151 matcher.addpercentage = False
152 matchers.append(matcher)
153
154
155 for input_unit in input_store.units:
156 if input_unit.istranslatable():
157 input_unit = pretranslate_unit(input_unit, template_store, matchers)
158
159 return input_store
160
161
162 -def main(argv=None):
163 from translate.convert import convert
164 formats = {"pot": ("po", pretranslate_file), ("pot", "po"): ("po", pretranslate_file),
165 "po": ("po", pretranslate_file), ("po", "po"): ("po", pretranslate_file),
166 "xlf": ("xlf", pretranslate_file), ("xlf", "xlf"): ("xlf", pretranslate_file),
167 }
168 parser = convert.ConvertOptionParser(formats, usetemplates=True,
169 allowmissingtemplate=True, description=__doc__)
170 parser.add_option("", "--tm", dest="tm", default=None,
171 help="The file to use as translation memory when fuzzy matching")
172 parser.passthrough.append("tm")
173 defaultsimilarity = 75
174 parser.add_option("-s", "--similarity", dest="min_similarity", default=defaultsimilarity,
175 type="float", help="The minimum similarity for inclusion (default: %d%%)" % defaultsimilarity)
176 parser.passthrough.append("min_similarity")
177 parser.add_option("--nofuzzymatching", dest="fuzzymatching", action="store_false",
178 default=True, help="Disable fuzzy matching")
179 parser.passthrough.append("fuzzymatching")
180 parser.run(argv)
181
182
183 if __name__ == '__main__':
184 main()
185