Package translate :: Package storage :: Module omegat

[hide private]
[frames] | no frames]

# Source Code for Module translate.storage.omegat

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2009 Zuza Software Foundation
      5  #
      6  # This file is part of the Translate Toolkit.
      7  #
      8  # This program 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  # This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
     20
     21  """Manage the OmegaT glossary format
     22
     23     OmegaT glossary format is used by the
     24     U{OmegaT<http://www.omegat.org/en/omegat.html>} computer aided
     25     translation tool.
     26
     27     It is a bilingual base class derived format with L{OmegaTFile}
     28     and L{OmegaTUnit} providing file and unit level access.
     29
     30     Format Implementation
     31     =====================
     32     The OmegaT glossary format is a simple Tab Separated Value (TSV) file
     33     with the columns: source, target, comment.
     34
     35     The dialect of the TSV files is specified by L{OmegaTDialect}.
     36
     37     Encoding
     38     --------
     39     The files are either UTF-8 or encoded using the system default.  UTF-8
     40     encoded files use the .utf8 extension while system encoded files use
     41     the .tab extension.
     42  """
     43
     44  import csv
     45  import locale
     46  import os.path
     47  import sys
     48  import time
     49  from translate.storage import base
     50
     51  OMEGAT_FIELDNAMES = ["source", "target", "comment"]
     52  """Field names for an OmegaT glossary unit"""
     53
     54
     55 -class OmegaTDialect(csv.Dialect):
     56      """Describe the properties of an OmegaT generated TAB-delimited file."""
     57      delimiter = "\t"
     58      lineterminator = "\r\n"
     59      quoting = csv.QUOTE_NONE
     60      if sys.version_info < (2, 5, 0):
     61          # We need to define the following items for csv in Python < 2.5
     62          quoting = csv.QUOTE_MINIMAL   # OmegaT does not quote anything FIXME So why MINIMAL?
     63          doublequote = False
     64          skipinitialspace = False
     65          escapechar = None
     66          quotechar = '"'
     67  csv.register_dialect("omegat", OmegaTDialect)
     68
     69 -class OmegaTUnit(base.TranslationUnit):
     70      """An OmegaT translation memory unit"""
     71 -    def __init__(self, source=None):
     72          self._dict = {}
     73          if source:
     74              self.source = source
     75          super(OmegaTUnit, self).__init__(source)
     76
     77 -    def getdict(self):
     78          """Get the dictionary of values for a OmegaT line"""
     79          return self._dict
     80
     81 -    def setdict(self, newdict):
     82          """Set the dictionary of values for a OmegaT line
     83
     84          @param newdict: a new dictionary with OmegaT line elements
     85          @type newdict: Dict
     86          """
     87          # TODO First check that the values are OK
     88          self._dict = newdict
     89      dict = property(getdict, setdict)
     90
     91 -    def _get_field(self, key):
     92          if key not in self._dict:
     93              return None
     94          elif self._dict[key]:
     95              return self._dict[key].decode('utf-8')
     96          else:
     97              return ""
     98
     99 -    def _set_field(self, key, newvalue):
    100          if newvalue is None:
    101              self._dict[key] = None
    102          if isinstance(newvalue, unicode):
    103              newvalue = newvalue.encode('utf-8')
    104          if not key in self._dict or newvalue != self._dict[key]:
    105              self._dict[key] = newvalue
    106
    107 -    def getnotes(self, origin=None):
    108          return self._get_field('comment')
    109
    110 -    def getsource(self):
    111          return self._get_field('source')
    112
    113 -    def setsource(self, newsource):
    114          self._rich_source = None
    115          return self._set_field('source', newsource)
    116      source = property(getsource, setsource)
    117
    118 -    def gettarget(self):
    119          return self._get_field('target')
    120
    121 -    def settarget(self, newtarget):
    122          self._rich_target = None
    123          return self._set_field('target', newtarget)
    124      target = property(gettarget, settarget)
    125
    126 -    def settargetlang(self, newlang):
    127          self._dict['target-lang'] = newlang
    128      targetlang = property(None, settargetlang)
    129
    130 -    def __str__(self):
    131          return str(self._dict)
    132
    133 -    def istranslated(self):
    134          return bool(self._dict.get('target', None))
    135
    136
    137 -class OmegaTFile(base.TranslationStore):
    138      """An OmegaT translation memory file"""
    139      Name = _("OmegaT Glossary")
    140      Mimetypes  = ["application/x-omegat-glossary"]
    141      Extensions = ["utf8"]
    142 -    def __init__(self, inputfile=None, unitclass=OmegaTUnit):
    143          """Construct an OmegaT glossary, optionally reading in from inputfile."""
    144          self.UnitClass = unitclass
    145          base.TranslationStore.__init__(self, unitclass=unitclass)
    146          self.filename = ''
    147          self.extension = ''
    148          self._encoding = self._get_encoding()
    149          if inputfile is not None:
    150              self.parse(inputfile)
    151
    152 -    def _get_encoding(self):
    153          return 'utf-8'
    154
    155 -    def parse(self, input):
    156          """parsese the given file or file source string"""
    157          if hasattr(input, 'name'):
    158              self.filename = input.name
    159          elif not getattr(self, 'filename', ''):
    160              self.filename = ''
    161          if hasattr(input, "read"):
    162              tmsrc = input.read()
    163              input.close()
    164              input = tmsrc
    165          try:
    166              input = input.decode(self._encoding).encode('utf-8')
    167          except:
    168              raise ValueError("OmegaT files are either UTF-8 encoded or use the default system encoding")
    169          lines = csv.DictReader(input.split("\n"), fieldnames=OMEGAT_FIELDNAMES, dialect="omegat")
    170          for line in lines:
    171              newunit = OmegaTUnit()
    172              newunit.dict = line
    173              self.addunit(newunit)
    174
    175 -    def __str__(self):
    176          output = csv.StringIO()
    177          writer = csv.DictWriter(output, fieldnames=OMEGAT_FIELDNAMES, dialect="omegat")
    178          unit_count = 0
    179          for unit in self.units:
    180              if unit.istranslated():
    181                  unit_count += 1
    182                  writer.writerow(unit.dict)
    183          if unit_count == 0:
    184              return ""
    185          output.reset()
    186          decoded = "".join(output.readlines()).decode('utf-8')
    187          try:
    188              return decoded.encode(self._encoding)
    189          except UnicodeEncodeError:
    190              return decoded.encode('utf-8')
    191
    192 -class OmegaTFileTab(OmegaTFile):
    193      """An OmegT translation memory file in the default system encoding"""
    194      # FIXME: uncomment this when we next open from string freeze
    195      #Name = _("OmegaT Glossary")
    196      Name = None
    197      Mimetypes  = ["application/x-omegat-glossary"]
    198      Extensions = ["tab"]
    199
    200 -    def _get_encoding(self):
    201          return locale.getdefaultlocale()[1]
    202