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-2011 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_FUZZY_OBSOLETE = state.OBSOLETE-1 44 S_OBSOLETE = state.OBSOLETE 45 S_UNTRANSLATED = state.EMPTY 46 S_FUZZY = state.NEEDS_WORK 47 S_TRANSLATED = state.UNREVIEWED 48 49 STATE = { 50 S_FUZZY_OBSOLETE: (S_FUZZY_OBSOLETE, state.OBSOLETE), 51 S_OBSOLETE: (state.OBSOLETE, state.EMPTY), 52 S_UNTRANSLATED: (state.EMPTY, state.NEEDS_WORK), 53 S_FUZZY: (state.NEEDS_WORK, state.UNREVIEWED), 54 S_TRANSLATED: (state.UNREVIEWED, state.MAX), 55 } 56
57 - def adderror(self, errorname, errortext):
58 """Adds an error message to this unit.""" 59 text = u'(pofilter) %s: %s' % (errorname, errortext) 60 # Don't add the same error twice: 61 if text not in self.getnotes(origin='translator'): 62 self.addnote(text, origin="translator")
63
64 - def geterrors(self):
65 """Get all error messages.""" 66 notes = self.getnotes(origin="translator").split('\n') 67 errordict = {} 68 for note in notes: 69 if '(pofilter) ' in note: 70 error = note.replace('(pofilter) ', '') 71 errorname, errortext = error.split(': ', 1) 72 errordict[errorname] = errortext 73 return errordict
74
75 - def markreviewneeded(self, needsreview=True, explanation=None):
76 """Marks the unit to indicate whether it needs review. Adds an optional explanation as a note.""" 77 if needsreview: 78 reviewnote = "(review)" 79 if explanation: 80 reviewnote += " " + explanation 81 self.addnote(reviewnote, origin="translator") 82 else: 83 # Strip (review) notes. 84 notestring = self.getnotes(origin="translator") 85 notes = notestring.split('\n') 86 newnotes = [] 87 for note in notes: 88 if not '(review)' in note: 89 newnotes.append(note) 90 newnotes = '\n'.join(newnotes) 91 self.removenotes() 92 self.addnote(newnotes, origin="translator")
93
94 - def istranslated(self):
95 return super(pounit, self).istranslated() and not self.isobsolete() and not self.isheader()
96
97 - def istranslatable(self):
98 return not (self.isheader() or self.isblank() or self.isobsolete())
99
100 - def hasmarkedcomment(self, commentmarker):
101 raise NotImplementedError
102
103 - def isreview(self):
104 return self.hasmarkedcomment("review") or self.hasmarkedcomment("pofilter")
105
106 - def isobsolete(self):
107 return self.STATE[self.S_FUZZY_OBSOLETE][0] <= self.get_state_n() < self.STATE[self.S_OBSOLETE][1]
108
109 - def isfuzzy(self):
110 # implementation specific fuzzy detection, must not use get_state_n() 111 raise NotImplementedError()
112
113 - def markfuzzy(self, present=True):
114 if present: 115 self.set_state_n(self.STATE[self.S_FUZZY][0]) 116 else: 117 self.set_state_n(self.STATE[self.S_TRANSLATED][0])
118 # set_state_n will check if target exists 119
120 - def makeobsolete(self):
121 if self.isfuzzy(): 122 self.set_state_n(self.STATE[self.S_FUZZY_OBSOLETE][0]) 123 else: 124 self.set_state_n(self.STATE[self.S_OBSOLETE][0])
125
126 - def resurrect(self):
127 self.set_state_n(self.STATE[self.S_TRANSLATED][0]) 128 if not self.gettarget(): 129 self.set_state_n(self.STATE[self.S_UNTRANSLATED][0])
130
131 - def _domarkfuzzy(self, present=True):
132 raise NotImplementedError()
133
134 - def get_state_n(self):
135 value = super(pounit, self).get_state_n() 136 if value <= self.S_OBSOLETE: 137 return value 138 if self.target: 139 if self.isfuzzy(): 140 return self.S_FUZZY 141 else: 142 return self.S_TRANSLATED 143 else: 144 return self.S_UNTRANSLATED
145
146 - def set_state_n(self, value):
147 super(pounit, self).set_state_n(value) 148 has_target = False 149 if self.hasplural(): 150 for string in self.target.strings: 151 if string: 152 has_target = True 153 break 154 else: 155 has_target = bool(self.target) 156 if has_target: 157 isfuzzy = self.STATE[self.S_FUZZY][0] <= value < self.STATE[self.S_FUZZY][1] or \ 158 self.STATE[self.S_FUZZY_OBSOLETE][0] <= value < self.STATE[self.S_FUZZY_OBSOLETE][1] 159 self._domarkfuzzy(isfuzzy) # Implementation specific fuzzy-marking 160 else: 161 super(pounit, self).set_state_n(self.S_UNTRANSLATED) 162 self._domarkfuzzy(False)
163 164
165 -def encodingToUse(encoding):
166 """Tests whether the given encoding is known in the python runtime, or returns utf-8. 167 This function is used to ensure that a valid encoding is always used.""" 168 if encoding == "CHARSET" or encoding == None: 169 return 'utf-8' 170 return encoding
171 # if encoding is None: return False 172 # return True 173 # try: 174 # tuple = codecs.lookup(encoding) 175 # except LookupError: 176 # return False 177 # return True 178 179
180 -class pofile(poheader.poheader, base.TranslationStore):
181 Name = _("Gettext PO file") # pylint: disable-msg=E0602 182 Mimetypes = ["text/x-gettext-catalog", "text/x-gettext-translation", "text/x-po", "text/x-pot"] 183 Extensions = ["po", "pot"] 184 # We don't want windows line endings on Windows: 185 _binary = True 186
187 - def __init__(self, inputfile=None, encoding=None):
188 super(pofile, self).__init__(unitclass=self.UnitClass) 189 self.units = [] 190 self.filename = '' 191 self._encoding = encodingToUse(encoding) 192 if inputfile is not None: 193 self.parse(inputfile) 194 else: 195 self.init_headers()
196