# vim:sw=4:et
"""build_pot

Build a PO template (for i18n) and update the .po files to reflect
the last changes.
"""

from distutils.core import Command
from commands import getstatus
import sys, os.path
import pygettext

# from pygettext.main():
class Options:
    # constants
    GNU = 1
    SOLARIS = 2
    # defaults
    extractall = 0 # FIXME: currently this option has no effect at all.
    keywords = []
    writelocations = 1
    locationstyle = GNU
    verbose = 0
    width = 78
    excludefilename = ''
    docstrings = 0
    nodocstrings = {}
    toexclude = []


class build_pot(Command):

    description="Generate a .po template file (.pot) from python source files"

    user_options = [('msgmerge=', None, 'location of the msgmerge program'),
                    ('extract-all', 'a', ''),
	            ('default-domain=', 'd', ''),
		    ('escape', 'E', ''),
		    ('docstrings', 'D', ''),
		    ('keyword=', 'k', 'Comma separated list of keywords'),
		    ('no-default-keywords', 'K', ''),
		    ('add-location', 'n', ''),
		    ('no-location', None, ''),
		    ('style=', 'S', 'POT file style "gnu" or "solaris"'),
		    ('output=', 'o', ''),
		    ('output-dir=', 'p', ''),
		    ('width=', 'w', ''),
		    ('exclude-file=', 'x', ''),
		    ('all-linguas=', None, ''),
		    #('no-docstrings=', 'X', ''),
    ]

    boolean_options = [ 'extract-all', 'escape', 'docstrings',
			'no-default-keywords', 'add-location',
			'no-location', 'no-docstrings' ]

    # constants
    GNU = 1
    SOLARIS = 2

    def initialize_options(self):
	self.podir = 'po'
	self.msgmerge = 'msgmerge'

	self.options = Options()

	# defaults for variable parsing:
        self.escape = 0
        self.width = 78
	self.extract_all = 0 # doesn't do anything yet
	self.default_domain = None
	self.keyword = None
	self.no_default_keywords = 0
	self.no_location = 0
	self.style = None
	self.output = None
	self.output_dir = None
        self.docstrings = 0
	self.exclude_file = None
	#self.no_docstrings = None
        self.all_linguas = []

    def finalize_options(self):
	options = self.options

	self.name = self.distribution.get_name()

	# Build default options for the TokenEater
	if self.default_domain:
	    self.output = self.default_domain + '.pot'
	if self.keyword:
	    options.keywords.extend(self.keyword.split(','))
	if self.no_default_keywords:
	    options.keywords = [ ]
	if self.no_location:
	    options.writelocations = 0
	if self.style:
	    if self.style == 'gnu':
		options.locationstyle = self.GNU
	    elif self.style == 'solaris':
		options.locationstyle = self.SOLARIS
	    else:
		raise SystemExit, 'Invalid value for --style: %s' % self.style
	if not self.output:
	    self.output = self.distribution.get_name() + '.pot'
	if not self.output_dir:
	    self.output_dir = self.podir
	if self.docstrings:
	    options.docstrings = 1
	options.width = int(self.width)
	if self.exclude_file:
	    try:
		fp = open(self.exclude_file)
		options.toexclude = fp.readlines()
		fp.close()
	    except IOError:
		raise SystemExit, "Can't read --exclude-file: %s" % self.exclude_file
	# skip: self.no_docstrings
        if self.all_linguas:
            self.all_linguas = self.all_linguas.split(',')

	# calculate escapes
	pygettext.make_escapes(self.escape)

	# calculate all keywords
	options.keywords.append('_')

	if self.output_dir:
	    self.output = os.path.join(self.output_dir, self.output)

	self.packages = self.distribution.packages
	#self.all_linguas = self.distribution.get_all_linguas()
	#self.all_linguas = self.distribution.options['po']['all_linguas']

    def run(self):
	self.create_pot_file()
	self.merge_files()

    def create_pot_file(self):
	"""
        Create a new .pot file. This is basically a rework of the
	main function of pygettext.
        """
	import glob
	import tokenize
	source_files = []
	for p in self.packages:
	    pathlist = p.split('.')
	    path = apply(os.path.join, pathlist)
	    source_files.extend(glob.glob(os.path.join(path, '*.py')))

	# slurp through all the files
	eater = pygettext.TokenEater(self.options)
	for filename in source_files:
	    if self.verbose:
		print 'Working on %s' % filename
	    fp = open(filename)
	    try:
		eater.set_filename(filename)
		try:
		    tokenize.tokenize(fp.readline, eater)
		except tokenize.TokenError, e:
		    print '%s: %s, line %d, column %d' % (
			e[0], filename, e[1][0], e[1][1])
	    finally:
		fp.close()

	# write the output
	if self.output == '-':
	    fp = sys.stdout
	else:
	    fp = open(self.output, 'w')
	try:
	    eater.write(fp)
	finally:
	    if fp is not sys.stdout:
		fp.close()

    def merge_files(self):
	if not self.all_linguas:
	    return

	for lingua in self.all_linguas:
	    d = { 'msgmerge': self.msgmerge,
		  'po': os.path.join(self.output_dir, lingua + '.po'),
		  'pot': self.output
	    }
	    if self.verbose:
		sys.stdout.write('Merging %(pot)s and %(po)s ' % d)
                sys.stdout.flush()
	    res = os.system('%(msgmerge)s %(po)s %(pot)s -o %(po)s' % d)
	    if res:
		SystemExit, 'error while running msgmerge.'