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  import re
     23
     24  from translate.storage import base
     25  from translate.storage import poheader
     26  from translate.storage.workflow import StateEnum as state
     27
     28  msgid_comment_re = re.compile("_: (.*?)\n")
     29
     30
     31 -def extract_msgid_comment(text):
     32      """The one definitive way to extract a msgid comment out of an unescaped
     33      unicode string that might contain it.
     34
     35      @rtype: unicode"""
     36      msgidcomment = msgid_comment_re.match(text)
     37      if msgidcomment:
     38          return msgidcomment.group(1)
     39      return u""
     40
     41
     42 -class pounit(base.TranslationUnit):
     43      S_OBSOLETE = state.OBSOLETE
     44      S_UNTRANSLATED = state.EMPTY
     45      S_FUZZY = state.NEEDS_WORK
     46      S_TRANSLATED = state.UNREVIEWED
     47
     48      STATE = {
     49          S_OBSOLETE: (state.OBSOLETE, state.EMPTY),
     50          S_UNTRANSLATED: (state.EMPTY, state.NEEDS_WORK),
     51          S_FUZZY: (state.NEEDS_WORK, state.UNREVIEWED),
     52          S_TRANSLATED: (state.UNREVIEWED, state.MAX),
     53      }
     54
     55 -    def adderror(self, errorname, errortext):
     56          """Adds an error message to this unit."""
     57          text = u'(pofilter) %s: %s' % (errorname, errortext)
     58          # Don't add the same error twice:
     59          if text not in self.getnotes(origin='translator'):
     60              self.addnote(text, origin="translator")
     61
     62 -    def geterrors(self):
     63          """Get all error messages."""
     64          notes = self.getnotes(origin="translator").split('\n')
     65          errordict = {}
     66          for note in notes:
     67              if '(pofilter) ' in note:
     68                  error = note.replace('(pofilter) ', '')
     69                  errorname, errortext = error.split(': ', 1)
     70                  errordict[errorname] = errortext
     71          return errordict
     72
     73 -    def markreviewneeded(self, needsreview=True, explanation=None):
     74          """Marks the unit to indicate whether it needs review. Adds an optional explanation as a note."""
     75          if needsreview:
     76              reviewnote = "(review)"
     77              if explanation:
     78                  reviewnote += " " + explanation
     79              self.addnote(reviewnote, origin="translator")
     80          else:
     81              # Strip (review) notes.
     82              notestring = self.getnotes(origin="translator")
     83              notes = notestring.split('\n')
     84              newnotes = []
     85              for note in notes:
     86                  if not '(review)' in note:
     87                      newnotes.append(note)
     88              newnotes = '\n'.join(newnotes)
     89              self.removenotes()
     90              self.addnote(newnotes, origin="translator")
     91
     92 -    def istranslated(self):
     93          return super(pounit, self).istranslated() and not self.isobsolete()
     94
     95 -    def istranslatable(self):
     96          return not (self.isheader() or self.isblank() or self.isobsolete())
     97
     98 -    def hasmarkedcomment(self, commentmarker):
     99          raise NotImplementedError
    100
    101 -    def isreview(self):
    102          return self.hasmarkedcomment("review") or self.hasmarkedcomment("pofilter")
    103
    104 -    def isobsolete(self):
    105          return self.STATE[self.S_OBSOLETE][0] <= self.get_state_n() < self.STATE[self.S_OBSOLETE][1]
    106
    107 -    def isfuzzy(self):
    108          return self.STATE[self.S_FUZZY][0] <= self.get_state_n() < self.STATE[self.S_FUZZY][1]
    109
    110 -    def markfuzzy(self, present=True):
    111          if present:
    112              self.set_state_n(self.STATE[self.S_FUZZY][0])
    113          elif self.gettarget():
    114              self.set_state_n(self.STATE[self.S_TRANSLATED][0])
    115          else:
    116              self.set_state_n(self.STATE[self.S_UNTRANSLATED][0])
    117
    118 -    def makeobsolete(self):
    119          self.set_state_n(self.STATE[self.S_OBSOLETE][0])
    120
    121 -    def resurrect(self):
    122          self.set_state_n(self.STATE[self.S_TRANSLATED][0])
    123          if not self.gettarget():
    124              self.set_state_n(self.STATE[self.S_UNTRANSLATED][0])
    125
    126 -    def _domarkfuzzy(self, present=True):
    127          raise NotImplementedError()
    128
    129 -    def set_state_n(self, value):
    130          super(pounit, self).set_state_n(value)
    131          isfuzzy = self.STATE[self.S_FUZZY][0] <= value < self.STATE[self.S_FUZZY][1]
    132          self._domarkfuzzy(isfuzzy) # Implementation specific fuzzy-marking
    133
    134
    135 -def encodingToUse(encoding):
    136      """Tests whether the given encoding is known in the python runtime, or returns utf-8.
    137      This function is used to ensure that a valid encoding is always used."""
    138      if encoding == "CHARSET" or encoding == None:
    139          return 'utf-8'
    140      return encoding
    141  #    if encoding is None: return False
    142  #    return True
    143  #    try:
    144  #        tuple = codecs.lookup(encoding)
    145  #    except LookupError:
    146  #        return False
    147  #    return True
    148
    149
    150 -class pofile(poheader.poheader, base.TranslationStore):
    151      Name = _("Gettext PO file") # pylint: disable-msg=E0602
    152      Mimetypes = ["text/x-gettext-catalog", "text/x-gettext-translation", "text/x-po", "text/x-pot"]
    153      Extensions = ["po", "pot"]
    154
    155 -    def __init__(self, inputfile=None, encoding=None):
    156          super(pofile, self).__init__(unitclass=self.UnitClass)
    157          self.units = []
    158          self.filename = ''
    159          self._encoding = encodingToUse(encoding)
    160          if inputfile is not None:
    161              self.parse(inputfile)
    162          else:
    163              self.init_headers()
    164