| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
| 3 # | 3 # |
| 4 # Copyright 2006-2008 Zuza Software Foundation | 4 # Copyright 2006-2008 Zuza Software Foundation |
| 5 # | 5 # |
| 6 # This file is part of translate. | 6 # This file is part of translate. |
| 7 # | 7 # |
| 8 # translate is free software; you can redistribute it and/or modify | 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 | 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 | 10 # the Free Software Foundation; either version 2 of the License, or |
| 11 # (at your option) any later version. | 11 # (at your option) any later version. |
| 12 # | 12 # |
| 13 # translate is distributed in the hope that it will be useful, | 13 # translate is distributed in the hope that it will be useful, |
| 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 # GNU General Public License for more details. | 16 # GNU General Public License for more details. |
| 17 # | 17 # |
| 18 # You should have received a copy of the GNU General Public License | 18 # You should have received a copy of the GNU General Public License |
| 19 # along with translate; if not, write to the Free Software | 19 # along with translate; if not, write to the Free Software |
| 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | 21 |
| 22 """Base classes for storage interfaces. | 22 """Base classes for storage interfaces. |
| 23 | 23 |
| 24 @organization: Zuza Software Foundation | 24 @organization: Zuza Software Foundation |
| 25 @copyright: 2006-2007 Zuza Software Foundation | 25 @copyright: 2006-2007 Zuza Software Foundation |
| 26 @license: U{GPL <http://www.fsf.org/licensing/licenses/gpl.html>} | 26 @license: U{GPL <http://www.fsf.org/licensing/licenses/gpl.html>} |
| 27 """ | 27 """ |
| 28 | 28 |
| 29 try: | 29 try: |
| 30 import cPickle as pickle | 30 import cPickle as pickle |
| 31 except: | 31 except: |
| 32 import pickle | 32 import pickle |
| 33 from exceptions import NotImplementedError | 33 from exceptions import NotImplementedError |
| 34 | 34 |
| 35 def force_override(method, baseclass): | 35 def force_override(method, baseclass): |
| 36 """Forces derived classes to override method.""" | 36 """Forces derived classes to override method.""" |
| 37 | 37 |
| 38 if type(method.im_self) == type(baseclass): | 38 if type(method.im_self) == type(baseclass): |
| 39 # then this is a classmethod and im_self is the actual class | 39 # then this is a classmethod and im_self is the actual class |
| 40 actualclass = method.im_self | 40 actualclass = method.im_self |
| 41 else: | 41 else: |
| 42 actualclass = method.im_class | 42 actualclass = method.im_class |
| 43 if actualclass != baseclass: | 43 if actualclass != baseclass: |
| 44 raise NotImplementedError("%s does not reimplement %s as required by %s"
% (actualclass.__name__, method.__name__, baseclass.__name__)) | 44 raise NotImplementedError("%s does not reimplement %s as required by %s"
% (actualclass.__name__, method.__name__, baseclass.__name__)) |
| 45 | 45 |
| 46 class ParseError(Exception): | 46 class ParseError(Exception): |
| 47 pass | 47 pass |
| 48 | 48 |
| 49 class TranslationUnit(object): | 49 class TranslationUnit(object): |
| 50 """Base class for translation units. | 50 """Base class for translation units. |
| (...skipping 62 matching lines...) Show 10 above Show 10 below |
| 113 return length | 113 return length |
| 114 | 114 |
| 115 def getid(self): | 115 def getid(self): |
| 116 """A unique identifier for this unit. | 116 """A unique identifier for this unit. |
| 117 | 117 |
| 118 @rtype: string | 118 @rtype: string |
| 119 @return: an identifier for this unit that is unique in the store | 119 @return: an identifier for this unit that is unique in the store |
| 120 | 120 |
| 121 Derived classes should override this in a way that guarantees a unique | 121 Derived classes should override this in a way that guarantees a unique |
| 122 identifier for each unit in the store. | 122 identifier for each unit in the store. |
| 123 """ | 123 """ |
| 124 return self.source | 124 return self.source |
| 125 | 125 |
| 126 def getlocations(self): | 126 def getlocations(self): |
| 127 """A list of source code locations. | 127 """A list of source code locations. |
| 128 | 128 |
| 129 @note: Shouldn't be implemented if the format doesn't support it. | 129 @note: Shouldn't be implemented if the format doesn't support it. |
| 130 @rtype: List | 130 @rtype: List |
| 131 | 131 |
| 132 """ | 132 """ |
| 133 | 133 |
| 134 return [] | 134 return [] |
| 135 | 135 |
| 136 def addlocation(self, location): | 136 def addlocation(self, location): |
| 137 """Add one location to the list of locations. | 137 """Add one location to the list of locations. |
| 138 | 138 |
| 139 @note: Shouldn't be implemented if the format doesn't support it. | 139 @note: Shouldn't be implemented if the format doesn't support it. |
| 140 | 140 |
| 141 """ | 141 """ |
| 142 pass | 142 pass |
| 143 | 143 |
| 144 def addlocations(self, location): | 144 def addlocations(self, location): |
| 145 """Add a location or a list of locations. | 145 """Add a location or a list of locations. |
| 146 | 146 |
| 147 @note: Most classes shouldn't need to implement this, | 147 @note: Most classes shouldn't need to implement this, |
| 148 but should rather implement L{addlocation()}. | 148 but should rather implement L{addlocation()}. |
| 149 @warning: This method might be removed in future. | 149 @warning: This method might be removed in future. |
| 150 | 150 |
| 151 """ | 151 """ |
| 152 | 152 |
| 153 if isinstance(location, list): | 153 if isinstance(location, list): |
| 154 for item in location: | 154 for item in location: |
| 155 self.addlocation(item) | 155 self.addlocation(item) |
| 156 else: | 156 else: |
| 157 self.addlocation(location) | 157 self.addlocation(location) |
| 158 | 158 |
| 159 def getcontext(self): | 159 def getcontext(self): |
| 160 """Get the message context.""" | 160 """Get the message context.""" |
| 161 return "" | 161 return "" |
| 162 | 162 |
| 163 def setcontext(self, context): |
| 164 """Sets the message context""" |
| 165 pass |
| 166 |
| 163 def getnotes(self, origin=None): | 167 def getnotes(self, origin=None): |
| 164 """Returns all notes about this unit. | 168 """Returns all notes about this unit. |
| 165 | 169 |
| 166 It will probably be freeform text or something reasonable that can be | 170 It will probably be freeform text or something reasonable that can be |
| 167 synthesised by the format. | 171 synthesised by the format. |
| 168 It should not include location comments (see L{getlocations()}). | 172 It should not include location comments (see L{getlocations()}). |
| 169 | 173 |
| 170 """ | 174 """ |
| 171 return getattr(self, "notes", "") | 175 return getattr(self, "notes", "") |
| 172 | 176 |
| 173 def addnote(self, text, origin=None): | 177 def addnote(self, text, origin=None): |
| 174 """Adds a note (comment). | 178 """Adds a note (comment). |
| 175 | 179 |
| 176 @type text: string | 180 @type text: string |
| 177 @param text: Usually just a sentence or two. | 181 @param text: Usually just a sentence or two. |
| 178 @type origin: string | 182 @type origin: string |
| 179 @param origin: Specifies who/where the comment comes from. | 183 @param origin: Specifies who/where the comment comes from. |
| 180 Origin can be one of the following text strings: | 184 Origin can be one of the following text strings: |
| 181 - 'translator' | 185 - 'translator' |
| 182 - 'developer', 'programmer', 'source code' (synonyms) | 186 - 'developer', 'programmer', 'source code' (synonyms) |
| 183 | 187 |
| 184 """ | 188 """ |
| 185 if getattr(self, "notes", None): | 189 if getattr(self, "notes", None): |
| 186 self.notes += '\n'+text | 190 self.notes += '\n'+text |
| 187 else: | 191 else: |
| 188 self.notes = text | 192 self.notes = text |
| 189 | 193 |
| 190 def removenotes(self): | 194 def removenotes(self): |
| 191 """Remove all the translator's notes.""" | 195 """Remove all the translator's notes.""" |
| 192 | 196 |
| 193 self.notes = u'' | 197 self.notes = u'' |
| 194 | 198 |
| 195 def adderror(self, errorname, errortext): | 199 def adderror(self, errorname, errortext): |
| 196 """Adds an error message to this unit. | 200 """Adds an error message to this unit. |
| 197 | 201 |
| 198 @type errorname: string | 202 @type errorname: string |
| 199 @param errorname: A single word to id the error. | 203 @param errorname: A single word to id the error. |
| 200 @type errortext: string | 204 @type errortext: string |
| 201 @param errortext: The text describing the error. | 205 @param errortext: The text describing the error. |
| 202 | 206 |
| 203 """ | 207 """ |
| 204 | 208 |
| 205 pass | 209 pass |
| 206 | 210 |
| 207 def geterrors(self): | 211 def geterrors(self): |
| 208 """Get all error messages. | 212 """Get all error messages. |
| 209 | 213 |
| 210 @rtype: Dictionary | 214 @rtype: Dictionary |
| 211 | 215 |
| 212 """ | 216 """ |
| (...skipping 247 matching lines...) Show 10 above Show 10 below |
| 460 return newstore | 464 return newstore |
| 461 parsestring = classmethod(parsestring) | 465 parsestring = classmethod(parsestring) |
| 462 | 466 |
| 463 def parse(self, data): | 467 def parse(self, data): |
| 464 """parser to process the given source string""" | 468 """parser to process the given source string""" |
| 465 self.units = pickle.loads(data).units | 469 self.units = pickle.loads(data).units |
| 466 | 470 |
| 467 def savefile(self, storefile): | 471 def savefile(self, storefile): |
| 468 """Writes the string representation to the given file (or filename).""" | 472 """Writes the string representation to the given file (or filename).""" |
| 469 if isinstance(storefile, basestring): | 473 if isinstance(storefile, basestring): |
| 470 storefile = open(storefile, "w") | 474 storefile = open(storefile, "w") |
| 471 self.fileobj = storefile | 475 self.fileobj = storefile |
| 472 self._assignname() | 476 self._assignname() |
| 473 storestring = str(self) | 477 storestring = str(self) |
| 474 storefile.write(storestring) | 478 storefile.write(storestring) |
| 475 storefile.close() | 479 storefile.close() |
| 476 | 480 |
| 477 def save(self): | 481 def save(self): |
| 478 """Save to the file that data was originally read from, if available.""" | 482 """Save to the file that data was originally read from, if available.""" |
| 479 fileobj = getattr(self, "fileobj", None) | 483 fileobj = getattr(self, "fileobj", None) |
| 480 if not fileobj: | 484 if not fileobj: |
| 481 filename = getattr(self, "filename", None) | 485 filename = getattr(self, "filename", None) |
| 482 if filename: | 486 if filename: |
| 483 fileobj = file(filename, "w") | 487 fileobj = file(filename, "w") |
| 484 else: | 488 else: |
| 485 fileobj.close() | 489 fileobj.close() |
| 486 filename = getattr(fileobj, "name", getattr(fileobj, "filename", Non
e)) | 490 filename = getattr(fileobj, "name", getattr(fileobj, "filename", Non
e)) |
| 487 if not filename: | 491 if not filename: |
| 488 raise ValueError("No file or filename to save to") | 492 raise ValueError("No file or filename to save to") |
| 489 fileobj = fileobj.__class__(filename, "w") | 493 fileobj = fileobj.__class__(filename, "w") |
| 490 self.savefile(fileobj) | 494 self.savefile(fileobj) |
| 491 | 495 |
| 492 def parsefile(cls, storefile): | 496 def parsefile(cls, storefile): |
| 493 """Reads the given file (or opens the given filename) and parses back to
an object.""" | 497 """Reads the given file (or opens the given filename) and parses back to
an object.""" |
| 494 | 498 |
| 495 if isinstance(storefile, basestring): | 499 if isinstance(storefile, basestring): |
| 496 storefile = open(storefile, "r") | 500 storefile = open(storefile, "r") |
| 497 mode = getattr(storefile, "mode", "r") | 501 mode = getattr(storefile, "mode", "r") |
| 498 #For some reason GzipFile returns 1, so we have to test for that here | 502 #For some reason GzipFile returns 1, so we have to test for that here |
| 499 if mode == 1 or "r" in mode: | 503 if mode == 1 or "r" in mode: |
| 500 storestring = storefile.read() | 504 storestring = storefile.read() |
| 501 storefile.close() | 505 storefile.close() |
| 502 else: | 506 else: |
| 503 storestring = "" | 507 storestring = "" |
| 504 newstore = cls.parsestring(storestring) | 508 newstore = cls.parsestring(storestring) |
| 505 newstore.fileobj = storefile | 509 newstore.fileobj = storefile |
| 506 newstore._assignname() | 510 newstore._assignname() |
| 507 return newstore | 511 return newstore |
| 508 parsefile = classmethod(parsefile) | 512 parsefile = classmethod(parsefile) |
| 509 | 513 |
| OLD | NEW |