Package translate :: Package storage :: Module pocommon

[hide private]
[frames] | no frames]

# Source Code for Module translate.storage.pocommon

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2002-2007 Zuza Software Foundation
      5  #
      6  # This file is part of translate.
      7  #
      8  # translate is free software; you can redistribute it and/or modify
      9  # it under the terms of the GNU General Public License as published by
     10  # the Free Software Foundation; either version 2 of the License, or
     11  # (at your option) any later version.
     12  #
     13  # translate is distributed in the hope that it will be useful,
     14  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  # GNU General Public License for more details.
     17  #
     18  # You should have received a copy of the GNU General Public License
     19  # along with translate; if not, write to the Free Software
     20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21
     22  from translate.storage import base
     23  from translate.storage import poheader
     24  from translate.storage.workflow import StateEnum as state
     25
     26  import re
     27
     28  msgid_comment_re = re.compile("_: (.*?)\n")
     29
     30 -def extract_msgid_comment(text):
     31      """The one definitive way to extract a msgid comment out of an unescaped
     32      unicode string that might contain it.
     33
     34      @rtype: unicode"""
     35      msgidcomment = msgid_comment_re.match(text)
     36      if msgidcomment:
     37          return msgidcomment.group(1)
     38      return u""
     39
     40
     41 -class pounit(base.TranslationUnit):
     42      S_OBSOLETE     = state.OBSOLETE
     43      S_UNTRANSLATED = state.EMPTY
     44      S_FUZZY        = state.NEEDS_WORK
     45      S_TRANSLATED   = state.UNREVIEWED
     46
     47      STATE = {
     48          S_OBSOLETE:     (state.OBSOLETE,   state.EMPTY),
     49          S_UNTRANSLATED: (state.EMPTY,      state.NEEDS_WORK),
     50          S_FUZZY:        (state.NEEDS_WORK, state.UNREVIEWED),
     51          S_TRANSLATED:   (state.UNREVIEWED, state.MAX),
     52      }
     53
     54 -    def adderror(self, errorname, errortext):
     55          """Adds an error message to this unit."""
     56          text = u'(pofilter) %s: %s' % (errorname, errortext)
     57          # Don't add the same error twice:
     58          if text not in self.getnotes(origin='translator'):
     59              self.addnote(text, origin="translator")
     60
     61 -    def geterrors(self):
     62          """Get all error messages."""
     63          notes = self.getnotes(origin="translator").split('\n')
     64          errordict = {}
     65          for note in notes:
     66              if '(pofilter) ' in note:
     67                  error = note.replace('(pofilter) ', '')
     68                  errorname, errortext = error.split(': ', 1)
     69                  errordict[errorname] = errortext
     70          return errordict
     71
     72 -    def markreviewneeded(self, needsreview=True, explanation=None):
     73          """Marks the unit to indicate whether it needs review. Adds an optional explanation as a note."""
     74          if needsreview:
     75              reviewnote = "(review)"
     76              if explanation:
     77                  reviewnote += " " + explanation
     78              self.addnote(reviewnote, origin="translator")
     79          else:
     80              # Strip (review) notes.
     81              notestring = self.getnotes(origin="translator")
     82              notes = notestring.split('\n')
     83              newnotes = []
     84              for note in notes:
     85                  if not '(review)' in note:
     86                      newnotes.append(note)
     87              newnotes = '\n'.join(newnotes)
     88              self.removenotes()
     89              self.addnote(newnotes, origin="translator")
     90
     91 -    def istranslated(self):
     92          return super(pounit, self).istranslated() and not self.isobsolete()
     93
     94 -    def istranslatable(self):
     95          return not (self.isheader() or self.isblank() or self.isobsolete())
     96
     97 -    def hasmarkedcomment(self, commentmarker):
     98          raise NotImplementedError
     99
    100 -    def isreview(self):
    101          return self.hasmarkedcomment("review") or self.hasmarkedcomment("pofilter")
    102
    103 -    def isobsolete(self):
    104          return self.STATE[self.S_OBSOLETE][0] <= self.get_state_n() < self.STATE[self.S_OBSOLETE][1]
    105
    106 -    def isfuzzy(self):
    107          return self.STATE[self.S_FUZZY][0] <= self.get_state_n() < self.STATE[self.S_FUZZY][1]
    108
    109 -    def markfuzzy(self, present=True):
    110          if present:
    111              self.set_state_n(self.STATE[self.S_FUZZY][0])
    112          elif self.gettarget():
    113              self.set_state_n(self.STATE[self.S_TRANSLATED][0])
    114          else:
    115              self.set_state_n(self.STATE[self.S_UNTRANSLATED][0])
    116
    117 -    def makeobsolete(self):
    118          self.set_state_n(self.STATE[self.S_OBSOLETE][0])
    119
    120 -    def resurrect(self):
    121          self.set_state_n(self.STATE[self.S_TRANSLATED][0])
    122          if not self.gettarget():
    123              self.set_state_n(self.STATE[self.S_UNTRANSLATED][0])
    124
    125 -    def _domarkfuzzy(self, present=True):
    126          raise NotImplementedError()
    127
    128 -    def set_state_n(self, value):
    129          super(pounit, self).set_state_n(value)
    130          isfuzzy = self.STATE[self.S_FUZZY][0] <= value < self.STATE[self.S_FUZZY][1]
    131          self._domarkfuzzy(isfuzzy) # Implementation specific fuzzy-marking
    132
    133
    134 -def encodingToUse(encoding):
    135      """Tests whether the given encoding is known in the python runtime, or returns utf-8.
    136      This function is used to ensure that a valid encoding is always used."""
    137      if encoding == "CHARSET" or encoding == None:
    138          return 'utf-8'
    139      return encoding
    140  #    if encoding is None: return False
    141  #    return True
    142  #    try:
    143  #        tuple = codecs.lookup(encoding)
    144  #    except LookupError:
    145  #        return False
    146  #    return True
    147
    148 -class pofile(poheader.poheader, base.TranslationStore):
    149      Name = _("Gettext PO file") # pylint: disable-msg=E0602
    150      Mimetypes  = ["text/x-gettext-catalog", "text/x-gettext-translation", "text/x-po", "text/x-pot"]
    151      Extensions = ["po", "pot"]
    152
    153 -    def __init__(self, inputfile=None, encoding=None):
    154          super(pofile, self).__init__(unitclass=self.UnitClass)
    155          self.units = []
    156          self.filename = ''
    157          self._encoding = encodingToUse(encoding)
    158          if inputfile is not None:
    159              self.parse(inputfile)
    160          else:
    161              self.init_headers()
    162