#!/usr/bin/env python
#Licence: GPLv3.0
#Copyright: Krasimir S. Stefanov

import locale
import sys
import ConfigParser
import os
import os.path
import gettext
import pygtk
import time
import gtk
import gtk.glade
import gobject
import platform
import shutil
import re
import asubprocess
import urllib
import signal
import libtorrent
import tempfile
import statvfs
from threading import Thread
import hashlib
if platform.system() == "Windows":
	import pywintypes
	import win32com.client
	import wmi
	import win32file
	import win32api
	import win32pipe
	from win32file import ReadFile, WriteFile
	from win32pipe import PeekNamedPipe
	import msvcrt
else:
	import dbus

APP = "live-usb-install"
APP_VERSION = "2.2.1"

locale.setlocale(locale.LC_ALL, '')

if platform.system() == "Windows":
	DIR = "locale"
	os.environ['LANG'] = locale.getdefaultlocale()[0]
else:
	if os.path.exists('./locale'):
		DIR = os.path.join(os.path.dirname(sys.argv[0]),"locale")
	else:
		DIR = os.path.join(sys.prefix, 'share', 'locale')

(lang_code, encoding) = locale.getlocale()
gettext.bindtextdomain(APP, DIR)
gettext.textdomain(APP)
gettext.install(APP, localedir=DIR)
gtk.glade.bindtextdomain(APP, DIR)
gtk.glade.textdomain(APP)
_ = gettext.gettext

gobject.threads_init()

