1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """Merges XLIFF and Gettext PO localization files
23
24 Snippet file produced by pogrep or updated by a translator can be merged into
25 existing files
26
27 See: http://translate.sourceforge.net/wiki/toolkit/pomerge for examples and
28 usage instructions
29 """
30
31 import sys
32 from translate.storage import factory
33 from translate.storage import po
34 from translate.storage import xliff
35 from translate.storage.poheader import poheader
36
37 -def mergestores(store1, store2, mergeblanks, mergecomments):
38 """Take any new translations in store2 and write them into store1."""
39
40 for unit2 in store2.units:
41 if unit2.isheader():
42 if isinstance(store1, poheader):
43 store1.mergeheaders(store2)
44
45 continue
46
47 entities = unit2.getlocations()
48 if len(entities) == 0:
49 source = unit2.source
50 unit1 = store1.findunit(source)
51 if unit1 is None:
52 sys.stderr.write(str(unit2) + "\n")
53 else:
54
55 unit1.merge(unit2, overwrite=True)
56 for entity in entities:
57 unit1 = None
58 if store1.locationindex.has_key(entity):
59
60 unit1 = store1.locationindex[entity]
61
62 if store2.locationindex.has_key(entity):
63 if store2.locationindex[entity] is None:
64 unit1 = None
65
66 if unit1 is None:
67 source = unit2.source
68 unit1 = store1.findunit(source)
69
70 if unit1 is None:
71 print >> sys.stderr, "# the following po element was not found"
72 sys.stderr.write(str(unit2) + "\n")
73 else:
74 if not mergeblanks:
75 target = unit2.target
76 if len(target.strip()) == 0: continue
77
78 unit1.merge(unit2, overwrite=True, comments=mergecomments)
79 return store1
80
82 """Convert a string value to boolean
83
84 @param option: yes, true, 1, no, false, 0
85 @type option: String
86 @rtype: Boolean
87
88 """
89 option = option.lower()
90 if option in ("yes", "true", "1"):
91 return True
92 elif option in ("no", "false", "0"):
93 return False
94 else:
95 raise ValueError("invalid boolean value: %r" % option)
96
97 -def mergestore(inputfile, outputfile, templatefile, mergeblanks="no", mergecomments="yes"):
98 try:
99 mergecomments = str2bool(mergecomments)
100 except ValueError:
101 raise ValueError("invalid mergecomments value: %r" % mergecomments)
102 try:
103 mergeblanks = str2bool(mergeblanks)
104 except ValueError:
105 raise ValueError("invalid mergeblanks value: %r" % mergeblanks)
106 inputstore = factory.getobject(inputfile)
107 if templatefile is None:
108
109 templatestore = type(inputstore)()
110 else:
111 templatestore = factory.getobject(templatefile)
112 templatestore.makeindex()
113 inputstore.makeindex()
114 outputstore = mergestores(templatestore, inputstore, mergeblanks, mergecomments)
115 if outputstore.isempty():
116 return 0
117 outputfile.write(str(outputstore))
118 return 1
119
121 from translate.convert import convert
122 pooutput = ("po", mergestore)
123 potoutput = ("pot", mergestore)
124 xliffoutput = ("xlf", mergestore)
125 formats = {("po", "po"): pooutput, ("po", "pot"): pooutput, ("pot", "po"): pooutput, ("pot", "pot"): potoutput,
126 "po": pooutput, "pot": pooutput,
127 ("xlf", "po"): pooutput, ("xlf", "pot"): pooutput,
128 ("xlf", "xlf"): xliffoutput, ("po", "xlf"): xliffoutput}
129 mergeblanksoption = convert.optparse.Option("", "--mergeblanks", dest="mergeblanks",
130 action="store", default="yes", help="whether to overwrite existing translations with blank translations (yes/no). Default is yes.")
131 mergecommentsoption = convert.optparse.Option("", "--mergecomments", dest="mergecomments",
132 action="store", default="yes", help="whether to merge comments as well as translations (yes/no). Default is yes.")
133 parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
134 parser.add_option(mergeblanksoption)
135 parser.passthrough.append("mergeblanks")
136 parser.add_option(mergecommentsoption)
137 parser.passthrough.append("mergecomments")
138 parser.run()
139
140
141 if __name__ == '__main__':
142 main()
143