#!/usr/bin/python
#
# e-package-themes.py
#
#   Fetch E17 themes from exchange.enlightenment.org
#   and build packages for each of them.
#
# author: Falko Schmidt <kaethorn@gmail.com>
# date: Wed Dec  3 11:09:22 UTC 2008
#

from optparse import OptionParser
from time import strftime
import os, sys, re, string
import httplib
import socket
import urllib

desc="Package builder for E17 themes"
version="0.1"
author="Falko Schmidt <kaethorn@gmail.com>"
progname=os.path.basename(sys.argv[0])
parser = OptionParser(usage="usage: %s [options]\n%s\n(version: %s, author: %s, license: BSD)\n"%(progname,desc,version,author))
parser.add_option("-o", "--output", type="string", default="./", dest="outdir", help="directory used for resulting packages and temporary files")
parser.add_option("-u", "--url", type="string", default="http://exchange.enlightenment.org", dest="srcurl", help="URL to the enlightenment exchange site")
(options, args) = parser.parse_args()



themeurls = []
themedebs = []


def fetch_theme_urls():
	try:
		url = urllib.urlopen(options.srcurl+'/themeGroup/show/2514?limit=100')
	except (IOError), err:
		print "An error occured while attempting to connect to "+options.srcurl+":\n  "+str(err)
		sys.exit(1)
	pattern = re.compile('\s*<a href="(/theme/show/\d+)">[a-zA-Z0-9_ ]+</a>\s*')
	for line in url.readlines():
		match = pattern.match(line)
		if match:
			themeurls.append(match.group(1))
	url.close()


def fill_debian_control_files(theme):
	try:
		url = urllib.urlopen(theme)
	except (IOError), err:
		print "An error occured while attempting to connect to "+theme+":\n  "+str(err)
		sys.exit(1)
	theme_html = url.read()
	
	# Parse the theme's page and fill in fields of a
	# Debian control file. Create directories if needed.
	deb_name_pattern = re.compile('<h1>([a-zA-Z0-9_ ]+)</h1>')
	deb_desc_pattern = re.compile('<div class="description">\n(.*?)</div>', re.DOTALL)
	deb_name_match = deb_name_pattern.search(theme_html)
	deb_desc_match = deb_desc_pattern.search(theme_html)
	deb_name = ''
	deb_desc = ''
	if deb_name_match:
		deb_name = deb_name_match.group(1)
	else:
		print "Error: no name found (did the HTML code change?)"
		sys.exit(1)
	if deb_desc_match:
		deb_desc = deb_desc_match.group(1)
	else:
		print "Error: no description found (did the HTML code change?)"
		sys.exit(1)
	
	deb_name_corrected = deb_name.lower().strip().replace(' ', '-')
	tags_pattern = re.compile('<.*?>')
	br_tags_pattern = re.compile('\s*<br.{0,2}>\s*')
	
	# Format the description by inserting newlines and removing
	# ugly white spaces.
	deb_desc_corrected = ''
	deb_desc_corrected_new = ''
	deb_desc_corrected = deb_desc.strip()
	deb_desc_corrected = br_tags_pattern.sub(r'\n', deb_desc_corrected)
	deb_desc_corrected = tags_pattern.sub('', deb_desc_corrected)
	
	for line in deb_desc_corrected.splitlines():
                #tline = line
                tline = line.strip()
                length = len(tline)     
                if length > 70:
                        pos = 0
                        while (length - pos) > 70:
                                spacepos = tline.rfind(' ', pos, pos+70)
				if spacepos == -1: spacepos = pos+70
                                deb_desc_corrected_new += tline[pos:spacepos]+'\n '
                                pos = spacepos+1
                        deb_desc_corrected_new += tline[pos:length]+'\n '
                else:
                        # Add dots to empty lines.
                        if tline.strip() == '':
                                deb_desc_corrected_new += '.\n '
                        else:
                                deb_desc_corrected_new += tline+'\n '
        deb_desc_corrected = deb_desc_corrected_new

        # Replace any crufty dots
        deb_desc_corrected = re.sub(r'[.]{2}\n', r'.\n', deb_desc_corrected)
        # Add a dot at the end if it doesn't yet exist
        if deb_desc_corrected[len(deb_desc_corrected)-3] != '.':
		deb_desc_corrected = deb_desc_corrected[0:len(deb_desc_corrected)-2]+'.\n'

        control_file=open('e17-themes/debian/control', 'a')
        control_file.write('Package: e17-theme-'+deb_name_corrected+'\nArchitecture: any\nDepends: e17\nDescription: The '+deb_name+' theme for E17\n A theme for the E17 desktop shell, obtained from\n http://exchange.enlightenment.org.\n .\n '+deb_desc_corrected+'\n')
	control_file.close()
	
	themedebs.append(deb_name_corrected)
	print " * "+deb_name


