1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22  """convert Gettext PO templates (.pot) to PO localization files, preserving existing translations 
 23   
 24  See: http://translate.sourceforge.net/wiki/toolkit/pot2po for examples and  
 25  usage instructions 
 26  """ 
 27   
 28  from translate.storage import po 
 29  from translate.storage import factory 
 30  from translate.search import match 
 31  from translate.misc.multistring import multistring 
 32   
 33   
 34  tmmatcher = None 
 35   
 36 -def memory(tmfiles, max_candidates=1, min_similarity=75, max_length=1000): 
  37      """Returns the TM store to use. Only initialises on first call.""" 
 38      global tmmatcher 
 39       
 40      if tmmatcher is None: 
 41          if isinstance(tmfiles, list): 
 42              tmstore = [factory.getobject(tmfile) for tmfile in tmfiles] 
 43          else: 
 44              tmstore = factory.getobject(tmfiles) 
 45          tmmatcher = match.matcher(tmstore, max_candidates=max_candidates, min_similarity=min_similarity, max_length=max_length) 
 46      return tmmatcher 
  47   
 48 -def convertpot(inputpotfile, outputpofile, templatepofile, tm=None, min_similarity=75, fuzzymatching=True, **kwargs): 
  49      """reads in inputpotfile, adjusts header, writes to outputpofile. if templatepofile exists, merge translations from it into outputpofile""" 
 50      inputpot = po.pofile(inputpotfile) 
 51      inputpot.makeindex() 
 52      thetargetfile = po.pofile() 
 53       
 54      charset = "UTF-8" 
 55      encoding = "8bit" 
 56      project_id_version = None 
 57      pot_creation_date = None 
 58      po_revision_date = None 
 59      last_translator = None 
 60      language_team = None 
 61      mime_version = None 
 62      plural_forms = None 
 63      kwargs = {} 
 64      if templatepofile is not None: 
 65          templatepo = po.pofile(templatepofile) 
 66          fuzzyfilematcher = None 
 67          if fuzzymatching: 
 68              for unit in templatepo.units: 
 69                  if unit.isobsolete(): 
 70                      unit.resurrect() 
 71              try: 
 72                  fuzzyfilematcher = match.matcher(templatepo, max_candidates=1, min_similarity=min_similarity, max_length=1000, usefuzzy=True) 
 73                  fuzzyfilematcher.addpercentage = False 
 74              except ValueError: 
 75                   
 76                  pass 
 77   
 78          templatepo.makeindex() 
 79          templateheadervalues = templatepo.parseheader() 
 80          for key, value in templateheadervalues.iteritems(): 
 81              if key == "Project-Id-Version": 
 82                  project_id_version = value 
 83              elif key == "Last-Translator": 
 84                  last_translator = value 
 85              elif key == "Language-Team": 
 86                  language_team = value 
 87              elif key == "PO-Revision-Date": 
 88                  po_revision_date = value 
 89              elif key in ("POT-Creation-Date", "MIME-Version"): 
 90                   
 91                  pass 
 92              elif key == "Content-Type": 
 93                  kwargs[key] = value 
 94              elif key == "Content-Transfer-Encoding": 
 95                  encoding = value 
 96              elif key == "Plural-Forms": 
 97                  plural_forms = value 
 98              else: 
 99                  kwargs[key] = value 
