#!/usr/bin/python
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

#
# Typical usage:
# dohtml -r docs/*
#  - put all files and directories in docs into /usr/share/doc/${PF}/html
# dohtml foo.html
#  - put foo.html into /usr/share/doc/${PF}/html
#
#
# Detailed usage:
# dohtml <list-of-files> 
#  - will install the files in the list of files (space-separated list) into 
#    /usr/share/doc/${PF}/html, provided the file ends in .htm, .html, .css,
#      .js, ,gif, .jpeg, .jpg, or .png.
# dohtml -r <list-of-files-and-directories>
#  - will do as 'dohtml', but recurse into all directories, as long as the 
#    directory name is not CVS
# dohtml -A jpe,java [-r] <list-of-files[-and-directories]>
#  - will do as 'dohtml' but add .jpe,.java (default filter list is
#    added to your list)
# dohtml -a png,gif,html,htm [-r] <list-of-files[-and-directories]>
#  - will do as 'dohtml' but filter on .png,.gif,.html,.htm (default filter 
#    list is ignored)
# dohtml -x CVS,SCCS,RCS -r <list-of-files-and-directories>
#  - will do as 'dohtml -r', but ignore directories named CVS, SCCS, RCS
#

import os
import sys
import types

def dodir(path):
	os.spawnlp(os.P_WAIT, "install", "install", "-d", path)

def dofile(src,dst):
	os.spawnlp(os.P_WAIT, "install", "install", "-m0644", src, dst)

def eqawarn(lines):
	cmd = "source '%s/isolated-functions.sh' ; " % \
		os.environ["PORTAGE_BIN_PATH"]
	for line in lines:
		cmd += "eqawarn \"%s\" ; " % line
	os.spawnlp(os.P_WAIT, "bash", "bash", "-c", cmd)

skipped_directories = []

def install(basename, dirname, options, prefix=""):
	fullpath = basename
	if prefix:
		fullpath = prefix + "/" + fullpath
	if dirname:
		fullpath = dirname + "/" + fullpath

	if options.DOCDESTTREE:
		destdir = options.D + "usr/share/doc/" + options.PF + "/" + options.DOCDESTTREE + "/" + options.doc_prefix + "/" + prefix
	else:
		destdir = options.D + "usr/share/doc/" + options.PF + "/html/" + options.doc_prefix + "/" + prefix

	if os.path.isfile(fullpath):
		ext = os.path.splitext(basename)[1]
		if (len(ext) and ext[1:] in options.allowed_exts) or basename in options.allowed_files:
			dodir(destdir)
			dofile(fullpath, destdir + "/" + basename)
	elif options.recurse and os.path.isdir(fullpath) and \
	     basename not in options.disallowed_dirs:
		for i in os.listdir(fullpath):
			pfx = basename
			if prefix: pfx = prefix + "/" + pfx
			install(i, dirname, options, pfx)
	elif not options.recurse and os.path.isdir(fullpath):
		global skipped_directories
		skipped_directories.append(fullpath)
		return False
	else:
		return False
	return True


class OptionsClass:
	def __init__(self):
		self.PF = ""
		self.D = ""
		self.DOCDESTTREE = ""
		
		if "PF" in os.environ:
			self.PF = os.environ["PF"]
		if "D" in os.environ:
			self.D = os.environ["D"]
		if "_E_DOCDESTTREE_" in os.environ:
			self.DOCDESTTREE = os.environ["_E_DOCDESTTREE_"]
		
		self.allowed_exts = [ 'htm', 'html', 'css', 'js',
			'gif', 'jpeg', 'jpg', 'png' ]
		self.allowed_files = []
		self.disallowed_dirs = [ 'CVS' ]
		self.recurse = False
		self.verbose = False
		self.doc_prefix = ""

def print_help():
	opts = OptionsClass()

	print "dohtml [-a .foo,.bar] [-A .foo,.bar] [-f foo,bar] [-x foo,bar]"
	print "       [-r] [-V] <file> [file ...]"
	print
	print " -a   Set the list of allowed to those that are specified."
	print "      Default:", ",".join(opts.allowed_exts)
	print " -A   Extend the list of allowed file types."
	print " -f   Set list of allowed extensionless file names."
	print " -x   Set directories to be excluded from recursion."
	print "      Default:", ",".join(opts.disallowed_dirs)
	print " -p   Set a document prefix for installed files (empty by default)."
	print " -r   Install files and directories recursively."
	print " -V   Be verbose."
	print

def parse_args():
	options = OptionsClass()
	args = []
	
	x = 1
	while x < len(sys.argv):
		arg = sys.argv[x]
		if arg in ["-h","-r","-V"]:
			if arg == "-h":
				print_help()
				sys.exit(0)
			elif arg == "-r":
				options.recurse = True
			elif arg == "-V":
				options.verbose = True
		elif sys.argv[x] in ["-A","-a","-f","-x","-p"]:
			x += 1
			if x == len(sys.argv):
				print_help()
				sys.exit(0)
			elif arg == "-p":
				options.doc_prefix = sys.argv[x]
			else:
				values = sys.argv[x].split(",")
				if arg == "-A":
					options.allowed_exts.extend(values)
				elif arg == "-a":
					options.allowed_exts = values
				elif arg == "-f":
					options.allowed_files = values
				elif arg == "-x":
					options.disallowed_dirs = values
		else:
			args.append(sys.argv[x])
		x += 1
	
	return (options, args)

def main():

	(options, args) = parse_args()

	if type(options.allowed_exts) == types.StringType:
		options.allowed_exts = options.allowed_exts.split(",")

	if options.verbose:
		print "Allowed extensions:", options.allowed_exts
		print "Document prefix : '" + options.doc_prefix	 + "'"
		print "Allowed files :", options.allowed_files

	success = False
	
	for x in args:
		basename = os.path.basename(x)
		dirname  = os.path.dirname(x)
		success |= install(basename, dirname, options)

	if success:
		retcode = 0
	else:
		retcode = 1
		global skipped_directories
		for x in skipped_directories:
			eqawarn(["QA Notice: dohtml on directory " + \
				"'%s' without recursion option" % x])

	sys.exit(retcode)

if __name__ == "__main__":
	main()