def create_debian_files():
	if os.path.exists("e17-themes"):
		yesno = raw_input("The directory \'e17-themes\' already exists. Continuing will erease all its content. Are you sure?\n(Y/N) ")
		if not yesno.strip() == "Y" and not yesno.strip() == "y":
			print yesno
			exit(0)
		else:
			# delete the directory and all its content
			try:
				for root, dirs, files in os.walk('e17-themes', topdown=False):
					for name in files:
						os.remove(os.path.join(root, name))
					for name in dirs:
						os.rmdir(os.path.join(root, name))
				os.rmdir('e17-themes')
			except Exception, err:
				print "An error occured trying to delete the directory \'e17-themes\':\n  "+str(err)
				sys.exit(1)
	try:
		os.makedirs("e17-themes/debian",0755)
	except Exception, err:
		print "An error occured trying to create the directories \'e17-themes/debian\':\n  "+str(err)
		sys.exit(1)

	control_file=open('e17-themes/debian/control','w')
	control_file.write('Source: e17-themes\nSection: x11\nPriority: optional\nMaintainer: Falko Schmidt <falko@alphagemini.org>\nBuild-Depends: debhelper (>= 6), cdbs\nStandards-Version: 3.7.3\nHomepage: http://exchange.enlightenment.org\n\n')
	control_file.close()
	
	changelog_file=open('e17-themes/debian/changelog','w')
	timestr = strftime("%a, %d %b %Y %H:%M:%S")
	changelog_file.write('e17-themes (0.1-0) unstable; urgency=low\n\n  Last fetched on '+timestr+'.\n\n -- Falko Schmidt <falko@alphagemini.org>  '+timestr+' +0000')
	changelog_file.close()

	rules_file=open('e17-themes/debian/rules','w')
	rules_file.write('#!/usr/bin/make -f\n\ninclude /usr/share/cdbs/1/rules/debhelper.mk\ninclude /usr/share/cdbs/1/class/makefile.mk\n\nDEB_MAKE_CLEAN_TARGET :=\nDEB_MAKE_CHECK_TARGET :=\nDEB_MAKE_INSTALL_TARGET := install\n\ninstall::\n\tmake install\n\n')
	rules_file.close()
	os.chmod('e17-themes/debian/rules', 0755)

	makefile_file=open('e17-themes/Makefile','w')
	makefile_file.write('install:\n\tmkdir -p debian/tmp/usr/share/enlightenment/data/themes\n\tcp $(shell find -name \'*.edj\') debian/tmp/usr/share/enlightenment/data/themes/')
	makefile_file.close()

	print "Debian directories and files created."


def add_virt_package():
	if themeurls == [] or themedebs == []:
		print "No themes have been parsed. Make sure to call this function after fetch_theme_urls() and fill_debian_control_files()."
		sys.exit(1)
	control_file=open('e17-themes/debian/control', 'a')
	deps = ''
	for theme in themedebs:
		deps += 'e17-theme-'+theme+', '
	deps = deps[0:-2]
	control_file.write('Package: e17-themes\nArchitecture: any\nDepends: '+deps+'\nProvides: e17-themes-all, e17-theme-all\nDescription: A dummy package for installing alll E17 themes\n This package will install all available E17 themes available on\n http://exchange.enlightenment.org.\n')
	control_file.close()


def create_install_files():
	if themeurls == [] or themedebs == []:
		print "No themes have been parsed. Make sure to call this function after fetch_theme_urls() and fill_debian_control_files()."
		sys.exit(1)
	pos = 0
	for theme in themeurls:
		instfile = open('e17-themes/debian/e17-theme-'+themedebs[pos]+'.install','w')
		instfile.write('debian/tmp/usr/share/enlightenment/data/themes/'+themedebs[pos]+'.edj')
		instfile.close()
		pos += 1 


def get_themes():
	if themeurls == [] or themedebs == []:
		print "No themes have been parsed. Make sure to call this function after fetch_theme_urls() and fill_debian_control_files()."
		sys.exit(1)
	pos = 0
	for theme in themeurls:
		try:
			urllib.urlretrieve(options.srcurl+theme.replace('show', 'get'), 'e17-themes/'+themedebs[pos]+'.edj')
		except Exception, err:
			print "An error occured while trying to download to "+options.srcurl+theme.replace('show', 'get')+":\n  "+str(err)
		pos += 1



create_debian_files()
fetch_theme_urls()
print "Processing themes:"
for themeurl in themeurls:
	fill_debian_control_files(options.srcurl+themeurl)
add_virt_package()
create_install_files()
get_themes()
print "Done. You can now build the package in e17-themes/, e.g. by running \'dpkg-buildpackage\'"