100      fuzzyglobalmatcher = None 
101      if fuzzymatching and tm: 
102          fuzzyglobalmatcher = memory(tm, max_candidates=1, min_similarity=min_similarity, max_length=1000) 
103          fuzzyglobalmatcher.addpercentage = False 
104      inputheadervalues = inputpot.parseheader() 
105      for key, value in inputheadervalues.iteritems(): 
106          if key in ("Project-Id-Version", "Last-Translator", "Language-Team", "PO-Revision-Date", "Content-Type", "Content-Transfer-Encoding", "Plural-Forms"): 
107               
108              pass 
109          elif key == "POT-Creation-Date": 
110              pot_creation_date = value 
111          elif key == "MIME-Version": 
112              mime_version = value 
113          else: 
114              kwargs[key] = value 
115      targetheader = thetargetfile.makeheader(charset=charset, encoding=encoding, project_id_version=project_id_version, 
116          pot_creation_date=pot_creation_date, po_revision_date=po_revision_date, last_translator=last_translator, 
117          language_team=language_team, mime_version=mime_version, plural_forms=plural_forms, **kwargs) 
118       
119      if templatepofile is not None and len(templatepo.units) > 0: 
120          if templatepo.units[0].isheader(): 
121              if templatepo.units[0].getnotes("translator"): 
122                  targetheader.addnote(templatepo.units[0].getnotes("translator"), "translator") 
123              if inputpot.units[0].getnotes("developer"): 
124                  targetheader.addnote(inputpot.units[0].getnotes("developer"), "developer") 
125              targetheader.markfuzzy(templatepo.units[0].isfuzzy()) 
126      elif inputpot.units[0].isheader(): 
127          targetheader.addnote(inputpot.units[0].getnotes()) 
128      thetargetfile.addunit(targetheader) 
129       
130      for inputpotunit in inputpot.units: 
131          if not (inputpotunit.isheader() or inputpotunit.isobsolete()): 
132              if templatepofile: 
133                  possiblematches = [] 
134                  for location in inputpotunit.getlocations(): 
135                      templatepounit = templatepo.locationindex.get(location, None) 
136                      if templatepounit is not None: 
137                          possiblematches.append(templatepounit) 
138                  if len(inputpotunit.getlocations()) == 0: 
139                      templatepounit = templatepo.findunit(inputpotunit.source) 
140                  if templatepounit: 
141                      possiblematches.append(templatepounit) 
142                  for templatepounit in possiblematches: 
143                      if inputpotunit.source == templatepounit.source and templatepounit.target: 
144                          inputpotunit.merge(templatepounit, authoritative=True) 
145                          break 
146                  else: 
147                      fuzzycandidates = [] 
148                      if fuzzyfilematcher: 
149                          fuzzycandidates = fuzzyfilematcher.matches(inputpotunit.source) 
150                          if fuzzycandidates: 
151                              inputpotunit.merge(fuzzycandidates[0]) 
152                              original = templatepo.findunit(fuzzycandidates[0].source) 
153                              if original: 
154                                  original.reused = True 
155                      if fuzzyglobalmatcher and not fuzzycandidates: 
156                          fuzzycandidates = fuzzyglobalmatcher.matches(inputpotunit.source) 
157                          if fuzzycandidates: 
158                              inputpotunit.merge(fuzzycandidates[0]) 
159              else: 
160                  if fuzzyglobalmatcher: 
161                      fuzzycandidates = fuzzyglobalmatcher.matches(inputpotunit.source) 
162                      if fuzzycandidates: 
163                          inputpotunit.merge(fuzzycandidates[0]) 
164              if inputpotunit.hasplural() and len(inputpotunit.target) == 0: 
165                   
166                  nplurals, plural = thetargetfile.getheaderplural() 
167                  if nplurals and nplurals.isdigit() and nplurals != '2': 
168                      inputpotunit.target = multistring([""]*int(nplurals)) 
169              thetargetfile.addunit(inputpotunit) 
170   
171       
172      if templatepofile: 
173          newlyobsoleted = [] 
174          for unit in templatepo.units: 
175              if unit.isheader(): 
176                  continue 
177              if unit.target and not (inputpot.findunit(unit.source) or hasattr(unit, "reused")): 
178                   
179                  unit.makeobsolete() 
180                  newlyobsoleted.append(unit) 
181              elif unit.isobsolete(): 
182                  thetargetfile.addunit(unit) 
183          for unit in newlyobsoleted: 
184              thetargetfile.addunit(unit) 
185      outputpofile.write(str(thetargetfile)) 
186      return 1 
 187   
188 -def main(argv=None): 
 189      from translate.convert import convert 
190      formats = {"pot": ("po", convertpot), ("pot", "po"): ("po", convertpot)} 
191      parser = convert.ConvertOptionParser(formats, usepots=True, usetemplates=True,  
192          allowmissingtemplate=True, description=__doc__) 
193      parser.add_option("", "--tm", dest="tm", default=None, 
194          help="The file to use as translation memory when fuzzy matching") 
195      parser.passthrough.append("tm") 
196      defaultsimilarity = 75 
197      parser.add_option("-s", "--similarity", dest="min_similarity", default=defaultsimilarity, 
198          type="float", help="The minimum similarity for inclusion (default: %d%%)" % defaultsimilarity) 
199      parser.passthrough.append("min_similarity") 
200      parser.add_option("--nofuzzymatching", dest="fuzzymatching", action="store_false",  
201          default=True, help="Disable fuzzy matching") 
202      parser.passthrough.append("fuzzymatching") 
203      parser.run(argv) 
 204   
205   
206  if __name__ == '__main__': 
207      main() 
208