class appgui:
	def __init__(self):
		self.glade_dir = os.path.dirname(sys.argv[0])
		self.gladefile = os.path.join(self.glade_dir, "live-usb-install.glade")
		self.md5sum_thread = None
		windowname = "window1"	
		self.widgets = gtk.glade.XML(self.gladefile,windowname,APP)

		dic = { "on_button1_clicked" : self.on_button1_clicked,
				"on_button2_clicked" : self.on_button2_clicked,
				"on_button3_clicked" : self.on_button3_clicked,
				"on_button4_clicked" : self.on_button4_clicked,
				"on_button5_clicked" : self.on_button5_clicked,
				"on_button6_clicked" : self.on_button6_clicked,
				"on_button7_clicked" : self.on_button7_clicked,
				"on_button8_clicked" : self.on_button8_clicked,
				"on_button9_clicked" : self.on_button9_clicked,
				"on_button10_clicked" : self.on_button10_clicked,
				"on_button11_clicked": self.on_button11_clicked,
				"on_combobox1_changed" : self.on_combobox1_changed,
				"on_combobox2_changed" : self.on_combobox2_changed,
				"on_combobox6_changed" : self.on_combobox6_changed,
				"on_radiobutton1_toggled" : self.on_radiobutton1_toggled,
				"on_radiobutton2_toggled" : self.on_radiobutton2_toggled,
				"on_checkbutton1_toggled" : self.on_checkbutton1_toggled,
				"on_filechooserbutton2_file_set" : self.on_filechooserbutton2_file_set,
				"on_checkbutton2_toggled" : self.on_checkbutton2_toggled,
				"on_window1_delete_event" : self.on_button3_clicked}
		self.widgets.signal_autoconnect (dic)
		
		splash = gtk.Window() 
		vbox = gtk.VBox(False, 10)
		vbox.set_border_width(10)
		
		label = gtk.Label()
		label.set_markup('<span size="large" weight="bold">%s</span>' % _("Loading, please wait..."))
		
		label1 = gtk.Label()
		label1.set_markup('<span size="large" weight="bold">%s %s</span>' % (_("live-usb-install"), APP_VERSION))
		
		splash.set_position(gtk.WIN_POS_CENTER_ALWAYS)
		
		image = gtk.Image()
		image.set_from_file(os.path.join(os.path.abspath(self.glade_dir),"logo.png"))
		
		vbox.add(label1)
		vbox.add(image)
		vbox.add(label)
		splash.add(vbox)

		splash.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_SPLASHSCREEN)
		splash.set_decorated(False)
		splash.show_all()

		while gtk.events_pending():
			gtk.main_iteration_do()
		
		#setup versions ComboBox
		liststore = gtk.ListStore(gobject.TYPE_STRING)
		self.widgets.get_widget("combobox2").set_model(liststore)
		cell = gtk.CellRendererText()
		self.widgets.get_widget("combobox2").pack_start(cell, True)
		self.widgets.get_widget("combobox2").add_attribute(cell, 'text', 0)  

		# list distributions
		liststore_distributions = gtk.ListStore(gobject.TYPE_STRING)
		self.widgets.get_widget("combobox1").set_model(liststore_distributions)
		cell = gtk.CellRendererText()
		self.widgets.get_widget("combobox1").pack_start(cell, True)
		self.widgets.get_widget("combobox1").add_attribute(cell, 'text', 0)  
		
		self.presets_dir = os.path.join(os.path.abspath(self.glade_dir),"presets")
		self.presets = os.listdir(self.presets_dir)
				
		self.list_distributions()
		self.list_distribution_versions()
		self.combobox_select(self.widgets.get_widget("combobox1"),"USU",0)
		self.combobox_select(self.widgets.get_widget("combobox2"),"6.1 - Desktop - i386",0)
		
		self.widgets.get_widget("combobox1").get_model().set_sort_column_id(0,gtk.SORT_ASCENDING)
		self.widgets.get_widget("combobox2").get_model().set_sort_column_id(0,gtk.SORT_ASCENDING)
		
		# setup cd drives combobox
		liststore_drives = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING,gobject.TYPE_STRING)
		self.widgets.get_widget("combobox3").set_model(liststore_drives)
		
		cell_icon = gtk.CellRendererPixbuf()
		cell0 = gtk.CellRendererText()
		cell1 = gtk.CellRendererText()

		self.widgets.get_widget("combobox3").pack_start(cell_icon, False)
		self.widgets.get_widget("combobox3").pack_start(cell0, False)
		self.widgets.get_widget("combobox3").pack_start(cell1, True)

		self.widgets.get_widget("combobox3").add_attribute(cell_icon, 'pixbuf', 0)  
		self.widgets.get_widget("combobox3").add_attribute(cell0, 'text', 1)  
		self.widgets.get_widget("combobox3").add_attribute(cell1, 'text', 2)  
		
		#list cd drives
		self.on_button5_clicked(self.widgets.get_widget("button5"))
		
		# setup removable drives combobox
		liststore_drives1 = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING, \
			gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, \
			gobject.TYPE_STRING)
		self.widgets.get_widget("combobox4").set_model(liststore_drives1)
		
		cell0 = gtk.CellRendererPixbuf()
		cell1 = gtk.CellRendererText()
		cell2 = gtk.CellRendererText()
		cell3 = gtk.CellRendererText()
		
		cell4 = gtk.CellRendererProgress()
		cell4.set_property("pulse", -1)
		cell4.set_property("orientation", gtk.PROGRESS_LEFT_TO_RIGHT)
		cell4.set_property("width", 180)
		
		cell5 = gtk.CellRendererText()
		cell5.set_property("visible",0)
		
		self.widgets.get_widget("combobox4").pack_start(cell0, False)
		self.widgets.get_widget("combobox4").pack_start(cell1, False)
		self.widgets.get_widget("combobox4").pack_start(cell2, False)
		self.widgets.get_widget("combobox4").pack_start(cell3, True)
		self.widgets.get_widget("combobox4").pack_start(cell4, False)
		self.widgets.get_widget("combobox4").pack_start(cell5, False)
		
		self.widgets.get_widget("combobox4").add_attribute(cell0, 'pixbuf', 0)  
		self.widgets.get_widget("combobox4").add_attribute(cell1, 'text', 1)  
		self.widgets.get_widget("combobox4").add_attribute(cell2, 'text', 2)  
		self.widgets.get_widget("combobox4").add_attribute(cell3, 'text', 3)  
		
		self.widgets.get_widget("combobox4").add_attribute(cell4, 'value', 4)  
		self.widgets.get_widget("combobox4").add_attribute(cell4, 'text', 5)

		# list removable disk drives
		self.on_button4_clicked(self.widgets.get_widget("button4"))
		self.widgets.get_widget("radiobutton8").set_active(True)
		
		splash.destroy()
		self.widgets.get_widget("combobox6").set_active(0)
		
		self.widgets.get_widget("filechooserbutton2").set_current_folder((os.getenv('HOME') or os.getenv('USERPROFILE')) \
			if platform.system() == "Windows" else ('/media' if os.path.exists('/media') else '/mnt'))
		self.widgets.get_widget("filechooserbutton1").set_current_folder((os.getenv('HOME') or os.getenv('USERPROFILE')) \
			if platform.system() == "Windows" else ('/media' if os.path.exists('/media') else '/mnt'))
		self.widgets.get_widget("window1").show()
			
		return
		
	def list_removable_drives(self):
		""" Detect all removable USB storage devices using HAL via D-Bus """
		self.drives = {}
		if platform.system() == "Windows":
			c = wmi.WMI ()
			for disk in c.query("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'"):
				for partition in c.query("SELECT * FROM Win32_DiskPartition WHERE DiskIndex='" + str(disk.Index) + "'"):
					for partition_1 in c.query("SELECT * FROM Win32_LogicalDiskToPartition"):
						if partition.DeviceID == partition_1.Antecedent.DeviceID:
							try:
								info = win32api.GetVolumeInformation(partition_1.Dependent.DeviceID)
								drive = partition_1.Dependent.DeviceID
								self.drives[drive] = {
										'label': info[0],
										'mount': drive,
										'uuid': self._get_device_uuid(drive),
										'free': self.get_free_bytes(drive),
										'fstype': info[-1],
										'device': drive,
										'fsversion': info[-1],
										'size': self._get_device_size(drive)
								}
							except:
								pass
		else:
			import dbus
			self.drives = {}
			self.bus = dbus.SystemBus()
			hal_obj = self.bus.get_object("org.freedesktop.Hal","/org/freedesktop/Hal/Manager")
			self.hal = dbus.Interface(hal_obj, "org.freedesktop.Hal.Manager")
			devices = []
			devices = self.hal.FindDeviceByCapability("storage")

			for device in devices:
				dev = self._get_device(device)
				if self._storage_bus(dev) == "usb":
					if self._block_is_volume(dev):
						self._add_device(dev)
						continue
					else: # iterate over children looking for a volume
						children = self.hal.FindDeviceStringMatch("info.parent",device)
						for child in children:
							child = self._get_device(child)
							if self._block_is_volume(child):
								self._add_device(child, parent=dev)
								#break	  # don't break, allow all partitions
		return self.drives
	
	def list_removable_drives1(self):
		""" Detect all removable USB storage devices using HAL via D-Bus """
		if platform.system() == "Windows":
			self.drives = {}
			for drive in [l + ':' for l in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ']:
				try:
					if win32file.GetDriveType(drive) == win32file.DRIVE_REMOVABLE:
						vol = [None]
						try:
							vol = win32api.GetVolumeInformation(drive)
						except:
							continue
						print drive
						self.drives[drive] = {
							'label': vol[0],
							'mount': drive,
							'uuid': self._get_device_uuid(drive),
							'free': self.get_free_bytes(drive),
							'fstype': 'vfat',
							'fsversion': 'FAT32',
							'device': drive,
							'fsversion': vol[-1],
							'size': self._get_device_size(drive)
						}
				except:
					return self.drives
		else:
			import dbus
			self.drives = {}
			self.bus = dbus.SystemBus()
			hal_obj = self.bus.get_object("org.freedesktop.Hal","/org/freedesktop/Hal/Manager")
			self.hal = dbus.Interface(hal_obj, "org.freedesktop.Hal.Manager")
			devices = []
			devices = self.hal.FindDeviceByCapability("storage")
			for device in devices:
				dev = self._get_device(device)
				if self._storage_bus(dev) == "usb":
					if self._block_is_volume(dev):
						self._add_device(dev)
						continue
					else: # iterate over children looking for a volume
						children = self.hal.FindDeviceStringMatch("info.parent",device)
						for child in children:
							child = self._get_device(child)
							if self._block_is_volume(child):
								self._add_device(child, parent=dev)
								#break	  # don't break, allow all partitions
		return self.drives
	
	def list_distributions(self):
		self.widgets.get_widget("combobox1").get_model().clear()
		if self.presets:
			self.presets.sort()
			for preset in self.presets:
				self.widgets.get_widget("combobox1").append_text(preset)
				self.widgets.get_widget("combobox1").set_active(0)
	
	def list_distribution_versions(self):
		self.widgets.get_widget("combobox2").get_model().clear()
		path = os.path.join(self.presets_dir, \
			self.widgets.get_widget("combobox1").get_active_text())
		presets = os.listdir(path) 
		presets.sort()

		for preset in presets:
			if os.path.isdir(path + "/" + preset) == True:
				self.widgets.get_widget("combobox2").append_text(preset)

		return

	def _get_device(self, udi):
		""" Return a dbus Interface to a specific HAL device UDI """
		import dbus
		dev_obj = self.bus.get_object("org.freedesktop.Hal", udi)
		return dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")

	def _storage_bus(self, dev):
		storage_bus = None
		try:
			storage_bus = dev.GetProperty('storage.bus')
		except:
			return
		return storage_bus

	def _block_is_volume(self, dev):
		is_volume = False
		try:
			is_volume = dev.GetProperty("block.is_volume")
		except:
			return
		return is_volume
		
	def _add_device(self, dev, parent=None):
		mount = str(dev.GetProperty('volume.mount_point'))
		device = str(dev.GetProperty('block.device'))
		if parent:
			parent = parent.GetProperty('block.device')
		if mount:
			self.drives[device] = {
				'label'   : str(dev.GetProperty('volume.label')).replace(' ', '_'),
				'fstype'  : str(dev.GetProperty('volume.fstype')),
				'fsversion': str(dev.GetProperty('volume.fsversion')),
				'uuid'	: str(dev.GetProperty('volume.uuid')),
				'mount'   : mount,
				'udi'	 : dev,
				'unmount' : False,
				'free'	: mount and self.get_free_bytes(mount) or None,
				'size': self._get_device_size(dev),
				'device'  : device,
				'parent'  : parent
			}
		
	def get_free_bytes(self, device=None):
		""" Return the number of free bytes on our selected drive """
		if platform.system() == "Windows":
			import win32file
			device = device and device or self.drive['device']
			try:
				(spc, bps, fc, tc) = win32file.GetDiskFreeSpace(device)
			except:
				return 0
			return fc * (spc * bps) # free-clusters * bytes per-cluster	
		else:
			import statvfs
			device = device and device or self.dest
			stat = os.statvfs(device)
			return stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL]
		

	def _get_device_uuid(self, drive):
		""" Return the UUID of our selected drive (win32)"""
		#print "_get_device_uuid(%s)" % drive
		uuid = None
		try:
			uuid = self._get_win32_logicaldisk(drive).VolumeSerialNumber
			if uuid in (None, 'None', ''):
				uuid = None
			else:
				uuid = uuid[:4] + '-' + uuid[4:]
		except:
			return None
		return uuid
		
	# Cache these, because they are fairly expensive
	_win32_logicaldisk = {}
	def _get_win32_logicaldisk(self, drive):
		#print "_get_win32_logicaldisk(%s)" % drive
		""" Return the Win32_LogicalDisk object for the given drive """
		import win32com.client
		cache = self._win32_logicaldisk.get('drive')
		if cache:
			return cache
		obj = None
		try:
			obj = win32com.client.Dispatch("WbemScripting.SWbemLocator") \
						 .ConnectServer(".", "root\cimv2") \
						 .ExecQuery("Select * from Win32_LogicalDisk where Name = '%s'" %	drive)
			if obj:
				obj = obj[0]
				self._win32_logicaldisk[drive] = obj
		except:
			return None
		return obj
		
	def _get_device_size(self, drive):
		""" Return the size of the given drive """
		size = None
		try:
			if platform.system() == "Windows":
				size = int(self._get_win32_logicaldisk(drive).Size)
			else:
				size = drive.GetProperty('volume.size')
		except:
			return None
		return size
	
	def download_torrent(self, torrent, target_dir, http_referrer = None):
		print "download_torrent", torrent, target_dir, http_referrer
		local_torrent = os.path.join(tempfile.gettempdir(), 'live-usb-install', \
			self.widgets.get_widget("combobox1").get_active_text() + ' - ' \
			+ self.widgets.get_widget("combobox2").get_active_text() + '.torrent')
		if http_referrer:
			print 'wget --referer="%s" "%s" -O"%s"' % (http_referrer, torrent, local_torrent)
			download_result = os.system('wget --no-check-certificate --referer="%s" "%s" -O"%s"' \
				% (http_referrer, torrent, local_torrent))
		else:
			download_result = os.system('wget --no-check-certificate "%s" -O"%s"' \
				% (torrent, local_torrent))
		
		if download_result != 0:
			self.msg_error(_("Error while downloading torrent file! Installation aborted."))
			self.widgets.get_widget("window1").show()
			return 1

		try:
			e = libtorrent.bdecode(open(local_torrent, 'rb').read())
			info = libtorrent.torrent_info(e)
		except:
			return 1
		ns = Namespace()
		ns.kill_process = False

		def cancel_process(widget, other = None):
			ns.kill_process = True
			return True
		
		window = gtk.glade.XML(self.gladefile,"window2" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"on_window2_delete_event" : (cancel_process),
			"on_button1_clicked" : (cancel_process)
		}
		window.signal_autoconnect (dic)

		window.get_widget('image1').set_from_icon_name('application-x-bittorrent',64)
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' \
			% _("Downloading torrent..."))
		window.get_widget('label3').set_text(torrent)
		
		ses = libtorrent.session()
		ses.listen_on(6881, 6891)
		h = ses.add_torrent(info, target_dir, storage_mode=libtorrent.storage_mode_t.storage_mode_sparse)

		window.get_widget('label3').set_text(torrent)
		window.get_widget('label11').set_text(target_dir)
		
		window.get_widget('label14').show()
		window.get_widget('label15').show()
		
		while (not h.is_seed()):
			if ns.kill_process:
				self.widgets.get_widget("window1").show()
				while gtk.events_pending():
					gtk.main_iteration_do()			
				ses.remove_torrent(h)
				ses.pause()
				break
			s = h.status()
			state_str = [_('queued'), _('checking'), _('downloading metadata'), \
				_('downloading'), _('finished'), _('seeding'), _('allocating')]

			window.get_widget('label5').set_text(_('%.2fMB (%d bytes)') \
				% (s.total_wanted / 1024.0**2, s.total_wanted))
			window.get_widget('label7').set_text(_('%.2fMB (%d bytes)') \
				% (s.total_download / 1024.0**2, s.total_download))
			window.get_widget('label9').set_text(_('%.1fkB/s') \
				% (s.download_rate / 1024))
			window.get_widget('label15').set_text(str(s.num_peers))
			
			if s.state == 3 or s.state == 1:
				window.get_widget("progressbar1").set_fraction(s.progress)
				window.get_widget("progressbar1").set_text('%s %.2f%%' \
					% (state_str[s.state],s.progress*100))
			else:
				window.get_widget("progressbar1").pulse()
				try:
					window.get_widget("progressbar1").set_text('%s %.2f%%' \
						% (state_str[s.state],s.progress*100))
				except:
					pass
						
			time.sleep(0.05)
			while gtk.events_pending():
				gtk.main_iteration_do()			
				
		window.get_widget("window2").destroy()
		while gtk.events_pending():
			gtk.main_iteration_do()			
		if ns.kill_process:
			return 1
		else:
			return 0
	
	def mkfs(self, location, label):
		print "format_casper_rw", location
		ns = Namespace()
		
		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False
			
			
		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		
		window.signal_autoconnect (dic)

		window.get_widget('image1').set_from_icon_name('drive-harddisk',64)
		window.get_widget('window5').set_title(_('live-usb-install') + ' - ' + \
			(_('Formatting %s') % label))
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' \
			% (_('Formatting %s') % label))

		while gtk.events_pending():
			gtk.main_iteration_do()
		
		if platform.system() == "Windows":
			argv = ['mke2fs.exe', '-F', '-L', label, location]	
		else:
			argv = ['mkfs.ext2', '-F', '-L', label, location]
			
		#print ' '.join(argv)
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE
		
		ns.process = asubprocess.Popen(argv, startupinfo=info)

		ns.kill_process = False		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)
				
		window.get_widget("window5").destroy()
		return ns.process.returncode	
	
	
	def write_img(self, fileFrom, fileTo, title = _('Writing disk image file'), bs = 512, count = None):
		print "write_img", fileFrom, fileTo, title, bs, count
		ns = Namespace()
		
		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False
			
			
		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		
		window.signal_autoconnect (dic)

		window.get_widget('image1').set_from_icon_name('drive-harddisk',64)
		window.get_widget('window5').set_title(_('live-usb-install') + ' - ' + title)
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % title)
		while gtk.events_pending():
			gtk.main_iteration_do()
		
		if platform.system() == "Windows":
			argv = ['dd','if=%s' % fileFrom.encode(sys.getfilesystemencoding(), 'replace'), 'of=\\\.\%s' % fileTo, '--progress', 'bs=%s' % bs]	
		else:
			argv = ['dd','if=%s' % fileFrom.encode(sys.getfilesystemencoding(), 'replace'),'of=%s' % fileTo, 'bs=%s' % bs]		
			
		if count:
			argv.append('count=%d' % count)	
			
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, startupinfo=info)

		ns.kill_process = False		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)
				
		window.get_widget("window5").destroy()
		return ns.process.returncode
		
		
	def copy_file(self, fileFrom, fileTo):
		print "copy_file", fileFrom, fileTo
		ns = Namespace()
		
		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False
			
			
		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		
		window.signal_autoconnect (dic)

		window.get_widget('image1').set_from_icon_name('drive-harddisk',64)
		window.get_widget('window5').set_title(_('live-usb-install')+' - ' + _('Copying files...'))
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % _('Copying files...'))
		
		while gtk.events_pending():
			gtk.main_iteration_do()
		
		if platform.system() == "Windows":
			argv = ['xcopy',fileFrom.encode(sys.getfilesystemencoding(), 'replace'),fileTo.encode(sys.getfilesystemencoding(), 'replace'),'/H','/R','/Y','/i']	
		else:
			argv = ['rsync','-v','--progress', fileFrom.encode(sys.getfilesystemencoding(), 'replace'),fileTo.encode(sys.getfilesystemencoding(), 'replace')]		
		
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, startupinfo=info)

		ns.kill_process = False		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)
				
		window.get_widget("window5").destroy()
		return ns.process.returncode

	
	def uncompress(self, archive, target_dir):
		print "uncompress", archive, target_dir
		ns = Namespace()
		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False
		
		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		window.signal_autoconnect (dic)

		window.get_widget('window5').set_title(_('live-usb-install') + ' - ' + _('Extracting files...'))
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % _('Extracting files...'))


		while gtk.events_pending():
			gtk.main_iteration_do()

		argv = ['7z','x','-y',('-o'+target_dir).encode(sys.getfilesystemencoding(), 'replace'),archive.encode(sys.getfilesystemencoding(), 'replace')]		
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, startupinfo=info)
		ns.kill_process = False		
		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)
				
		window.get_widget("window5").destroy()
		return ns.process.returncode
	
	
	
	def copy_from_cd(self, dirFrom, dirTo):
		print "copy_from_cd", dirFrom, dirTo
		ns = Namespace()

		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False
			
			
		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		window.signal_autoconnect (dic)
		
		window.get_widget('image1').set_from_icon_name('media-optical',64)
		window.get_widget('window5').set_title(_('live-usb-install') + ' - ' + _('Copying files from CD/DVD...'))
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % _('Copying files from CD/DVD...'))

		while gtk.events_pending():
			gtk.main_iteration_do()
		
		if platform.system() == "Windows":
			argv = ['xcopy',(dirFrom+'*.*').encode(sys.getfilesystemencoding(), 'replace'),(dirTo+'*.*').encode(sys.getfilesystemencoding(), 'replace'),'/H','/E','/R','/Y']	
		else:
			argv = ['rsync','-rv','--include=".*"','--include=".*/"', '--progress', (dirFrom+'/').encode(sys.getfilesystemencoding(), 'replace'),dirTo.encode(sys.getfilesystemencoding(), 'replace')]		
				
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, startupinfo=info)
		ns.kill_process = False	
		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)
				
		window.get_widget("window5").destroy()
		return ns.process.returncode
		
		
	def uncompress_iso(self, archive, filename, target_dir, archive_type):
		print "uncompress_iso", archive, filename, target_dir, archive_type
		ns = Namespace()

		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False
			
			
		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		window.signal_autoconnect (dic)
		window.get_widget('window5').set_title(_('live-usb-install') + ' - ' + _('Extracting ISO image from downloaded archive...'))
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % _('Extracting ISO image from downloaded archive...'))

		while gtk.events_pending():
			gtk.main_iteration_do()
		
		if archive_type == 'rar':
			argv = ['unrar','e',archive.encode(sys.getfilesystemencoding(), 'replace'),filename.encode(sys.getfilesystemencoding(), 'replace'),target_dir.encode(sys.getfilesystemencoding(), 'replace')]
		else:
			argv = ['7z','e','-y','-o'+target_dir.encode(sys.getfilesystemencoding(), 'replace'),archive.encode(sys.getfilesystemencoding(), 'replace'),filename.encode(sys.getfilesystemencoding(), 'replace')]		
				
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, startupinfo=info)
		ns.kill_process = False	
		
		while ns.process.poll() == None:
			if ns.kill_process:

				
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)
				
		window.get_widget("window5").destroy()
		return ns.process.returncode
		
	def extract_iso(self, iso_location, extract_to):
		print "extract_iso", iso_location, extract_to
		ns = Namespace()

		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False

		window = gtk.glade.XML(self.gladefile,"window5" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"progress_cancel" : (cancel_process),
		}
		window.signal_autoconnect (dic)
		window.get_widget('window5').set_title(_('live-usb-install') + ' - ' + _('Extracting files from ISO image...'))
		window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % _('Extracting files from ISO image...'))

		while gtk.events_pending():
			gtk.main_iteration_do()
		
		argv = ['7z','x',iso_location.encode(sys.getfilesystemencoding(), 'replace'),'-x![BOOT]','-y',('-o%s' % extract_to).encode(sys.getfilesystemencoding(), 'replace')]
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, startupinfo=info)
		ns.kill_process = False	
		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window5").destroy()
				return ns.process.returncode
				
			else:
				window.get_widget("progressbar1").pulse()

			while gtk.events_pending():
				gtk.main_iteration_do()
			time.sleep(0.05)

		window.get_widget("window5").destroy()
		return ns.process.returncode
		
	def download_file(self, remote, local, http_referrer = None):
		if not remote:
			self.msg_error(_("The download link is invalid!"))
			return 1
		ns = Namespace()
		
		def cancel_process(widget, other = None):
			ns.kill_process = True
			return False

		window = gtk.glade.XML(self.gladefile,"window2" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"on_button1_clicked" : (cancel_process),
			"on_window2_delete_event" : (cancel_process)
		}
		window.signal_autoconnect (dic)

		window.get_widget('label3').set_text(remote)
		window.get_widget("label11").set_text(local)

		while gtk.events_pending():
			gtk.main_iteration_do()
			
		if http_referrer:
			argv = ['wget','--no-check-certificate','--referer="%s"' % http_referrer,'-S','-c',remote,'-O',local.encode(sys.getfilesystemencoding(), 'replace')]
		else:
			argv = ['wget','--no-check-certificate','-S','-c',remote,'-O',local.encode(sys.getfilesystemencoding(), 'replace')]
			
		info = None
		if platform.system() == "Windows":
			info = asubprocess.STARTUPINFO()
			info.dwFlags |= asubprocess.STARTF_USESHOWWINDOW
			info.wShowWindow = asubprocess.SW_HIDE

		ns.process = asubprocess.Popen(argv, stdout=asubprocess.PIPE, stderr=asubprocess.PIPE, startupinfo=info)
		ns.kill_process = False
		
		while ns.process.poll() == None:
			if ns.kill_process:
				if platform.system() == "Windows":
					os.system("taskkill /PID %d /F" % ns.process.pid)
				else:
					os.kill(ns.process.pid, signal.SIGKILL)
				ns.process.wait()
				window.get_widget("window2").destroy()
				return ns.process.returncode
				
			else:
				
				line = ns.process.stderr.readline()

				while gtk.events_pending():
					gtk.main_iteration_do()
					
				
				m = re.search('Content-Range: bytes \d+-\d+/(\d+)', line)
				if m:
					window.get_widget("label5").set_text(_("%s bytes") % m.group(1))
					
				m = re.search('Content-Length: (\d+)', line)
				if m:
					window.get_widget("label5").set_text(_("%s bytes") % m.group(1))
								
				m = re.search('(\d+[KMG]).*?(\d+)%.*?(\d+,?\d*[KMG]).*?((\d+[yhms])+)',line)
				if m:
					window.get_widget("progressbar1").set_fraction(float(float(m.group(2))/100.0))
					window.get_widget("label7").set_text(m.group(1))
					window.get_widget("label9").set_text(m.group(3))
					window.get_widget("label13").set_text(m.group(4))
		
		window.get_widget("window2").destroy()
		return ns.process.returncode
	
	#####CALLLBACKS
	def on_destroy_info(self,widget,other):
		widget.destroy()
		return
		
	def on_destroy_drive_info(self,widget,other):
		widget.destroy()
		return
	
	def on_button7_clicked(self,widget):
		self.info_window_widgets = gtk.glade.XML(self.gladefile,"window3" ,APP)
		self.info_window = self.info_window_widgets.get_widget("window3")
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"on_window3_delete_event" : self.on_destroy_info
		}
		self.info_window_widgets.signal_autoconnect (dic)	
		
		if self.widgets.get_widget("combobox2").get_active_iter():
			screenshot_file = os.path.join(self.presets_dir,self.widgets.get_widget("combobox1").get_active_text(),self.widgets.get_widget("combobox2").get_active_text(),"screenshot.png")
			if os.path.isfile(screenshot_file) == True:
				self.info_window_widgets.get_widget("image1").set_from_file(screenshot_file)
				self.info_window_widgets.get_widget("image1").show()
			else:
				self.info_window_widgets.get_widget("image1").hide()
			
			path = os.path.join(self.presets_dir,self.widgets.get_widget("combobox1").get_active_text())
			config = CustomConfig()
			config.readfp(open(os.path.join(path,self.widgets.get_widget("combobox2").get_active_text(),"info.txt")))
			self.info_window_widgets.get_widget("textview1").get_buffer().set_text(_(config.getvalue('liveusb', 'description')))
			self.info_window_widgets.get_widget("label1").set_markup('<span size="large" weight="bold">%s</span>' % self.widgets.get_widget("combobox1").get_active_text())
			self.info_window_widgets.get_widget("label5").set_text(_('%.2f MB') % (float(config.getvalue('liveusb', 'iso_size'))/1024/1024))
			self.info_window_widgets.get_widget("label6").set_text(config.getvalue('liveusb', 'md5'))
			self.info_window_widgets.get_widget("label7").set_text(config.getvalue('liveusb', 'iso_location'))
			self.info_window_widgets.get_widget("window3").show()
			#import webkit
			#gtk.gdk.threads_init()
			#webview = webkit.WebView()
			#webview.set_size_request(640,240)
			#webview.show()	
			#webview.open('http://en.wikipedia.org/w/index.php?title=%s&printable=yes')
			#self.info_window_widgets.get_widget("scrolledwindow2").add(webview)
		return
		
	def on_button8_clicked(self,widget):
		self.drive_info_window_widgets = gtk.glade.XML(self.gladefile,"window4" ,APP)
		self.drive_info_window = self.drive_info_window_widgets.get_widget("window4")
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"on_window4_delete_event" : self.on_destroy_drive_info
		}
		self.drive_info_window_widgets.signal_autoconnect (dic)	
		
		if self.widgets.get_widget("combobox4").get_active_iter():
			removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
			if platform.system() == "Windows":
				removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
				removable_drive_device = removable_drive_path.replace("\\","")
			else:
				removable_drive_device = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
							
			self.drive_info_window_widgets.get_widget("label8").set_markup('<b>'+removable_drive_device+'</b>')
			self.drive_info_window_widgets.get_widget("label9").set_markup('<b>'+self.drives[removable_drive_device]['label']+'</b>')
			self.drive_info_window_widgets.get_widget("label10").set_markup('<b>'+self.drives[removable_drive_device]['mount']+'</b>')
			self.drive_info_window_widgets.get_widget("label11").set_markup('<b>'+self.drives[removable_drive_device]['uuid']+'</b>')
			self.drive_info_window_widgets.get_widget("label12").set_markup('<b>'+(_('%.2f MB') % (self.drives[removable_drive_device]['size']/1024/1024))+'</b>')
			self.drive_info_window_widgets.get_widget("label13").set_markup('<b>'+(_('%.2f MB') % (self.drives[removable_drive_device]['free']/1024/1024))+'</b>')
			self.drive_info_window_widgets.get_widget("label14").set_markup('<b>'+self.drives[removable_drive_device]['fstype']+'</b>')
			self.drive_info_window_widgets.get_widget("label16").set_markup('<b>'+self.drives[removable_drive_device]['fsversion']+'</b>')
		return	
		
	
	def on_button9_clicked(self,widget):
		removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
		if removable_drive_iter:
			if platform.system() == "Windows":
				removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
				
			else:
				removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,2)
		return

	def on_button6_clicked(self,widget):	
		dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_WARNING,gtk.BUTTONS_YES_NO, 
			_("WARNING! This will destroy all data on the selected drive!!! Are you sure?"))
		dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
		response = dialog.run()
		dialog.destroy()
		if response == gtk.RESPONSE_YES:
			self.widgets.get_widget("window1").hide()
			while gtk.events_pending():
				gtk.main_iteration_do()
			removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
			if platform.system() == "Windows":
				import win32api, win32file
				removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
				removable_drive_device = removable_drive_path.replace("\\","")
				removable_drive_iter = self.widgets.get_widget("window1").hide()
				os.system('format /Q '+removable_drive_device)
				dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK, 
					_("Formatting complete!"))
				dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
				response = dialog.run()
				dialog.destroy()
			else:
				removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,2)
				removable_drive_device = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
				os.system('umount %s' % removable_drive_device)
				if os.path.exists('/usr/lib/gnome-disk-utility/gdu-format-tool'):
					os.system('/usr/lib/gnome-disk-utility/gdu-format-tool -d %s' % removable_drive_device)
					dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK, 
						_("Formatting complete!"))
					dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
					response = dialog.run()
					dialog.destroy()
				else:
					os.system('xterm -e mkfs.vfat -v %s' % removable_drive_device)
					dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK, 
						_("Formatting complete! Now, you should manually reinsert the removable drive."))
					dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
					response = dialog.run()
					dialog.destroy()
			
			self.widgets.get_widget("window1").show()
			self.on_button4_clicked(widget)
		return
		

	def msg_error(self,msg, parent = None):
		if not parent:
			self.widgets.get_widget("window1")
		dialog = gtk.MessageDialog(parent,gtk.DIALOG_MODAL,gtk.MESSAGE_ERROR,gtk.BUTTONS_OK,msg)
		dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
		dialog.run()
		dialog.destroy()	

	def msg_info(self,msg, parent = None):
		if not parent:
			self.widgets.get_widget("window1")
		dialog = gtk.MessageDialog(parent,gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK)
		dialog.set_markup(msg)
		dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
		dialog.run()
		dialog.destroy()
		
	def on_button1_clicked(self,widget):
		start = time.time()
		self.widgets.get_widget("window1").hide()
		while gtk.events_pending():
			gtk.main_iteration_do()
			
		removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
		if not removable_drive_iter:
			self.msg_error(_("No removable drive selected!"))
			self.widgets.get_widget("window1").show()	
			return

		if platform.system() == "Windows":
			import win32api, win32file
			removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
			removable_drive_device = removable_drive_path.replace("\\","")
		else:
			removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,2)
			removable_drive_device = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
			
		removable_drive_freespace = int(self.drives[removable_drive_device]['free'])
		#=======================================================================================	
		if self.widgets.get_widget("radiobutton7").get_active() == True:  # Install from CD/DVD
			cd_drive_iter = self.widgets.get_widget("combobox3").get_active_iter()
			if not cd_drive_iter:
				self.msg_error(_("No CD/DVD drive selected!"))
				self.widgets.get_widget("window1").show()					
				return

			if platform.system() == "Windows":
				cd_drive_path = self.widgets.get_widget("combobox3").get_model().get_value(cd_drive_iter,1)
				cd_drive_size = (win32file.GetDiskFreeSpaceEx(cd_drive_path)[1]) # in bytes
			else:
				cd_drive_path = self.widgets.get_widget("combobox3").get_model().get_value(cd_drive_iter,2)
				cd_drive_size = 0
				if os.popen('mount | grep ' + self.widgets.get_widget("combobox3").get_model().get_value(cd_drive_iter,1) + '| cut -d\  -f1').read().strip() == '':
					self.msg_error(_("No CD/DVD drive mounted!"))
					self.widgets.get_widget("window1").show()					
					return			

			if cd_drive_size > removable_drive_freespace:
				required_space = cd_drive_size - removable_drive_freespace
				self.msg_error(_("There is not enough free space on the selected removable drive. You must free additional %s MB") % required_space)
				self.widgets.get_widget("window1").show()
				return
			else:
				if self.copy_from_cd(cd_drive_path,removable_drive_path) != 0:
					self.msg_error(_("Installation aborted!"))
					self.widgets.get_widget("window1").show()
					return

		#=======================================================================================	
		elif self.widgets.get_widget("radiobutton8").get_active() == True:  # Install from ISO
			#sys.exit(0)
			if not self.widgets.get_widget("filechooserbutton2").get_filename():
				self.msg_error(_("Please select ISO file!"))
				self.widgets.get_widget("window1").show()
				return

			if self.widgets.get_widget("combobox6").get_active() == 2:
				if self.copy_file(self.widgets.get_widget("filechooserbutton2").get_filename(),removable_drive_path) != 0:
					self.msg_error(_("Installation aborted!"))
					self.widgets.get_widget("window1").show()
					return
			else:
				if self.extract_iso(self.widgets.get_widget("filechooserbutton2").get_filename(),removable_drive_path) != 0:
					self.msg_error(_("Installation aborted!"))
					self.widgets.get_widget("window1").show()
					return
		
		#=======================================================================================	
		elif self.widgets.get_widget("radiobutton9").get_active() == True:  # Install from Internet
			path = os.path.join(self.presets_dir,self.widgets.get_widget("combobox1").get_active_text())
			config = CustomConfig()
			config.readfp(open(os.path.join(path, self.widgets.get_widget("combobox2").get_active_text(),"info.txt")))
			iso_location = config.getvalue('liveusb', 'iso_location')
			iso_size = config.getvalue('liveusb', 'iso_size')
			archive = config.getvalue('liveusb', 'archive')
			iso_extract = config.getvalue('liveusb', 'iso_extract')
			in_torrent = config.getvalue('liveusb', 'in_torrent')
			http_referrer = config.getvalue('liveusb', 'http_referrer')
			if int(iso_size) > removable_drive_freespace:
				required_space = int(iso_size) - removable_drive_freespace
				self.msg_error(_("There is not enough free space on the selected removable drive. You must free additional %s MB") % required_space)
				self.widgets.get_widget("window1").show()
				return
			if not os.path.exists(os.path.join(tempfile.gettempdir(),'live-usb-install')):
				os.mkdir(os.path.join(tempfile.gettempdir(),'live-usb-install'))
			
			if in_torrent:
				download_result = self.download_torrent(iso_location, os.path.join(tempfile.gettempdir(),'live-usb-install'), http_referrer)
				if download_result != 0:
					self.msg_error(_("Torrent invalid or canceled! Installation aborted."))
					self.widgets.get_widget("window1").show()
					return			
			if archive:
				if in_torrent:
					extract_result = self.uncompress_iso(
						os.path.join(tempfile.gettempdir(),'live-usb-install',in_torrent)
						, iso_extract
						, os.path.join(tempfile.gettempdir(),'live-usb-install')
						, archive)

					if extract_result != 0:
						self.msg_error(_("There was an error while extracting the iso file from the downloaded archive"))
						self.widgets.get_widget("window1").show()
						return
					
					isoName = os.path.basename(iso_extract)
					isoName_full = os.path.join(tempfile.gettempdir(),'live-usb-install', isoName)
					
					if self.extract_iso(isoName_full,removable_drive_path) != 0:
						self.msg_error(_("Installation aborted!"))
						self.widgets.get_widget("window1").show()
						return
				else:
					isoName = self.widgets.get_widget("combobox1").get_active_text() + ' - ' + self.widgets.get_widget("combobox2").get_active_text() + '.' + archive
					isoName_full = os.path.join(tempfile.gettempdir(),'live-usb-install',isoName)
					download_result = self.download_file(iso_location,isoName_full, http_referrer)

					if download_result != 0:
						self.msg_error(_("Installation aborted!"))
						self.widgets.get_widget("window1").show()
						return
				
					extract_result = self.uncompress_iso(isoName_full, iso_extract, os.path.join(tempfile.gettempdir(),'live-usb-install'), archive)

					if extract_result != 0:
						self.msg_error(_("There was an error while extracting the iso file from the downloaded archive"))
						self.widgets.get_widget("window1").show()
						return
					

					isoName = os.path.basename(iso_extract)
					isoName_full = os.path.join(tempfile.gettempdir(),'live-usb-install', isoName)
		
					if self.extract_iso(isoName_full,removable_drive_path) != 0:
						self.msg_error(_("Installation aborted!"))
						self.widgets.get_widget("window1").show()
						return
			else:
			
				if in_torrent:
					isoName_full = os.path.join(tempfile.gettempdir(),'live-usb-install', in_torrent)
				else:
					isoName = self.widgets.get_widget("combobox1").get_active_text() + ' - ' + self.widgets.get_widget("combobox2").get_active_text() + '.iso'
					while gtk.events_pending():
						gtk.main_iteration_do()

					isoName_full = os.path.join(tempfile.gettempdir(),'live-usb-install', isoName)
					download_result = self.download_file(iso_location,isoName_full, http_referrer)

					if download_result != 0:
						self.msg_error(_("Installation aborted!"))
						self.widgets.get_widget("window1").show()
						return
				
				if self.extract_iso(isoName_full,removable_drive_path) != 0:
					self.msg_error(_("Installation aborted!"))
					self.widgets.get_widget("window1").show()
					return		
		#=======================================================================================	
		elif self.widgets.get_widget("radiobutton3").get_active() == True:  # Install from IMG file
			img_filename = self.widgets.get_widget("filechooserbutton4").get_filename()
			if not img_filename:
				self.msg_error(_("Please select image file!"))
				self.widgets.get_widget("window1").show()
				return
			
			if platform.system() == "Windows":
				img_write_result =  self.write_img(img_filename, removable_drive_device)
				
				if img_write_result != 0:
					self.msg_error(_("Error while transferring image file to %s. Installation aborted!") % removable_drive_device)
					self.widgets.get_widget("window1").show()
					return
			else:
				parent_dev = self.get_parent_device(removable_drive_device)
				os.system('sync')
				
				if os.system('umount %s' % removable_drive_device)!=0:
					self.msg_error(_("The removable drive can not be unmounted. Installation aborted!"))
					self.widgets.get_widget("window1").show()
					return
				
				img_write_result =  self.write_img(img_filename, parent_dev)
				
							
				if img_write_result != 0:
					self.msg_error(_("Error while transferring image file to %s. Installation aborted!") % parent_dev)
					self.widgets.get_widget("window1").show()
					return
							
			dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK,_("Installation is complete!\nTime taken: %f seconds") % round(time.time() - start))
			dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
			dialog.run()
			dialog.destroy()
			self.widgets.get_widget("window1").show()		
			return # skip the rest!!
		#=======================================================================================	
			
		
		if platform.system() == "Windows":
			shutil.copy2('vesamenu.c32',removable_drive_path)
		else:
			if os.path.isfile('/usr/lib/syslinux/vesamenu.c32'):
				shutil.copy2('/usr/lib/syslinux/vesamenu.c32',removable_drive_path)
			else:
				shutil.copy2('vesamenu.c32',removable_drive_path)
				
		if platform.system() == "Windows":
			os.system('del ' + removable_drive_path+'\\boot\\syslinux\\syslinux.cfg')
			os.system('del ' + removable_drive_path+'\\syslinux\\syslinux.cfg')
			os.system('del ' + removable_drive_path+'\\syslinux.cfg')
		else:
			os.system('rm "' + removable_drive_path+'/boot/syslinux/syslinux.cfg"')
			os.system('rm "' + removable_drive_path+'/syslinux/syslinux.cfg"')
			os.system('rm "' + removable_drive_path+'/syslinux.cfg"')			
			
		if self.widgets.get_widget("combobox6").get_active() == 1:
			syslinux_cfg_f = open("./syslinux-custom.cfg")
			syslinux_cfg = syslinux_cfg_f.read()
			syslinux_cfg_f.close()
			
			# syslinux_cfg = replace(syslinux_cfg,"%MENU_TITLE%",self.widgets.get_widget("entry1").get_text())
			syslinux_cfg = syslinux_cfg.replace("%MENU_LABEL%",self.widgets.get_widget("entry1").get_text())
			syslinux_cfg = syslinux_cfg.replace("%KERNEL%",self.widgets.get_widget("entry2").get_text())
			syslinux_cfg = syslinux_cfg.replace("%APPEND%",self.widgets.get_widget("entry4").get_text())
			
			if self.widgets.get_widget("filechooserbutton1").get_filename():
				shutil.copy2(self.widgets.get_widget("filechooserbutton1").get_filename(),removable_drive_path+'backg.png')
				syslinux_cfg = syslinux_cfg.replace('%MENUBG%','MENU BACKGROUND backg.png')
			else:
				syslinux_cfg = syslinux_cfg.replace('%MENUBG%','')
			
			syslinux_f = open(removable_drive_path+'/syslinux.cfg', 'w+')
			syslinux_f.write(syslinux_cfg)
			syslinux_f.close()
			
		elif self.widgets.get_widget("combobox6").get_active() == 2:
			syslinux_cfg_f = open("./syslinux-wingrub.cfg")
			syslinux_cfg = syslinux_cfg_f.read()
			syslinux_cfg_f.close()
			
			syslinux_cfg = syslinux_cfg.replace("%MENU_LABEL%",self.widgets.get_widget("entry5").get_text())
			print syslinux_cfg

			syslinux_f = open(removable_drive_path+'/syslinux.cfg', 'w+')
			syslinux_f.write(syslinux_cfg)
			syslinux_f.close()
						
			menu_lst_f = open("./menu.lst")
			menu_lst = menu_lst_f.read()
			menu_lst_f.close()
			menu_lst = menu_lst.replace("%MENU_LABEL%",self.widgets.get_widget("entry5").get_text())
			menu_lst = menu_lst.replace("%ISO%",os.path.basename(self.widgets.get_widget("filechooserbutton2").get_filename()).replace(' ','\ '))

			if self.widgets.get_widget("radiobutton1").get_active():
				menu_lst = menu_lst.replace("%BOOT%","chainloader (hd32)")
			else:
				menu_lst = menu_lst.replace("%BOOT%","kernel "+self.widgets.get_widget("entry6").get_text()+"\n"+"initrd "+self.widgets.get_widget("entry7").get_text())
			print menu_lst
			
			multi = False
			if os.path.isfile(removable_drive_path+'/menu.lst'):
				menu_lst1_f = open(removable_drive_path+'/menu.lst')
				menu_lst1 = menu_lst1_f.read()
				menu_lst1_f.close()				
				if re.search('^#live-usb-install wingrub iso boot', menu_lst1):
					multi = True
			
			if multi:
				menu_lst_f = open(removable_drive_path+'/menu.lst', 'w+')
				menu_lst_f.write(menu_lst1 + '\n' + menu_lst)	
				menu_lst_f.close()				
			else:
				menu_lst_f = open(removable_drive_path+'/menu.lst', 'w+')
				menu_lst_f.write(menu_lst)		
				menu_lst_f.close()
				
			shutil.copy2("./backg.png",removable_drive_path)			
			shutil.copy2("./grub.exe",removable_drive_path)
			
		else:
			
			shutil.copy2(os.path.join(self.presets_dir,self.widgets.get_widget("combobox1").get_active_text(), self.widgets.get_widget("combobox2").get_active_text(),"syslinux.cfg"),removable_drive_path)

			path = os.path.join(self.presets_dir,self.widgets.get_widget("combobox1").get_active_text())
			config = CustomConfig()
			config.readfp(open(os.path.join(path, self.widgets.get_widget("combobox2").get_active_text(), "info.txt")))
			

			if config.getvalue('liveusb', 'set_uuid').lower() == 'true':
				syslinux_cfg_f = open(os.path.join(removable_drive_path,"syslinux.cfg"))
				syslinux_cfg = syslinux_cfg_f.read()
				syslinux_cfg_f.close()			
				syslinux_cfg = syslinux_cfg.replace("%UUID%",self.drives[removable_drive_device]['uuid'])
				syslinux_cfg_f = open(os.path.join(removable_drive_path, "syslinux.cfg"), 'w+')
				syslinux_cfg_f.write(syslinux_cfg)		
				syslinux_cfg_f.close()

			if config.getvalue('liveusb', 'kiwi_mbrid').lower() == 'true':
				mbrid = self.get_mbrid(removable_drive_device)
				if mbrid == False:
					self.msg_error(_("Error while reading Master Boot Record ID! Installation aborted."))
					self.widgets.get_widget("window1").show()
					return
				if not os.path.exists(os.path.join(removable_drive_path,"boot","grub")):
					os.makedirs(os.path.join(removable_drive_path,"boot","grub"))
				mbrid_f = open(os.path.join(removable_drive_path,"boot","grub","mbrid"),'w+')
				mbrid_f.write(mbrid)	
				mbrid_f.close()	
			
			'''
			# set correct locale
			if os.path.isfile(os.path.join(removable_drive_path,"menu.lst")):
				cfg_filename = os.path.join(removable_drive_path,"menu.lst")
			else:
				cfg_filename = os.path.join(removable_drive_path,"syslinux.cfg")
				
			cfg_f = open(cfg_filename)
			cfg_txt = cfg_f.read()
			cfg_f.close()
			
			m = re.search('locale=([a-zA-Z_]+)',cfg_txt)
			if m:
				cfg_txt = cfg_txt.replace( m.group(0), 'locale='+locale.getdefaultlocale()[0])

			m = re.search('lang=([a-zA-Z]+)',cfg_txt)
			if m:
				cfg_txt = cfg_txt.replace( m.group(0), 'lang='+locale.getdefaultlocale()[0].split('_')[0])

			cfg_f = open(cfg_filename, 'w+')
			cfg_f.write(cfg_txt)	
			cfg_f.close()
			'''
			
			if self.widgets.get_widget("checkbutton1").get_active() == True:
				if config.getvalue('liveusb', 'ubuntu_persistent').lower() == 'true':
					persistent_file = '%s/casper-rw' % (removable_drive_path, persistent_file)
					persistent_label = 'casper-rw'
				elif config.getvalue('liveusb', 'debian_persistent').lower() == 'true':
					# Debian > 6
					persistent_file = '%s/live-rw' % removable_drive_path
					persistent_label = 'live-rw'
				'''
				elif config.getvalue('liveusb', 'sidux_persistent').lower() == 'true':
					persistent_file = '%s/sidux/sidux-rw' % removable_drive_path
					persistent_label = 'sidux-rw'
				elif config.getvalue('liveusb', 'aptosid_persistent').lower() == 'true':
					persistent_file = '%s/aptosid/aptosid-rw' % removable_drive_path
					persistent_label = 'aptosid-rw'
				#Puppy
				elif config.getvalue('liveusb', 'puppy_persistent').lower() == 'true':
					persistent_file = '%s/lupusave.2fs' % removable_drive_path
					persistent_label = 'lupusave'
				'''
				#TODO:
				'''
				#Fedora
				elif config.getvalue('liveusb', 'fedora_persistent').lower() == 'true':
					persistent_file = ('%s/LiveOS/overlay-'+LABEL.replace(' ','_')+'-'+UUID) % removable_drive_path
					persistent_label = '' # TODO: correct label?
					
					
				'''
				
				#syslinux_cfg_f = open(os.path.join(removable_drive_path,"syslinux.cfg"))
				
				syslinux_cfg_filename = os.path.join(removable_drive_path, "syslinux.cfg")
				syslinux_cfg = open(syslinux_cfg_filename).read().replace("#PERSISTENCE:","")
				syslinux_cfg_f = open(syslinux_cfg_filename, 'w+')
				syslinux_cfg_f.write(syslinux_cfg)	
				syslinux_cfg_f.close()
				
				persistent_size = int(self.widgets.get_widget("combobox5").get_active_text())
				
				dd_result = self.write_img(
					'/dev/zero'
					, persistent_file
					, _("Creating %s %s MB") % (persistent_file, persistent_size)
					, '1M'
					, persistent_size
				)
				
				if dd_result != 0:
					self.msg_error(_('The persistent storage was not created. Installation aborted!'))
					self.widgets.get_widget("window1").show()		
					return
				mkfs_result = self.mkfs(persistent_file, persistent_label)
				if mkfs_result != 0:
					self.msg_error(_('The persistent storage was not formated. Installation aborted!'))
					self.widgets.get_widget("window1").show()		
					return					
			
			backg_file = os.path.join(self.presets_dir, self.widgets.get_widget("combobox1").get_active_text(), "backg.png")
			if os.path.isfile(backg_file):
				shutil.copy2(backg_file,removable_drive_path)
			else:
				shutil.copy2(os.path.join(self.glade_dir, "backg.png"),removable_drive_path)
				
			support_files = os.path.join(self.presets_dir, self.widgets.get_widget("combobox1").get_active_text(), self.widgets.get_widget("combobox2").get_active_text(), "other.7z")
			if os.path.exists(support_files):
				self.uncompress(support_files,removable_drive_path)
			
			helper_file_path = os.path.join(self.presets_dir, self.widgets.get_widget("combobox1").get_active_text(), self.widgets.get_widget("combobox2").get_active_text(), "helper.py")
			if os.path.exists(helper_file_path):
				helper_file = open(helper_file_path)
				helper_file_contents = helper_file.read()
				helper_file.close()
				exec helper_file_contents
			
		if platform.system() == "Windows":
			os.system("del /F /Q " + os.path.join(removable_drive_path,'ldlinux.sys'))
			if os.system("syslinux -maf " + removable_drive_device) != 0:
				self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
				self.widgets.get_widget("window1").show()
				return
			#TODO: mark partition active
		else:
			os.system("rm -f " + os.path.join(removable_drive_path, 'ldlinux.sys'))
			os.system("sync")
			if os.system("umount " + removable_drive_device) != 0:
				self.msg_error(_("The target drive can not be unmounted, and the syslinux bootloader will not be installed! Installation aborted."))
				self.widgets.get_widget("window1").show()
				return

			parent_dev = self.get_parent_device(removable_drive_device)

			m = re.search('(\d+)$', removable_drive_device)
			if m:
				partition_number = m.group(1)
				if os.system("parted %s set %s boot on" % (parent_dev, partition_number)) != 0:
					self.msg_error(_("Cant mark partition %s as active! Installation aborted.") % removable_drive_device)
					self.widgets.get_widget("window1").show()
					return

			if os.system("syslinux -f " + removable_drive_device) != 0:
				if os.system("syslinux -sf " + removable_drive_device) != 0:
					self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
					self.widgets.get_widget("window1").show()
					return
			
			#cat /usr/lib/syslinux/mbr.bin > /dev/sdc
			#mark partition bootable: parted /dev/sdc set 1 boot on
			
			if os.system("dd if=%s of=%s" % (os.path.join(self.glade_dir,'syslinux.mbr'), parent_dev)) != 0:
				self.msg_error(_("Error while writing master boot record! Installation aborted."))
				self.widgets.get_widget("window1").show()
				return			
		
		if self.widgets.get_widget("radiobutton9").get_active() == True:
			dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_QUESTION,gtk.BUTTONS_YES_NO, _("Installation is complete!\nTime taken: %s\nDo you want to delete the downloaded temporaty files?") % time.strftime('%M min %S sec', time.gmtime(time.time() - start)))
			dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
			response = dialog.run()
			dialog.destroy()
			if response == gtk.RESPONSE_YES:
				try:
					tmp_path = os.path.join(tempfile.gettempdir(),'live-usb-install')
					if os.path.isdir(tmp_path):
						shutil.rmtree(tmp_path)
				except:
					pass		
		else:
			dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK,_("Installation is complete!\nTime taken: %s") % time.strftime('%M min %S sec', time.gmtime(time.time() - start)))
			dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
			dialog.run()
			dialog.destroy()

		self.widgets.get_widget("window1").show()
		return
		
	def on_button2_clicked(self,widget):
		about = gtk.AboutDialog()
		about.set_position(gtk.WIN_POS_CENTER_ALWAYS)
		about.set_program_name("live-usb-install")
		about.set_version(APP_VERSION)
		about.set_authors([_("Krasimir S. Stefanov <lokiisyourmaster@gmail.com>")])
		about.set_website("http://skss.learnfree.eu/")
		about.set_translator_credits(_("Bulgarian - Krasimir S. Stefanov <lokiisyourmaster@gmail.com>"))
		about.set_logo(gtk.gdk.pixbuf_new_from_file(os.path.join(self.glade_dir,'logo.png')))
		license = _('''live-usb-install: install linux on a removable drive
Copyright (C) 2010  Krasimir S. Stefanov

This program 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 3 of the License, or
(at your option) any later version.

This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.''')
		
		about.set_license(license)
		about.run()
		about.hide()
		return
  
	def on_button3_clicked(self, widget, args = None):
		if self.md5sum_thread:
			self.md5sum_thread.canceled = True
		gtk.main_quit()
		return
		
	def on_button4_clicked(self,widget):
		removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
		if removable_drive_iter:
			if platform.system() == "Windows":
				removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
				removable_drive_device = removable_drive_path.replace("\\","")
			else:
				removable_drive_device = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,1)
		else:
			removable_drive_device = ''
			
		#self.msg_error(removable_drive_device)			
		self.widgets.get_widget("combobox4").get_model().clear()
		removable_drives = self.list_removable_drives()

		if len(self.drives) > 0:
			for drive in self.drives:
				list_iter = self.widgets.get_widget("combobox4").get_model().append()
				icon = self.widgets.get_widget("combobox4").render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_MENU)
				if self.drives[drive]['size'] == None:
					self.drives[drive]['size'] = 0
				if self.drives[drive]['free'] == None:
					self.drives[drive]['free'] = 0
				if platform.system() == "Windows":
					self.widgets.get_widget("combobox4").get_model().set(
						list_iter
						, 0, icon
						, 1, self.drives[drive]['device']
						, 2, self.drives[drive]['label']
						, 3, ''
						, 4, int(float(self.drives[drive]['size'] - self.drives[drive]['free']) / float(self.drives[drive]['size']) * 100.0)
						, 5, _('%.2f / %.2f GB (%s)') % (float(self.drives[drive]['size'] - self.drives[drive]['free'])/1024.0**3, float(self.drives[drive]['size'])/1024.0**3, self.drives[drive]['fsversion'] or self.drives[drive]['fstype'])
					)
				else:
					self.widgets.get_widget("combobox4").get_model().set(
						list_iter
						, 0, icon
						, 1, self.drives[drive]['device']
						, 2, self.drives[drive]['mount']
						, 3, ''
						, 4, int(float(self.drives[drive]['size'] - self.drives[drive]['free']) / float(self.drives[drive]['size']) * 100.0)
						, 5, _('%.2f / %.2f GB (%s)') % (float(self.drives[drive]['size'] - self.drives[drive]['free'])/1024.0**3, float(self.drives[drive]['size'])/1024.0**3, self.drives[drive]['fsversion'] or self.drives[drive]['fstype'])
					)
			self.widgets.get_widget("combobox4").set_sensitive(True)
			self.widgets.get_widget("button6").set_sensitive(True)
			self.widgets.get_widget("button8").set_sensitive(True)
			
			
			self.combobox_select(self.widgets.get_widget("combobox4"), removable_drive_device, 1)
		else:
			self.widgets.get_widget("combobox4").set_sensitive(False)
			self.widgets.get_widget("button6").set_sensitive(False)
			self.widgets.get_widget("button8").set_sensitive(False)	
		#self.widgets.get_widget("combobox4").set_active(0)
		return

	def on_button5_clicked(self,widget):
		self.widgets.get_widget("combobox3").get_model().clear()
		#list cd drives
		self.cd_drives = self.list_cd_drives()
		if len(self.cd_drives) > 0:
			for drive in self.cd_drives:
				list_iter = self.widgets.get_widget("combobox3").get_model().append()
				icon = self.widgets.get_widget("combobox3").render_icon(gtk.STOCK_CDROM, gtk.ICON_SIZE_MENU)
				self.widgets.get_widget("combobox3").get_model().set(list_iter,0, icon, 1,drive[0],2,drive[1])
			self.widgets.get_widget("combobox3").set_active(0)
			self.widgets.get_widget("radiobutton7").set_sensitive(True)
			
		else:
			self.widgets.get_widget("radiobutton7").set_sensitive(False)
			self.widgets.get_widget("radiobutton8").set_active(True)

		return  

			
	def on_combobox6_changed(self,widget):
		active = self.widgets.get_widget("combobox6").get_active()
		
		if active == 0: # cd, iso, internet
			self.widgets.get_widget("frame1").show()
			self.widgets.get_widget("frame5").hide()
			self.widgets.get_widget("frame6").hide()
			
			self.widgets.get_widget("image6").show() # cd
			self.widgets.get_widget("radiobutton7").show() # cd
			self.widgets.get_widget("hbox4").show() # cd
			
			self.widgets.get_widget("image7").show() # iso
			self.widgets.get_widget("radiobutton8").show() # iso
			self.widgets.get_widget("vbox4").show() # iso
			self.widgets.get_widget("checkbutton2").show() # md5check
			
			
			self.widgets.get_widget("image8").show() # internet
			self.widgets.get_widget("hbox5").show() # internet

			self.widgets.get_widget("image1").hide() # img
			self.widgets.get_widget("radiobutton3").hide() # img
			self.widgets.get_widget("filechooserbutton4").hide() # img
			self.widgets.get_widget("hbox2").show()
		elif active == 1: # cd, iso
			self.widgets.get_widget("frame1").hide()
			self.widgets.get_widget("frame5").show()
			self.widgets.get_widget("frame6").hide()
			if self.widgets.get_widget("radiobutton3").get_active() or self.widgets.get_widget("radiobutton9").get_active():
				self.widgets.get_widget("radiobutton8").set_active(True)
			self.widgets.get_widget("checkbutton1").set_active(False)	
			
			self.widgets.get_widget("image6").show() # cd
			self.widgets.get_widget("radiobutton7").show() # cd
			self.widgets.get_widget("hbox4").show() # cd
			
			self.widgets.get_widget("image7").show() # iso
			self.widgets.get_widget("radiobutton8").show() # iso
			self.widgets.get_widget("vbox4").show() # iso
			self.widgets.get_widget("checkbutton2").hide() # md5check
			self.widgets.get_widget("checkbutton2").set_active(False) # md5check
			
			self.widgets.get_widget("image8").hide() # internet
			self.widgets.get_widget("hbox5").hide() # internet

			self.widgets.get_widget("image1").hide() # img
			self.widgets.get_widget("radiobutton3").hide() # img
			self.widgets.get_widget("filechooserbutton4").hide() # img
			self.widgets.get_widget("hbox2").hide()
		elif active == 2: #  iso
			self.widgets.get_widget("frame1").hide()
			self.widgets.get_widget("frame5").hide()
			self.widgets.get_widget("frame6").show()
			if self.widgets.get_widget("radiobutton3").get_active() or self.widgets.get_widget("radiobutton9").get_active():
				self.widgets.get_widget("radiobutton8").set_active(True)
							
			self.widgets.get_widget("image6").hide() # cd
			self.widgets.get_widget("radiobutton7").hide() # cd
			self.widgets.get_widget("hbox4").hide() # cd
			
			self.widgets.get_widget("image7").show() # iso
			self.widgets.get_widget("radiobutton8").show() # iso
			self.widgets.get_widget("vbox4").show() # iso
			self.widgets.get_widget("checkbutton2").hide() # md5check
			self.widgets.get_widget("checkbutton2").set_active(False) # md5check
			
			self.widgets.get_widget("image8").hide() # internet
			self.widgets.get_widget("hbox5").hide() # internet

			self.widgets.get_widget("image1").hide() # img
			self.widgets.get_widget("radiobutton3").hide() # img
			self.widgets.get_widget("filechooserbutton4").hide() # img
			self.widgets.get_widget("hbox2").hide()
			
			dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK,_("Please note: your removable drive must be empty or defragmented, otherwise it may not boot properly the ISO file!"))
			dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
			dialog.run()
			dialog.destroy()		
		elif active == 3: # img
			self.widgets.get_widget("frame1").hide()
			self.widgets.get_widget("frame5").hide()
			self.widgets.get_widget("frame6").hide()
			self.widgets.get_widget("radiobutton3").set_active(True)
			self.widgets.get_widget("checkbutton1").set_active(False)
			
			self.widgets.get_widget("image6").hide() # cd
			self.widgets.get_widget("radiobutton7").hide() # cd
			self.widgets.get_widget("hbox4").hide() # cd	
			
			self.widgets.get_widget("image7").hide() # iso
			self.widgets.get_widget("radiobutton8").hide() # iso
			self.widgets.get_widget("vbox4").hide() # iso
			self.widgets.get_widget("checkbutton2").hide() # md5check
			self.widgets.get_widget("checkbutton2").set_active(False) # md5check
			
			self.widgets.get_widget("image8").hide() # internet
			self.widgets.get_widget("hbox5").hide() # internet

			self.widgets.get_widget("image1").show() # img
			self.widgets.get_widget("radiobutton3").show() # img
			self.widgets.get_widget("filechooserbutton4").show() # img
			self.widgets.get_widget("hbox2").hide()
			
			dialog = gtk.MessageDialog(self.widgets.get_widget("window1"),gtk.DIALOG_MODAL,gtk.MESSAGE_WARNING,gtk.BUTTONS_OK,_("WARNING! This will erase ALL data in all partitions on the selected removable drive! Be very, very carefull!"))
			dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
			dialog.run()
			dialog.destroy()

		self.on_combobox2_changed(self.widgets.get_widget("combobox2"))		
		return
		
	def on_combobox1_changed(self,widget):
		self.list_distribution_versions()
		self.widgets.get_widget("combobox2").set_active(0)
		return

	def on_combobox2_changed(self,widget):
		if self.widgets.get_widget("combobox2").get_active_iter():
			path = os.path.join(self.presets_dir, self.widgets.get_widget("combobox1").get_active_text())
			config = CustomConfig()
			config.readfp(open(os.path.join(path, self.widgets.get_widget("combobox2").get_active_text(), "info.txt")))
			# self.widgets.get_widget("textview1").get_buffer().set_text(_(config.getvalue('liveusb', 'description')))
			self.widgets.get_widget("label17").set_text(_("(Download size: %.2f MB)") % (float(config.getvalue('liveusb', 'iso_size'))/1024/1024))
			if config.getvalue('liveusb', 'ubuntu_persistent') or config.getvalue('liveusb', 'debian_persistent'):
				self.widgets.get_widget("combobox5").set_active(0)
				self.widgets.get_widget("hbox2").set_sensitive(True)
			else:
				self.widgets.get_widget("hbox2").set_sensitive(False)
				self.widgets.get_widget("checkbutton1").set_active(False)

		return
			
	def on_radiobutton1_toggled(self,widget):	
		if widget.get_active() == True:
			self.widgets.get_widget("label22").hide()
			self.widgets.get_widget("entry6").hide()
			self.widgets.get_widget("label15").hide()
			self.widgets.get_widget("entry7").hide()
		return
		
	def on_radiobutton2_toggled(self,widget):	
		if widget.get_active() == True:
			self.widgets.get_widget("label22").show()
			self.widgets.get_widget("entry6").show()
			self.widgets.get_widget("label15").show()
			self.widgets.get_widget("entry7").show()
		return
				
	def on_checkbutton1_toggled(self,widget):
		if widget.get_active() == True:
			self.widgets.get_widget("combobox5").show()
			self.widgets.get_widget("label3").show()
		else:
			self.widgets.get_widget("combobox5").hide()
			self.widgets.get_widget("label3").hide()

	def on_checkbutton2_toggled(self,widget):
		if self.widgets.get_widget("checkbutton2").get_active() == True:
			self.detect_distribution()

	def on_button11_clicked(self ,widget):
		ns = Namespace()
		
		def cancel(widget, other = None):
			ns.window.get_widget("window6").destroy()

		def send(widget, other = None):
			startiter = ns.window.get_widget("textview1").get_buffer().get_start_iter()
			enditer = ns.window.get_widget("textview1").get_buffer().get_end_iter()
			description = ns.window.get_widget("textview1").get_buffer().get_text(startiter, enditer, True)
			params = urllib.urlencode({
				'name': ns.window.get_widget("entry3").get_text()
				, 'version': ns.window.get_widget("entry4").get_text()
				, 'arch': ns.window.get_widget("entry5").get_text()
				, 'description': description
				, 'url': ns.window.get_widget("entry6").get_text()
				, 'size': ns.window.get_widget("entry7").get_text()
				, 'md5': ns.window.get_widget("entry8").get_text()

			})
			f = urllib.urlopen("http://live.learnfree.eu/suggest-distribution.php?%s" % params)
			try:
				result = f.read()
				print 'RESPONSE:',result
				if result == 'OK':
					ns.window.get_widget("window6").destroy()
					self.msg_info(_("Your suggestion has been sent! Thank you for your support!"), ns.window.get_widget("window6"))
				elif result == 'REQ':
					self.msg_error(_("Please fill in all the required fields."), ns.window.get_widget("window6"))
				else:
					self.msg_error(_("There was an error while sending the data! Please try again."), ns.window.get_widget("window6"))
			except:
				self.msg_error(_("There was an error while sending the data! Make sure you have active Internet connection."), ns.window.get_widget("window6"))
				
		ns.window = gtk.glade.XML(self.gladefile,"window6" ,APP)
		gtk.glade.bindtextdomain(APP,DIR)
		dic = {
			"on_button1_clicked" : (cancel),
			"on_button2_clicked" : (send),
			"on_window6_delete_event" : (cancel)
		}
		ns.window.signal_autoconnect (dic)

		#window.get_widget('label3').set_text(remote)
		ns.window.get_widget("window6").show()
				
	def on_button10_clicked(self ,widget):
		if self.md5sum_thread:
			self.md5sum_thread.canceled = True
	
	def md5sum_cancel(self):
		self.widgets.get_widget("frame1").set_sensitive(True)
		self.widgets.get_widget("button1").set_sensitive(True)
		self.widgets.get_widget("combobox6").set_sensitive(True)
		self.widgets.get_widget("hbox6").hide()
		self.widgets.get_widget("filechooserbutton2").show()
		self.md5sum_thread = None
		
	def md5sum_done(self, value):
		#print value
		#self.msg_error(value)
		distributions = os.listdir(self.presets_dir)
		detected = False
		if distributions:
			for distribution in distributions:
				versions = os.listdir(os.path.join(self.presets_dir, distribution))
				if versions:
					for version in versions:
						if os.path.isdir(os.path.join(self.presets_dir,distribution, version)):
							config = CustomConfig()
							distro_info = os.path.join(self.presets_dir,distribution, version,"info.txt")
							config.readfp(open(distro_info))
							if config.getvalue('liveusb', 'md5') == value:
								print _("Detected %s/%s" % (distribution, version))
								self.msg_info(_("Detected supported distribution: <b>%s (%s)</b>") % (distribution, version))
								detected = True
								#self.list_distributions(distribution)
								#self.list_distribution_versions(version)
								self.combobox_select(self.widgets.get_widget("combobox1"), distribution, 0)
								self.combobox_select(self.widgets.get_widget("combobox2"), version, 0)
		if not detected:
			self.msg_info(_("It looks like that this distribution is unsupported."))
		self.widgets.get_widget("frame1").set_sensitive(True)
		self.widgets.get_widget("button1").set_sensitive(True)
		self.widgets.get_widget("combobox6").set_sensitive(True)
		self.widgets.get_widget("hbox6").hide()
		self.widgets.get_widget("filechooserbutton2").show()
		
		self.md5sum_thread = None
			
	def md5sum_progress(self, filename, bytes_done, bytes_total, percent):
		self.widgets.get_widget("progressbar1").set_text(_('Calculating MD5 Sum... %d%%') % int(percent))
		self.widgets.get_widget("progressbar1").set_fraction(percent/100)
	
	def detect_distribution(self):
		isoName_full = self.widgets.get_widget("filechooserbutton2").get_filename()
		if isoName_full:
			self.widgets.get_widget("frame1").set_sensitive(False)
			self.widgets.get_widget("button1").set_sensitive(False)
			self.widgets.get_widget("combobox6").set_sensitive(False)
			self.widgets.get_widget("filechooserbutton2").hide()
			self.widgets.get_widget("hbox6").show()
		
			self.md5sum_thread = Md5SumThread(isoName_full, self.md5sum_progress, self.md5sum_done, self.md5sum_cancel)
			self.md5sum_thread.start()
					
	def on_filechooserbutton2_file_set(self,widget):
		isoName_full = self.widgets.get_widget("filechooserbutton2").get_filename()
		print isoName_full
		if isoName_full:
			self.widgets.get_widget("radiobutton8").set_active(True)	
			self.widgets.get_widget("entry5").set_text(os.path.basename(isoName_full))	

			if self.widgets.get_widget("combobox6").get_active() == 0 and self.widgets.get_widget("checkbutton2").get_active():
				self.detect_distribution()

	#### Other functions

	def list_cd_drives(self):
		drives = []
		if platform.system() == "Windows":
			import win32api
			import win32file
			all_drives = (drive for drive in win32api.GetLogicalDriveStrings ().split ("\000") if drive)
			for drive in all_drives:
				try:
					info = win32api.GetVolumeInformation(drive)
				
					if win32file.GetDriveType(drive) == 5:
						drives.append([drive,info[0],''])
				except:
					pass
		else:
			storages = os.popen('hal-find-by-capability --capability storage').read().split()
			for udi in storages:
				try:
					udi = udi.strip()
					isRemovable = os.popen('hal-get-property --udi ' + udi + ' --key storage.drive_type').read()
					#size = int(os.popen('hal-get-property --udi ' + udi + ' --key storage.size').read())
					if isRemovable.find("cdrom") > -1: # and size > 0:
						device = os.popen('hal-get-property --udi ' + udi + ' --key block.device').read().strip()
						parent_udi = os.popen('hal-find-by-property --key block.storage_device --string ' + udi).read().split ("\n")[0]
						mount_point = os.popen('hal-get-property --udi ' + parent_udi + ' --key volume.mount_point').read().strip()
						drives.append([device, mount_point])
				except:
					pass
		return drives
	
	def combobox_select(self, cb, text, col = 0):
		cb.set_active(0)
		model = cb.get_model()
		iter = model.get_iter_first()
		while iter:
			if model.get_value(iter,col) == text:
				cb.set_active_iter(iter)
				return		
			iter = model.iter_next(iter)
			
	def get_parent_device(self, dev):
		block_device = os.popen('hal-find-by-property --key block.device --string ' + dev).read().strip()
		storage_device = os.popen('hal-get-property --udi ' + block_device + ' --key block.storage_device').read().strip()
		return os.popen('hal-get-property --udi ' + storage_device + ' --key block.device').read().strip()
		
	def get_mbrid(self, dev):
		if platform.system() == "Windows":
			mbr_signature = False
			c = wmi.WMI ()
			for disk in c.query("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'"):
				for partition in c.query("SELECT * FROM Win32_DiskPartition WHERE DiskIndex='" + str(disk.Index) + "'"):
					for partition_1 in c.query("SELECT * FROM Win32_LogicalDiskToPartition"):
						if partition_1.Dependent.DeviceID == dev.upper():
							mbr_signature = hex(disk.Signature)

			return mbr_signature
		else:
			p = os.popen('dd if=%s bs=1 count=4 skip=440 | hexdump -n4 -e \'"0x%%x"\'' % self.get_parent_device(dev))
			if p:
				return p.read().strip()
			else:
				return False
	
