#!/usr/bin/python

# Copyright (c) 2007, Tobia Conforto <tobia.conforto@gmail.com>
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is
# hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

# Versions: 0.1  2007-08-13  Initial release

import os, sys, tempfile, pwd, re, fcntl, getopt
from threading import *
from pythumbnail import Lockfile

if __name__ == "__main__":
	# commandline arguments
	optlist, args = getopt.gnu_getopt(sys.argv[1:], 'd:n:v')
	opts = dict(optlist)
	n_threads = int(opts.get('-n', 10))
	dir = opts.get('-d', '.')
	verbose = '-v' in opts

	os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]  # strange su + GTK + VNC issue
	if not os.path.exists(dir):
		os.mkdir(dir)
	if args:
		sites = args
	else:
		sites = sys.stdin.readlines()

	if not sites:
		print 'Usage: pythumbnail-launcher.py [-v] [-d TARGET_DIR] [-n N_THREADS] URLS'
		print 'URLS can be provided either in the commandline or on standard input'
		sys.exit(1)

	# lockfile to protect ~/.vnc from other instances of this script
	vnc_lock = Lockfile('pythumbnail')
	# internal lock for the main site list
	sites_lock = Lock()

	# every thread will:
	def job():

		# launch a new vnc server
		vnc_lock.acquire()
		display = re.search(r'desktop is .*(:\d+)',
				os.popen('vncserver -geometry 800x600 2>&1').read()).group(1)
		vnc_lock.release()
		if verbose: print >>sys.stderr, 'begin thread', display
		env = os.environ.copy()
		env['DISPLAY'] = display

		# while there are sites to do, grab one
		try:
			sites_lock.acquire()
			while sites:
				site = sites.pop().strip()
				sites_lock.release()

				# adjust site url and filename
				if not site.startswith('http://'):
					site = 'http://' + site
				filename = site[7:].replace('/', '-')

				# launch an instance of thumbnail.py
				if verbose: print >>sys.stderr, '  thread', display, 'begin', site
				os.spawnlpe(os.P_WAIT, 'python', 'python', 'pythumbnail.py',
						'-o%s/%s.jpeg' % (dir, filename), site, env)
				if verbose: print >>sys.stderr, '  thread', display, 'end', site

				sites_lock.acquire()
		finally:
			sites_lock.release()

		# kill this vnc server
		vnc_lock.acquire()
		os.system('vncserver -kill %s 2>/dev/null' % display)
		vnc_lock.release()
		if verbose: print >>sys.stderr, 'end thread', display

	# launch N threads
	threads = []
	if verbose: print >>sys.stderr, 'launching', n_threads, 'threads'
	for i in range(n_threads):
		threads.append(Thread(target = job))
		threads[-1].start()

	# wait for completion
	for thread in threads:
		thread.join()
