#!/usr/bin/python
# 
# Copyright 2002, 2003 Zuza Software Foundation
# 
# This file is part of translate.
#
# translate is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# translate is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with translate; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"""script that converts a set of .po files to a set of .dtd and .properties files
either done using a template or just using the .po file"""

import os.path
import sys
from translate.convert import po2dtd
from translate.convert import po2prop
from translate.storage import xpi
from translate import __version__
from translate.convert import convert
import StringIO

class MozConvertOptionParser(convert.ConvertOptionParser):
  def __init__(self, formats, usetemplates=False, usepots=False):
    convert.ConvertOptionParser.__init__(self, formats, usetemplates, usepots)

  def isrecursive(self, fileoption):
    """checks if fileoption is a recursive file"""
    if self.isxpi(fileoption): return True
    return super(MozConvertOptionParser, self).isrecursive(fileoption)

  def isxpi(self, fileoption):
    """returns whether the file option is an xpi file"""
    return isinstance(fileoption, (str, unicode)) and fileoption.endswith(os.extsep + "xpi") and os.path.isfile(fileoption)

  def recurseconversion(self, options):
    """recurse through directories and convert files"""
    if options.template and self.isxpi(options.template):
      options.templatexpi = xpi.XpiFile(options.template, includenonloc=True)
    if options.output and options.output.endswith(os.extsep + "xpi"):
      if self.isxpi(options.template):
        options.outputxpi = options.templatexpi.clone(options.output, "a")
      else:
        options.outputxpi = xpi.XpiFile(options.output)
    result = super(MozConvertOptionParser, self).recurseconversion(options)
    if self.isxpi(options.output):
      options.outputxpi.close()
    return result

  def getfulloutputpath(self, options, outputpath):
    """gets the absolute path to an output file"""
    if self.isxpi(options.output):
      return outputpath
    else:
      return os.path.join(options.output, outputpath)

  def checkoutputsubdir(self, options, subdir):
    """checks to see if subdir under options.output needs to be created, creates if neccessary"""
    if not self.isxpi(options.output):
      super(MozConvertOptionParser, self).checkoutputsubdir(options, subdir)

  def openoutputfile(self, options, fulloutputpath):
    """opens the output file"""
    if self.isxpi(options.output):
      try:
        jarfilename, filename = options.outputxpi.ostojarpath(fulloutputpath)
      except IndexError:
        self.warning("Could not find where to put %s in output xpi; writing to tmp" % fulloutputpath)
        return StringIO.StringIO()
      return options.outputxpi.openoutputstream(jarfilename, filename)
    else:
      return super(MozConvertOptionParser, self).openoutputfile(options, fulloutputpath)

  def convertfile(self, convertmethod, options, fullinputpath, fulloutputpath, fulltemplatepath):
    """run an invidividual conversion"""
    if self.isxpi(options.output):
      inputfile = self.openinputfile(options, fullinputpath)
      # TODO: handle writing back to same xpi as input/template
      templatefile = self.opentemplatefile(options, fulltemplatepath)
      outputfile = self.openoutputfile(options, fulloutputpath)
      requiredoptions = self.getrequiredoptions(options)
      if convertmethod(inputfile, outputfile, templatefile, **requiredoptions):
        return True
      else:
        outputfile.close()
        os.unlink(fulloutputpath)
        return False
    else:
      return super(MozConvertOptionParser, self).convertfile(convertmethod, options, fullinputpath, fulloutputpath, fulltemplatepath)

  def opentemplatefile(self, options, fulltemplatepath):
    """opens the template file (if required)"""
    if fulltemplatepath is not None:
      if self.isxpi(options.template):
        # TODO: deal with different names in input/template xpis
        jarfilename, filename = options.templatexpi.ostojarpath(fulltemplatepath)
        if options.templatexpi.jarfileexists(jarfilename, filename):
          return options.templatexpi.openinputstream(jarfilename, filename)
        else:
          self.warning("missing template file %s" % fulltemplatepath)
    return super(MozConvertOptionParser, self).opentemplatefile(options, fulltemplatepath)

  def getfulltemplatepath(self, options, templatepath):
    """gets the absolute path to a template file"""
    if templatepath is not None and self.usetemplates and options.template:
      if self.isxpi(options.template):
        return templatepath
      else:
        return os.path.join(options.template, templatepath)
    else:
      return None

  def splitinputext(self, inputpath):
    """splits a inputpath into name and extension"""
    d, n = os.path.dirname(inputpath), os.path.basename(inputpath)
    s = n.find(".")
    if s == '-1':
      return (inputpath, "")
    root = os.path.join(d, n[:s])
    ext = n[s+1:]
    return (root, ext)

  def templateexists(self, options, templatepath):
    """returns whether the given template exists..."""
    if templatepath is not None:
      if self.isxpi(options.template):
        # TODO: deal with different names in input/template xpis
        try:
          jarfilename, filename = options.templatexpi.ostojarpath(templatepath)
        except IndexError:
          return False
        return options.templatexpi.jarfileexists(jarfilename, filename)
    return super(MozConvertOptionParser, self).templateexists(options, templatepath)

if __name__ == '__main__':
  # handle command line options
  formats = {("dtd.po", "dtd"): ("dtd", po2dtd.convertdtd),
             ("properties.po", "properties"): ("properties", po2prop.convertprop),
             (None, "*"): ("*", convert.copytemplate),
             ("*", "*"): ("*", convert.copyinput),
             "*": ("*", convert.copyinput)}
  nochecksoption = convert.optparse.Option("", "--nochecks", dest="showchecks",
    action="store_false", default=True, help="don't run and output results of checks")
  parser = MozConvertOptionParser(formats, usetemplates=True)
  parser.add_option(nochecksoption)
  parser.convertparameters.append("showchecks")
  parser.runconversion()