class Md5SumThread(Thread):
	def __init__ (self, filename, callback_progress = None, callback_done = None, callback_canceled = None):
		#Thread.__init__(self)
		super(Md5SumThread, self).__init__()

		self.filename = filename.encode(sys.getfilesystemencoding(), 'replace')
		self.callback_progress = callback_progress
		self.callback_done = callback_done
		self.callback_canceled = callback_canceled
		self.canceled = False
		
	def run(self):
		bytes_total = os.path.getsize(self.filename)
		bytes_done = 0
		m = hashlib.md5()
		f = open(self.filename, "rb")
		while 1:
			data = f.read(1024*1024)
			if not data or self.canceled:
				break
			m.update(data)
			bytes_done += len(data)
			if self.callback_progress:
				gobject.idle_add(self.callback_progress, self.filename, bytes_done, bytes_total, 100.0 * float(bytes_done) / bytes_total)
				#self.callback_progress(self.filename, bytes_done, bytes_total, 100.0 * float(bytes_done) / bytes_total)

		f.close()
		
		if self.canceled == True:
			if self.callback_canceled:
				gobject.idle_add(self.callback_canceled)
		else:
			self.md5sum = m.hexdigest()
			if self.callback_done:
				gobject.idle_add(self.callback_done, self.md5sum)
			#self.callback_done(self.md5sum)

