Package translate :: Package services :: Module lookupservice

[hide private]
[frames] | no frames]

# Source Code for Module translate.services.lookupservice

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2006 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
     23  """Server program to serve messages over XML-RPC
     24
     25  As this is implemented using the base classes (see storage.base), the
     26  work is minimal to use this with any storage format that is implemented
     27  using the base classes. Strictly speaking, only an init... function needs
     28  to be registered."""
     29
     30  from translate.convert import convert
     31  from translate.storage import tbx
     32  from translate.storage import tmx
     33  from translate.storage import po
     34  from translate.storage import csvl10n
     35  from translate.search import match
     36  from translate.misc.multistring import multistring
     37
     38  from SimpleXMLRPCServer import SimpleXMLRPCServer
     39  from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
     40
     41 -class lookupRequestHandler(SimpleXMLRPCRequestHandler):
     42      """Sets up the requested file for parsing"""
     43      #TODO: Parse request to see if tbx/tmx is requested,
     44      # or perhaps the url can specify the file to be queried
     45
     46 -class lookupServer(SimpleXMLRPCServer):
     47 -    def __init__(self, addr, storage):
     48          """Loads the initial tbx file from the given filename"""
     49          SimpleXMLRPCServer.__init__(self, addr, requestHandler=lookupRequestHandler, logRequests=1)
     50          self.storage = storage
     51          self.storage.makeindex()
     52          self.matcher = match.matcher(storage)
     53          print "Performing lookup from %d units" % len(storage.units)
     54          print "Translation memory using %d units" % len(self.matcher.candidates.units)
     55
     56 -    def _dispatch(self, method, params):
     57          try:
     58              # All public methods must be prefixed with 'public_' so no
     59              # internal methods are callable.
     60              func = getattr(self, 'public_' + method)
     61          except AttributeError:
     62              raise Exception('no method called "%s"' % method)
     63          else:
     64              try:
     65                  return func(*params)
     66              except Exception, e:
     67                  print str(e)
     68                  return ""
     69
     70 -    def internal_lookup(self, message):
     71          """Could perhaps include some intelligence in future, like case trying with different casing, etc."""
     72          message = message.strip()
     73          if message == "":
     74              return None
     75          if not isinstance(message, unicode):
     76              message = unicode(message)
     77          try:
     78              unit = self.storage.findunit(message)
     79          except Exception:
     80              return None
     81          return unit
     82
     83 -    def public_lookup(self, message):
     84          """Returns the source string of whatever was found. Keep in mind that this might not be what you want."""
     85          unit = self.internal_lookup(message)
     86          if unit:
     87              return str(unit)
     88          else:
     89              return ""
     90
     91 -    def public_translate(self, message):
     92          """Translates the message from the storage and returns a plain string"""
     93          unit = self.internal_lookup(message)
     94          if unit and unit.target:
     95              return unit.target
     96          else:
     97              return ""
     98
     99 -    def public_matches(self, message, max_candidates=15, min_similarity=50):
    100          """Returns matches from the storage with the associated similarity"""
    101          self.matcher.setparameters(max_candidates=max_candidates, min_similarity=min_similarity)
    102          if not isinstance(message, unicode):
    103              message = unicode(message)
    104          candidates = self.matcher.matches(message)
    105          clean_candidates = []
    106          for unit in candidates:
    107              score = unit.getnotes()
    108              original = unit.source
    109              translation = unit.target
    110
    111              # We might have gotten multistrings, so just convert them for now
    112              if isinstance(original, multistring):
    113                  original = unicode(original)
    114              if isinstance(translation, multistring):
    115                  translation = unicode(translation)
    116              clean_candidates += [(score, original, translation)]
    117          return clean_candidates
    118
    119 -class lookupOptionParser(convert.ConvertOptionParser):
    120      """Parser that calls instantiates the lookupServer"""
    121 -    def run(self):
    122          """parses arguments and instantiates the server"""
    123          (options, args) = self.parse_args()
    124          options.inputformats = self.inputformats
    125          self.usepsyco(options)
    126          inputbase, inputext = self.splitinputext(options.input)
    127          asdf, storagebuilder = self.outputoptions[inputext, None]
    128          storage = storagebuilder(open(options.input))
    129          server = lookupServer((options.address, int(options.port)), storage)
    130          try:
    131              server.serve_forever()
    132          except:
    133              server.server_close()
    134
    135 -def inittbx(inputfile, columnorder=None):
    136      return tbx.tbxfile(inputfile)
    137
    138 -def inittmx(inputfile, columnorder=None):
    139      return tmx.tmxfile(inputfile)
    140
    141 -def initpo(inputfile, columnorder=None):
    142      return po.pofile(inputfile)
    143
    144 -def initcsv(inputfile, columnorder=None):
    145      return csvl10n.csvfile(inputfile, columnorder)
    146
    147 -def main():
    148      formats = {"tbx": (None, inittbx), "tmx": (None, inittmx), "po": (None, initpo), "csv": (None, initcsv)}
    149      parser = lookupOptionParser(formats, usepots=False, description=__doc__)
    150      parser.add_option("-a", "--address", dest="address", default="localhost",
    151                        help="the host to bind to")
    152      parser.add_option("-p", "--port", dest="port", default=1234,
    153                        help="the port to listen on")
    154      parser.add_option("-l", "--language", dest="targetlanguage", default=None,
    155                        help="set target language code", metavar="LANG")
    156      parser.add_option("", "--source-language", dest="sourcelanguage", default='en',
    157                        help="set source language code", metavar="LANG")
    158      parser.remove_option("--output")
    159      parser.remove_option("--exclude")
    160      parser.passthrough.append("sourcelanguage")
    161      parser.passthrough.append("targetlanguage")
    162      parser.add_option("", "--columnorder", dest="columnorder", default=None,
    163                        help="specify the order and position of columns for CSV (comment,source,target)")
    164      parser.passthrough.append("columnorder")
    165      parser.run()
    166
    167  if __name__ == '__main__':
    168      main()
    169