class Namespace: pass

class CustomConfig( ConfigParser.ConfigParser ):
	def getvalue(self,section,name,default = ''):
		try:
			value = self.get(section,name)
		except:
			value = default
		return value
	

def getText(title, message, label, default = ''):
	def responseToDialog( entry, dialog, response):
		dialog.response(response)

	dialog = gtk.MessageDialog(
		None,
		gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
		gtk.MESSAGE_QUESTION,
		gtk.BUTTONS_OK_CANCEL,
		None
	)
	dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
	dialog.set_markup(message)
	dialog.set_title(title)

	entry = gtk.Entry()
	entry.set_text(default)
	entry.connect("activate", responseToDialog, dialog, gtk.RESPONSE_OK)
	hbox = gtk.HBox()
	hbox.pack_start(gtk.Label(label), False, 5, 5)
	hbox.pack_end(entry)
	dialog.vbox.pack_end(hbox, True, True, 0)
	dialog.show_all()
	response = dialog.run()
	text = entry.get_text()
	dialog.destroy()
	
	if response == gtk.RESPONSE_OK:
		return text
	else:
		return None
		
if platform.system() == "Windows":
	app = appgui()
	gtk.main()
else:
	if os.popen('whoami').read().strip() != 'root':
		if os.system('which gksu')==0:
			starter = os.path.join(os.path.dirname(sys.argv[0]),"live-usb-install.desktop")
			os.system('gksu -D %s ./live-usb-install.py' % '/usr/share/applications/live-usb-install.desktop' if os.path.exists('/usr/share/applications/live-usb-install.desktop') else _('live-usb-install'))
		elif os.system('which kdesudo')==0:
			os.system('kdesudo ./live-usb-install.py')
		else:
			password = getText('Enter your password','Password:','Password')
			if password:
				os.popen('sudo -S ./live-usb-install.py','w').write(password)
	else:
		app = appgui()
		gtk.main()



