#!/usr/bin/env python2
#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 re
import asubprocess
import urllib
import signal
from distutils import version
from shutil import *

try:
    import libtorrent
    LIBTORRENT_AVAILABLE = True
except:
    LIBTORRENT_AVAILABLE = False
    
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

import appversion

#APP = appversion.APP
APP_VERSION = appversion.APP_VERSION
#appversion.DEFAULT_DISTRO = appversion.appversion.DEFAULT_DISTRO

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(appversion.APP, DIR)
gettext.textdomain(appversion.APP)
gettext.install(appversion.APP, localedir=DIR)
gtk.glade.bindtextdomain(appversion.APP, DIR)
gtk.glade.textdomain(appversion.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,appversion.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_button12_clicked": self.on_button12_clicked,
            "on_button13_clicked": self.on_button13_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_button14_clicked" : self.on_button14_clicked,
            "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>' % (_("LiveUSB Install"), appversion.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)  
        
        if platform.system() == "Windows":
            self.presets_update_dir = os.path.join(os.environ['APPDATA'], appversion.APP, "presets")
            self.copy_presets(os.path.join(os.path.abspath(self.glade_dir),"presets"), self.presets_update_dir)
            #if not os.path.exists(self.presets_update_dir):
                #copytree(os.path.join(os.path.abspath(self.glade_dir),"presets"), self.presets_update_dir)
        else:
            self.presets_update_dir = os.path.join(os.path.abspath(self.glade_dir),"presets")
            #self.presets_update_dir = "/opt/live-usb-install/presets"
            #if not os.path.exists(self.presets_update_dir):
                #copytree(os.path.join(os.path.abspath(self.glade_dir),"presets"), self.presets_update_dir)
            
        self.presets_dir = self.presets_update_dir
        self.list_distributions()
        self.list_distribution_versions()
        
        default_fn = os.path.join(self.presets_dir,'default')
        if os.path.exists(default_fn):
            appversion.DEFAULT_DISTRO = open(default_fn,'r').read().strip().split('|')
        
        self.combobox_select(self.widgets.get_widget("combobox1"), appversion.DEFAULT_DISTRO[0],0)
        self.combobox_select(self.widgets.get_widget("combobox2"), appversion.DEFAULT_DISTRO[1],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()
        self.widgets.get_widget("window1").set_position(gtk.WIN_POS_CENTER_ALWAYS)
        #UpdaterThread(self.vercheck_done).start()
        PresetUpdaterThread(self.presetcheck_done, self.presets_dir).start()
        return
    
    #def vercheck_done(self, result):
        #self.msg_info(_("A new version of this program is available - %(version)s!\nDownload it from: %(url)s") % {'version': result[0], 'url': result[1]})
    def copy_presets(self, source, dest):
        if os.path.exists(dest) and os.path.exists(os.path.join(dest, 'timestamp')):
            dest_presets = {}
            source_presets = {}
            
            updated_presets = {}
            new_presets = {}
            deleted_presets = {}
            
            
            data = open(os.path.join(source,'timestamp')).read()
            data = data.split('\n')
            for row in data:
                if row != '':
                    row = row.split('|')
                    source_presets[row[0]] = row[1]
                
            data = open(os.path.join(dest,'timestamp')).read()
            data = data.split('\n')
            for row in data:
                if row != '':
                    row = row.split('|')
                    timestamp = row[1]
                    dest_presets[row[0]] = row[1]
            
            for preset in source_presets:
                if preset not in dest_presets:
                    new_presets[preset] = source_presets[preset]
                else:
                    if source_presets[preset] > dest_presets[preset]:
                        updated_presets[preset] = source_presets[preset]
                        if os.path.exists(os.path.join(self.presets_update_dir, preset)):
                            rmtree(os.path.join(self.presets_update_dir, preset))
            
            for preset in dest_presets:
                if preset not in source_presets:
                    deleted_presets[preset] = dest_presets[preset]
                    if os.path.exists(os.path.join(self.presets_update_dir, preset)):
                        rmtree(os.path.join(self.presets_update_dir, preset))
            
            copytree(source, dest)
            #msg = '\n'
            #msg += 'Deleted: '+ ', '.join(deleted_presets)+'\n'
            #msg += 'Updated: '+ ', '.join(updated_presets)+'\n'
            #msg += 'New: '+ ', '.join(new_presets)+'\n'
            #self.msg_info(msg)
        else:
            try:
                os.makedirs(dest)
            except:
                pass
            copytree(os.path.join(os.path.abspath(self.glade_dir),"presets"), self.presets_update_dir)
            
    def presetcheck_done(self, result):
        if result == 0:
            pass
        else:
            #result = self.msg_question(_("There are some updates available for the following distributions: %s\n\nDo you want to download them?") % ", ".join(result))
            if result['app_update']:
                self.msg_info(_("A new version of this program is available - %(version)s!\nDownload it from: %(url)s") % {'version': result['app_update'][0], 'url': result['app_update'][1]})
            else:
                #print result
                if result['updated'] != {} or result['deleted'] != {}:
                    msg = _("There are updates available!\n\n")
                    if result['updated'] != {}:
                        msg += _("Updated distributions: %s\n\n") % ", ".join(result['updated'])
                    if result['deleted'] != {}:
                        msg += _("Removed distributions: %s\n\n") % ", ".join(result['deleted'])
                    
                    msg += _("Would you like to download the updates?")
                    answer = self.msg_question(msg)
                    if answer == True:
                        self.widgets.get_widget("window1").hide()
                        if os.path.exists(self.presets_update_dir):
                            for preset in result['deleted']:
                                if os.path.exists(os.path.join(self.presets_update_dir, preset)):
                                    rmtree(os.path.join(self.presets_update_dir, preset))
                            
                            for preset in result['updated']:
                                if os.path.exists(os.path.join(self.presets_update_dir, preset)):
                                    rmtree(os.path.join(self.presets_update_dir, preset))
                        else:
                            os.makedirs(self.presets_update_dir)
                            
                        to_download = []
                        for preset in result['updated']:
                            print "MKDIR: %s" % os.path.join(self.presets_update_dir, preset)
                            print "GET: http://live.learnfree.eu/backends/presets/%s.7z" % preset
                            to_download.append("http://live.learnfree.eu/backends/presets/%s.7z" % preset)
                        to_download += ["http://live.learnfree.eu/backends/presets/timestamp"]
                        print to_download
                        if os.path.exists(os.path.join(self.presets_update_dir, "timestamp")):
                            os.unlink(os.path.join(self.presets_update_dir, "timestamp"))
                        self.download_file(to_download, self.presets_update_dir)
                        listing = os.listdir(self.presets_update_dir)
                        print "LISTING:", listing
                        if listing != []:
                            archives = []
                            for v in listing:
                                if re.search("\.7z$", v) != None:
                                    preset_archive = os.path.join(self.presets_update_dir, v)
                                    archives.append(preset_archive)
                            self.uncompress(archives, self.presets_update_dir, True)
                            self.list_distributions()
                            self.list_distribution_versions()

                            self.msg_info(_("The update is complete!"))
                        else:
                            self.msg_error(_("Oops, something went wrong :("))
                        self.widgets.get_widget("window1").show()
        default_fn = os.path.join(self.presets_dir,'default')
        if os.path.exists(default_fn):
            appversion.DEFAULT_DISTRO = open(default_fn,'r').read().strip().split('|')
        self.combobox_select(self.widgets.get_widget("combobox1"), appversion.DEFAULT_DISTRO[0],0)
        self.combobox_select(self.widgets.get_widget("combobox2"), appversion.DEFAULT_DISTRO[1],0)                        
    
    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:
            try:
                import pyudev
                context = pyudev.Context()
                enumerator = pyudev.Enumerator(context)
                enumerator.match(subsystem="block", ID_FS_USAGE="filesystem", ID_TYPE="disk", ID_BUS="usb")
                for device in enumerator:
                    if 'DEVTYPE' in device \
                        and 'ID_FS_UUID' in device \
                        and 'ID_FS_USAGE' in device \
                        and 'ID_TYPE' in device \
                        and 'ID_FS_TYPE' in device \
                        and 'ID_BUS' in device:
                        if device['ID_BUS'] == 'usb' and device['ID_FS_USAGE'] == 'filesystem':
                            mountpoint = os.popen('mount | grep %s | cut -d" " -f3' % device['DEVNAME']).read().strip()
                            size = os.popen("df -B 1 %s | head -n2 | tail -1 | awk '{ print $2 }'" % device['DEVNAME']).read().strip()
                            if 'ID_FS_VERSION' in device:
                                ID_FS_VERSION = device['ID_FS_VERSION']
                            else:
                                ID_FS_VERSION = ''
                            if 'ID_FS_LABEL' in device:
                                ID_FS_LABEL = device['ID_FS_LABEL']
                            else:
                                ID_FS_LABEL = ''
                            if mountpoint:
                                self.drives[device['DEVNAME']] = {
                                    'label'   : ID_FS_LABEL,
                                    'fstype'  : device['ID_FS_TYPE'],
                                    'fsversion': ID_FS_VERSION,
                                    'uuid'    : device['ID_FS_UUID'],
                                    'mount'   : mountpoint,
                                    'udi'     : None,
                                    'unmount' : False,
                                    'free'    : mountpoint and int(self.get_free_bytes(mountpoint)) or None,
                                    'size': int(size),
                                    'device'  : device['DEVNAME'],
                                    'parent'  : self.get_parent_device(device['DEVNAME'])
                                }
            except:
                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):
        distributions = self.get_distributions(self.presets_dir)
        self.widgets.get_widget("combobox1").get_model().clear()
        if distributions:
            for distribution in distributions:
                self.widgets.get_widget("combobox1").append_text(distribution)
                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)
        versions = self.get_versions(self.widgets.get_widget("combobox1").get_active_text())
        if versions:
            sort_nicely(versions)
            for version in versions:
                self.widgets.get_widget("combobox2").append_text(version)

    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)"""
        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):
        """ 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" ,appversion.APP)
        gtk.glade.bindtextdomain(APP,appversion.APP)
        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(_('%(sizemb).2fMB (%(sizeb)d bytes)') \
                % {'sizemb': s.total_wanted / 1024.0**2, 'sizeb': s.total_wanted})
            window.get_widget('label7').set_text(_('%(sizemb).2fMB (%(sizeb)d bytes)') \
                % {'sizemb': s.total_download / 1024.0**2, 'sizeb': 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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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 = '16M', 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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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, input_archive, target_dir, remove_archive = False):
        print "uncompress", input_archive, target_dir
        ns = Namespace()
        def cancel_process(widget, other = None):
            ns.kill_process = True
            return False
        
        window = gtk.glade.XML(self.gladefile,"window5" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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...'))
        window.get_widget("window5").show()

        while gtk.events_pending():
            gtk.main_iteration_do()
        n = 0
        if type(input_archive) != list:
            input_archive = [input_archive]
        
        for archive in input_archive:
            n += 1
            #window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % (_('Extracting files, archive %d of %d...') % (n, len(input_archive))))
            window.get_widget('label1').set_markup('<span size="large" weight="bold">%s</span>' % (_('Extracting %s') % os.path.basename(archive)))
            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:
                    if len(input_archive) == 1:
                        window.get_widget("progressbar1").pulse()
                    else:
                        window.get_widget("progressbar1").set_fraction(float((n-1)) / float(len(input_archive)))

                while gtk.events_pending():
                    gtk.main_iteration_do()
                time.sleep(0.05)
            if remove_archive:
                os.unlink(archive)

        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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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    
        window.get_widget("progressbar1").set_text("")
        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:
                #line = ns.process.stdout.asyncread()
                #line = ns.process.asyncread(0.1).strip()
                #while gtk.events_pending():
                    #gtk.main_iteration_do()
                #if line:
                    #window.get_widget("label1").set_text(line)
                #m = re.search('Extracting\s+(.*?)', line)
                #if m:
                    #window.get_widget("label1").set_text(m.group(1))
                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
        
        if type(remote) != list:
            remote = [remote]
        ns = Namespace()
        
        def cancel_process(widget, other = None):
            ns.kill_process = True
            return False
        
        window = gtk.glade.XML(self.gladefile,"window2" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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()
        n = 0
        for url in remote:
            n += 1
            if os.path.isdir(local):
                if http_referrer:
                    argv = ['wget','--no-check-certificate','--referer="%s"' % http_referrer,'-S','-c','-P',local.encode(sys.getfilesystemencoding(), 'replace'), url]
                else:
                    argv = ['wget','--no-check-certificate','-S','-c','-P',local.encode(sys.getfilesystemencoding(), 'replace'), url]
            else:
                if http_referrer:
                    argv = ['wget','--no-check-certificate','--referer="%s"' % http_referrer,'-S','-c','-O',local.encode(sys.getfilesystemencoding(), 'replace'), url]
                else:
                    argv = ['wget','--no-check-certificate','-S','-c','-O',local.encode(sys.getfilesystemencoding(), 'replace'), url]
            print "URL", url
                    
            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.process = asubprocess.Popen(argv, stdout=asubprocess.PIPE, stderr=asubprocess.STDOUT, startupinfo=info)
            ns.kill_process = False
            
            
            #window.get_widget('label3').set_text('<span size="large" weight="bold">Downloading file...</span>' % (_("Downloading file %s of %s") % (n, len(remote))))
            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()
                    line = ns.process.asyncread(0.2)
                    while gtk.events_pending():
                        gtk.main_iteration_do()
                    #print line
                    m = re.search('--.*?--\s*(.*)', line)
                    if m:
                        window.get_widget('label3').set_text(m.group(1))
                    
                    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:
                        if len(remote) > 1:
                            window.get_widget("progressbar1").set_fraction(float(n) / float(len(remote)) + 0.01 / float(float(m.group(2))/100.0))
                        else:
                            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" ,appversion.APP)
        self.info_window = self.info_window_widgets.get_widget("window3")
        gtk.glade.bindtextdomain(appversion.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.jpg")
            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', '0'))/1024/1024))
            
            iso_size = int(config.getvalue('liveusb', 'iso_size', '0'))
            if iso_size != 0 and iso_size != '':
                self.info_window_widgets.get_widget("label5").set_text(_('%.2f MB') % (float(iso_size)/1024/1024))
                self.info_window_widgets.get_widget("label3").show()
                self.info_window_widgets.get_widget("label5").show()
            else:
                self.info_window_widgets.get_widget("label3").hide()
                self.info_window_widgets.get_widget("label5").hide()     
            
            md5 = config.getvalue('liveusb', 'md5')
            if md5:
                self.info_window_widgets.get_widget("label6").set_text(md5)
                self.info_window_widgets.get_widget("label4").show()
                self.info_window_widgets.get_widget("label6").show()
            else:
                self.info_window_widgets.get_widget("label4").hide()
                self.info_window_widgets.get_widget("label6").hide()     

            
            iso_location = config.getvalue('liveusb', 'iso_location')
            if iso_location:
                self.info_window_widgets.get_widget("label7").set_text(iso_location)
                self.info_window_widgets.get_widget("label2").show()
                self.info_window_widgets.get_widget("label7").show()
            else:
                self.info_window_widgets.get_widget("label2").hide()
                self.info_window_widgets.get_widget("label7").hide()     
                
            website = config.getvalue('liveusb', 'website')
            if website:
                self.info_window_widgets.get_widget("label9").set_text(website)
                self.info_window_widgets.get_widget("label8").show()
                self.info_window_widgets.get_widget("label9").show()
            else:
                self.info_window_widgets.get_widget("label8").hide()
                self.info_window_widgets.get_widget("label9").hide()    
                
                
            self.info_window_widgets.get_widget("window3").show()
        return
        
    def on_button8_clicked(self, widget):
        self.drive_info_window_widgets = gtk.glade.XML(self.gladefile,"window4" ,appversion.APP)
        self.drive_info_window = self.drive_info_window_widgets.get_widget("window4")
        gtk.glade.bindtextdomain(appversion.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)
                os.system('start explorer.exe "%s"' % removable_drive_path)
            else:
                removable_drive_path = self.widgets.get_widget("combobox4").get_model().get_value(removable_drive_iter,2)
                if 'SUDO_USER' in os.environ:
                    os.system('sudo -E -u %s xdg-open "%s" &' % (os.environ['SUDO_USER'], removable_drive_path))
                else:
                    os.system('xdg-open %s &' % removable_drive_path)
        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('start /wait cmd /c format /q /v: '+removable_drive_device)
                os.system('start /wait fat32format.exe '+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:
            parent = self.widgets.get_widget("window1")
        dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK)
        dialog.set_markup(msg)
        dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
        dialog.run()
        dialog.destroy()    

    def msg_info(self, msg, parent = None):
        if not parent:
            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 msg_question(self, msg, parent = None):
        if not parent:
            parent = self.widgets.get_widget("window1")
        dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO)
        dialog.set_markup(msg)
        dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
        response = dialog.run()
        dialog.destroy()
        return response == gtk.RESPONSE_YES

    def on_button1_clicked(self, widget):
        if self.widgets.get_widget("combobox6").get_active() == 4: # syslinux reinstall: do nothing
            return
        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.widgets.get_widget("window1").show()    
            self.msg_error(_("No removable drive selected!"))
            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
            if self.widgets.get_widget("combobox1").get_active_text() == None or self.widgets.get_widget("combobox2").get_active_text() == None:
                self.msg_error(_("Please select Distribution/Version!"))
                self.widgets.get_widget("window1").show()                    
                return
            
            cd_drive_iter = self.widgets.get_widget("combobox3").get_active_iter()
            if not cd_drive_iter:
                self.widgets.get_widget("window1").show()                    
                self.msg_error(_("No CD/DVD drive selected!"))
                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.widgets.get_widget("window1").show()                    
                    self.msg_error(_("No CD/DVD drive mounted!"))
                    return
            
            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_label').lower() == 'true' and self.drives[removable_drive_device]['label'] == '':
                    self.widgets.get_widget("window1").show()                    
                    self.msg_error(_("The selected distribution requires that your flash drive must have filesystem label! Please set the label and try again."))
                    return  
                
            if cd_drive_size > removable_drive_freespace:
                required_space = cd_drive_size - removable_drive_freespace
                self.widgets.get_widget("window1").show()
                self.msg_error(_("There is not enough free space on the selected removable drive. You must free additional %s MB") % required_space)
                return
            else:
                if self.copy_from_cd(cd_drive_path,removable_drive_path) != 0:
                    self.widgets.get_widget("window1").show()
                    self.msg_error(_("Installation aborted!"))
                    return

        #=======================================================================================    
        elif self.widgets.get_widget("radiobutton8").get_active() == True:  # Install from ISO
            if self.widgets.get_widget("combobox1").get_active_text() == None or self.widgets.get_widget("combobox2").get_active_text() == None:
                self.msg_error(_("Please select Distribution/Version!"))
                self.widgets.get_widget("window1").show()                    
                return
            if not self.widgets.get_widget("filechooserbutton2").get_filename():
                self.widgets.get_widget("window1").show()
                self.msg_error(_("Please select ISO file!"))
                return
            
            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_label').lower() == 'true' and self.drives[removable_drive_device]['label'] == '':
                    self.widgets.get_widget("window1").show()                    
                    self.msg_error(_("The selected distribution requires that your flash drive must have filesystem label! Please set the label and try again."))
                    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.widgets.get_widget("window1").show()
                    self.msg_error(_("Installation aborted!"))
                    return
            else:
                if self.extract_iso(self.widgets.get_widget("filechooserbutton2").get_filename(),removable_drive_path) != 0:
                    self.widgets.get_widget("window1").show()
                    self.msg_error(_("Installation aborted!"))
                    return
        
        #=======================================================================================    
        elif self.widgets.get_widget("radiobutton9").get_active() == True:  # Install from Internet
            if self.widgets.get_widget("combobox1").get_active_text() == None or self.widgets.get_widget("combobox2").get_active_text() == None:
                self.msg_error(_("Please select Distribution/Version!"))
                self.widgets.get_widget("window1").show()                    
                return
            

            
            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', '0')
            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 config.getvalue('liveusb', 'set_label').lower() == 'true' and self.drives[removable_drive_device]['label'] == '':
                    self.widgets.get_widget("window1").show()                    
                    self.msg_error(_("The selected distribution requires that your flash drive must have filesystem label! Please set the label and try again."))
                    return
            
            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 and LIBTORRENT_AVAILABLE:
                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.widgets.get_widget("window1").show()
                        self.msg_error(_("There was an error while extracting the iso file from the downloaded archive"))
                        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.widgets.get_widget("window1").show()
                        self.msg_error(_("Installation aborted!"))
                        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.widgets.get_widget("window1").show()
                        self.msg_error(_("Installation aborted!"))
                        return
                
                    extract_result = self.uncompress_iso(isoName_full, iso_extract, os.path.join(tempfile.gettempdir(),'live-usb-install'), archive)

                    if extract_result != 0:
                        self.widgets.get_widget("window1").show()
                        self.msg_error(_("There was an error while extracting the iso file from the downloaded archive"))
                        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.widgets.get_widget("window1").show()
                        self.msg_error(_("Installation aborted!"))
                        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.widgets.get_widget("window1").show()
                        self.msg_error(_("Installation aborted!"))
                        return
                
                if self.extract_iso(isoName_full,removable_drive_path) != 0:
                    self.widgets.get_widget("window1").show()
                    self.msg_error(_("Installation aborted!"))
                    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.widgets.get_widget("window1").show()
                self.msg_error(_("Please select image file!"))
                return
            
            if platform.system() == "Windows":
                img_write_result =  self.write_img(img_filename, removable_drive_device)
                
                if img_write_result != 0:
                    self.widgets.get_widget("window1").show()
                    self.msg_error(_("Error while transferring image file to %s. Installation aborted!") % removable_drive_device)
                    return
            else:
                parent_dev = self.get_parent_device(removable_drive_device)
                os.system('sync')
                
                if os.system('umount %s' % removable_drive_device)!=0:
                    self.widgets.get_widget("window1").show()
                    self.msg_error(_("The removable drive can not be unmounted. Installation aborted!"))
                    return
                
                img_write_result =  self.write_img(img_filename, parent_dev)
                
                            
                if img_write_result != 0:
                    self.widgets.get_widget("window1").show()
                    self.msg_error(_("Error while transferring image file to %s. Installation aborted!") % parent_dev)
                    return

            self.widgets.get_widget("window1").show()       
            self.msg_info(_("Installation is complete!\nTime taken: %f seconds") % round(time.time() - start))
            StatsThread('MODE:IMG', os.path.basename(img_filename)).start() 
            return # skip the rest!!
        #=======================================================================================    

        #if platform.system() == "Windows":
            #copy2('vesamenu.c32',removable_drive_path)
        #else:
            #if os.path.isfile('/usr/lib/syslinux/vesamenu.c32'):
                #copy2('/usr/lib/syslinux/vesamenu.c32',removable_drive_path)
            #else:
                #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 os.path.exists(removable_drive_path+'/syslinux'):
            #if os.path.exists(removable_drive_path+'/syslinux.orig'):
               #rmtree(removable_drive_path+'/syslinux.orig') 
            #move(removable_drive_path+'/syslinux', removable_drive_path+'/syslinux.orig')
            
        # Custom syslinux ===========================
        if self.widgets.get_widget("combobox6").get_active() == 1: 
            syslinux_cfg_f = open("./templates/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 not os.path.exists(removable_drive_path+'/syslinux/'):
                os.makedirs(removable_drive_path+'/syslinux/')

            if self.widgets.get_widget("filechooserbutton1").get_filename():
                copy2(self.widgets.get_widget("filechooserbutton1").get_filename(),removable_drive_path+'/syslinux/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/syslinux.cfg', 'w+')
            syslinux_f.write(syslinux_cfg)
            syslinux_f.close()
            
        # wingrub ===========================
        elif self.widgets.get_widget("combobox6").get_active() == 2:
            syslinux_cfg_f = open("./templates/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
            
            if not os.path.exists(removable_drive_path+'/syslinux/'):
                os.makedirs(removable_drive_path+'/syslinux/')
            
            syslinux_f = open(removable_drive_path+'/syslinux/syslinux.cfg', 'w+')
            syslinux_f.write(syslinux_cfg)
            syslinux_f.close()
                        
            menu_lst_f = open("./templates/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()
                
            copy2("./templates/backg.png",removable_drive_path+'/syslinux/')            
            copy2("./wingrub/grub.exe",removable_drive_path)
        else:
            print "COPY PRESET"
            if not os.path.exists(removable_drive_path+'/syslinux/'):
                os.makedirs(removable_drive_path+'/syslinux/')
            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+'/syslinux/')

            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',"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',"syslinux.cfg"), 'w+')
                syslinux_cfg_f.write(syslinux_cfg)        
                syslinux_cfg_f.close()
                
            if config.getvalue('liveusb', 'set_label').lower() == 'true':
                syslinux_cfg_f = open(os.path.join(removable_drive_path,'syslinux',"syslinux.cfg"))
                syslinux_cfg = syslinux_cfg_f.read()
                syslinux_cfg_f.close()            
                syslinux_cfg = syslinux_cfg.replace("%LABEL%",self.drives[removable_drive_device]['label'])
                syslinux_cfg_f = open(os.path.join(removable_drive_path,'syslinux',"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.widgets.get_widget("window1").show()
                    self.msg_error(_("Error while reading Master Boot Record ID! Installation aborted."))
                    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")
                cfg_f = open(cfg_filename)
                cfg_txt = cfg_f.read()
                cfg_f.close()
            
                cfg_txt = re.sub(r'(kernel.*?locale=)([a-zA-Z_]+)(.*)', '\\1'+locale.getdefaultlocale()[0]+'\\3', cfg_txt)
                cfg_txt = re.sub(r'(kernel.*?lang=)([a-zA-Z_]+)(.*)', '\\1'+locale.getdefaultlocale()[0].split('_')[0]+'\\3', cfg_txt)

                cfg_f = open(cfg_filename, 'w+')
                cfg_f.write(cfg_txt)    
                cfg_f.close()
            
            if os.path.isfile(os.path.join(removable_drive_path,'syslinux',"syslinux.cfg")):
                cfg_filename = os.path.join(removable_drive_path,'syslinux',"syslinux.cfg")
                cfg_f = open(cfg_filename)
                cfg_txt = cfg_f.read()
                cfg_f.close()
            
                cfg_txt = re.sub(r'(append.*?locale=)([a-zA-Z_]+)(.*)', '\\1'+locale.getdefaultlocale()[0]+'\\3', cfg_txt)
                cfg_txt = re.sub(r'(append.*?lang=)([a-zA-Z_]+)(.*)', '\\1'+locale.getdefaultlocale()[0].split('_')[0]+'\\3', cfg_txt)

                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_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"))
                if not os.path.exists(removable_drive_path+'/syslinux/'):
                    os.makedirs(removable_drive_path+'/syslinux/')

                syslinux_cfg_filename = os.path.join(removable_drive_path,'syslinux', "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 %(file)s %(size)s MB") % {'file': persistent_file, 'size': persistent_size}
                    , '16M'
                    , int(persistent_size / 16)
                )
                
                if dd_result != 0:
                    self.widgets.get_widget("window1").show()        
                    self.msg_error(_('The persistent storage was not created. Installation aborted!'))
                    return
                mkfs_result = self.mkfs(persistent_file, persistent_label)
                if mkfs_result != 0:
                    self.widgets.get_widget("window1").show()        
                    self.msg_error(_('The persistent storage was not formated. Installation aborted!'))
                    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):
                copy2(backg_file,removable_drive_path)
            else:
                copy2(os.path.join(self.glade_dir, 'templates', "backg.png"),removable_drive_path+'/syslinux/')
                
            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
                
        print "INSTALL SYSLINUX"
        if self.install_syslinux(removable_drive_device, removable_drive_path) == False:
            self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
            return
        print "INSTALL SYSLINUX - DONE"
        #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:
            #if os.system("syslinux.exe -maf " + removable_drive_device) != 0:
                #self.widgets.get_widget("window1").show()
                #self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
                #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.widgets.get_widget("window1").show()
                #self.msg_error(_("The target drive can not be unmounted, and the syslinux bootloader will not be installed! Installation aborted."))
                #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.widgets.get_widget("window1").show()
                    #self.msg_error(_("Cant mark partition %s as active! Installation aborted.") % removable_drive_device)
                    #return

            #if os.system("./syslinux -if " + removable_drive_device) != 0:
                ##if os.system("syslinux -sf " + removable_drive_device) != 0:
				#self.widgets.get_widget("window1").show()
				#self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
				#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.widgets.get_widget("window1").show()
                #self.msg_error(_("Error while writing master boot record! Installation aborted."))
                #return            
        
        self.widgets.get_widget("window1").show()
        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):
                        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()

        if self.widgets.get_widget("combobox6").get_active() == 0:
            StatsThread(self.widgets.get_widget("combobox1").get_active_text(), self.widgets.get_widget("combobox2").get_active_text()).start()

        
        return
        
    def on_button2_clicked(self, widget):
        about = gtk.AboutDialog()
        about.set_position(gtk.WIN_POS_CENTER_ALWAYS)
        about.set_program_name("LiveUSB Install")
        about.set_version(appversion.APP_VERSION)
        about.set_authors([_("Krasimir S. Stefanov <lokiisyourmaster@gmail.com>")])
        about.set_website("http://live.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()
        #sys.exit(0)
        
    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, _('%(used).2f / %(size).2f GB (%(fstype)s)') % {
                            'used': float(self.drives[drive]['size'] - self.drives[drive]['free'])/1024.0**3,
                            'size': float(self.drives[drive]['size'])/1024.0**3,
                            'fstype': 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, _('%(used).2f / %(size).2f GB (%(fstype)s)') % {
                            'used': float(self.drives[drive]['size'] - self.drives[drive]['free'])/1024.0**3, 
                            'size': float(self.drives[drive]['size'])/1024.0**3, 
                            'fstype': 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.widgets.get_widget("button9").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("button9").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("frame2").show()
            self.widgets.get_widget("frame5").hide()
            self.widgets.get_widget("frame6").hide()
            self.widgets.get_widget("frame7").hide()
            self.widgets.get_widget("button1").set_sensitive(True)
            
            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("button14").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("frame2").show()
            self.widgets.get_widget("frame5").show()
            self.widgets.get_widget("frame6").hide()
            self.widgets.get_widget("frame7").hide()
            self.widgets.get_widget("button1").set_sensitive(True)
            self.widgets.get_widget("hbox2").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("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("button14").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("frame2").show()
            self.widgets.get_widget("frame5").hide()
            self.widgets.get_widget("frame6").show()
            self.widgets.get_widget("frame7").hide()
            self.widgets.get_widget("button1").set_sensitive(True)
            self.widgets.get_widget("hbox2").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("button14").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("frame2").show()
            self.widgets.get_widget("frame5").hide()
            self.widgets.get_widget("frame6").hide()
            self.widgets.get_widget("frame7").hide()
            self.widgets.get_widget("button1").set_sensitive(True)
            self.widgets.get_widget("radiobutton3").set_active(True)
            self.widgets.get_widget("checkbutton1").set_active(False)
            self.widgets.get_widget("hbox2").hide()
            
            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("button14").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()

        elif active == 4: # Syslinux reinstall
            self.widgets.get_widget("frame1").hide()
            self.widgets.get_widget("frame2").hide()
            self.widgets.get_widget("frame5").hide()
            self.widgets.get_widget("frame6").hide()
            self.widgets.get_widget("frame7").show()
            self.widgets.get_widget("button1").set_sensitive(False)
            self.widgets.get_widget("hbox2").hide()
            
        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')))
            
            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)
            
            if not config.getvalue('liveusb', 'iso_location'):
                self.widgets.get_widget("image8").set_sensitive(False)            
                self.widgets.get_widget("radiobutton9").set_sensitive(False)
                self.widgets.get_widget("label17").set_sensitive(False)
                self.widgets.get_widget("label17").set_text(_('Download unavailable!'))
            else:
                if config.getvalue('liveusb', 'in_torrent') and LIBTORRENT_AVAILABLE == False:
                    self.widgets.get_widget("image8").set_sensitive(False)            
                    self.widgets.get_widget("radiobutton9").set_sensitive(False)
                    self.widgets.get_widget("label17").set_sensitive(False)
                    self.widgets.get_widget("label17").set_text(_('Please install libtorrent!'))
                else:
                    self.widgets.get_widget("image8").set_sensitive(True)
                    self.widgets.get_widget("radiobutton9").set_sensitive(True)
                    self.widgets.get_widget("label17").set_sensitive(True)
                    
                    size = float(config.getvalue('liveusb', 'iso_size', '0.0'))/1024/1024
                    if size > 0:
                        size_txt = _("(Download size: %.2f MB)") % size
                    else:
                        size_txt = _("(Download size: unknown)")
                    self.widgets.get_widget("label17").set_text(size_txt)
            
            if config.getvalue('liveusb', 'dd_only') and self.widgets.get_widget("combobox6").get_active() == 0:
                self.msg_info(_("The selected distribution can only be installed in \"IMG Write\" mode! Please select it from the combobox above, and from the \"IMG File\" select your ISO file."))
        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_button14_clicked(self ,widget):
        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):
            params = urllib.urlencode({
                'distribution': ns.window.get_widget("entry3").get_text()
                , 'url': ns.window.get_widget("entry4").get_text()

            })
            f = urllib.urlopen("http://live.learnfree.eu/suggest-distribution.php?%s" % params)
            try:
                result = f.read()
                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" ,appversion.APP)
        gtk.glade.bindtextdomain(appversion.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("hbox7").show()
        self.md5sum_thread = None
    
    def get_distributions(self, presets_dir):
        distributions = []
        listing = os.listdir(presets_dir)
        for d in listing:
            if os.path.isdir(os.path.join(presets_dir, d)):
                distributions.append(d)
        return distributions
    
    def get_versions(self, distribution):
        if distribution:
            versions = []
            listing = os.listdir(os.path.join(self.presets_dir, distribution))
            for v in listing:
                if os.path.isdir(os.path.join(self.presets_dir, distribution, v)):
                    versions.append(v)
            return versions
    
    def md5sum_done(self, value):
        distributions = self.get_distributions(self.presets_dir)
        detected = False
        if distributions:
            for distribution in distributions:
                versions = self.get_versions(distribution)
                if versions:
                    for version in versions:
                        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:
                            self.msg_info(_("Detected supported distribution: <b>%(distribution)s (%(version)s)</b>") % {
                                'distribution': distribution, 'version': version
                            })
                            detected = True
                            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("hbox7").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("hbox7").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()
        if isoName_full:
            self.widgets.get_widget("radiobutton8").set_active(True)    
            self.widgets.get_widget("entry5").set_text(os.path.basename(isoName_full))    

            distributions = self.get_distributions(self.presets_dir)
            detected = False
            if distributions:
                for distribution in distributions:
                    versions = self.get_versions(distribution)
                    if versions:
                        for version in versions:
                            config = CustomConfig()
                            distro_info = os.path.join(self.presets_dir,distribution, version,"info.txt")
                            config.readfp(open(distro_info))
                            if os.path.basename(config.getvalue('liveusb', 'iso_location').replace('.torrent','')) == os.path.basename(isoName_full):
                                #self.msg_info(_("Detected supported distribution: <b>%(distribution)s (%(version)s)</b>") % {
                                    #'distribution': distribution, 'version': version
                                #})
                                detected = True
                                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."))

            #if not detected and self.widgets.get_widget("combobox6").get_active() == 0 and self.widgets.get_widget("checkbutton2").get_active():
                #self.detect_distribution()
    
    def on_button12_clicked(self ,widget):
        removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
        if not removable_drive_iter:
            self.msg_error(_("No removable drive selected!"))
            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)

        #if platform.system() == "Windows":
        #copy2('vesamenu.c32',removable_drive_path)
        #copy2('menu.c32',removable_drive_path)
        #copy2('chain.c32',removable_drive_path)
        #copy2('libutil.c32',removable_drive_path)
        #copy2('memdisk',removable_drive_path)
        #else:
            #if os.path.isfile('/usr/lib/syslinux/vesamenu.c32'):
                #copy2('/usr/lib/syslinux/vesamenu.c32',removable_drive_path)
            #else:
                #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"')            
            

        syslinux_cfg_f = open("./templates/syslinux-custom.cfg")
        syslinux_cfg = syslinux_cfg_f.read()
        syslinux_cfg_f.close()

        syslinux_cfg = syslinux_cfg.replace("%MENU_LABEL%",'Example Linux Config')
        syslinux_cfg = syslinux_cfg.replace("%KERNEL%",'/vmlinuz')
        syslinux_cfg = syslinux_cfg.replace("%APPEND%",'/initrd')
        
        if not os.path.isdir(removable_drive_path+'/syslinux/'): # This one line does the trick
            os.makedirs(removable_drive_path+'/syslinux/')
        copy2('./templates/backg.png',removable_drive_path+'/syslinux/backg.png')
        syslinux_cfg = syslinux_cfg.replace('%MENUBG%','MENU BACKGROUND backg.png')
        
        syslinux_f = open(removable_drive_path+'/syslinux/syslinux.cfg', 'w+')
        syslinux_f.write(syslinux_cfg)
        syslinux_f.close()

        if self.install_syslinux(removable_drive_device, removable_drive_path) == False:
            self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
            return
        #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("button4").clicked()
                #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("button4").clicked()
                #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("button4").clicked()
                    #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("button4").clicked()
                    #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("button4").clicked()
                #return
            #self.msg_info(_("Syslinux installed successfully!"))
            #self.widgets.get_widget("button4").clicked()
            
    def install_syslinux(self, removable_drive_device, removable_drive_path):
        if platform.system() == "Windows":
            os.system('del ' + removable_drive_path+'\\boot\\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.cfg"') 

        
        #copy2('vesamenu.c32',removable_drive_path)
        #copy2('menu.c32',removable_drive_path)
        #copy2('chain.c32',removable_drive_path)
        #copy2('libutil.c32',removable_drive_path)
        #copy2('libcom32.c32',removable_drive_path)
        #copy2('memdisk',removable_drive_path)
        copytree('./syslinux/', removable_drive_path+'/syslinux/')
        #copy2('./syslinux/*', removable_drive_path+'/syslinux/')
        
        if platform.system() == "Windows":
            os.system("del /F /Q " + os.path.join(removable_drive_path,'ldlinux.sys'))
            #print "syslinux/syslinux.exe --force --active --mbr " + removable_drive_device
            #os.chdir(
            syslinux_cmd  = "syslinux\syslinux.exe -sfma %s" % removable_drive_device
            print syslinux_cmd
            if os.system(syslinux_cmd) != 0:
                self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
                self.widgets.get_widget("button4").clicked()
                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("button4").clicked()
                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("button4").clicked()
                    return

            if os.system("./syslinux/syslinux -if " + 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("button4").clicked()
                #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','syslinux.mbr'), parent_dev)) != 0:
                self.msg_error(_("Error while writing master boot record! Installation aborted."))
                self.widgets.get_widget("button4").clicked()
                return
            self.widgets.get_widget("button4").clicked()
        return True
        
        
    def on_button13_clicked(self ,widget):
        removable_drive_iter = self.widgets.get_widget("combobox4").get_active_iter()
        if not removable_drive_iter:
            self.msg_error(_("No removable drive selected!"))
            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)

        #if platform.system() == "Windows":
            #copy2('vesamenu.c32',removable_drive_path)
        #else:
            #if os.path.isfile('/usr/lib/syslinux/vesamenu.c32'):
                #copy2('/usr/lib/syslinux/vesamenu.c32',removable_drive_path)
            #else:
                #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"')            
            

        syslinux_cfg_f = open("./templates/syslinux-custom.cfg")
        syslinux_cfg = syslinux_cfg_f.read()
        syslinux_cfg_f.close()

        syslinux_cfg = syslinux_cfg.replace("%MENU_LABEL%",'Wingrub')
        syslinux_cfg = syslinux_cfg.replace("%KERNEL%",'/grub.exe')
        syslinux_cfg = syslinux_cfg.replace("append %APPEND%",'')
        
        copy2('./templates/backg.png',removable_drive_path+'/syslinux/backg.png')
        syslinux_cfg = syslinux_cfg.replace('%MENUBG%','MENU BACKGROUND backg.png')
        
        syslinux_f = open(removable_drive_path+'/syslinux/syslinux.cfg', 'w+')
        syslinux_f.write(syslinux_cfg)
        syslinux_f.close()

        copy2("./wingrub/grub.exe",removable_drive_path)
        copy2("./templates/wingrub-menu.lst",removable_drive_path+'/menu.lst')
                              
        if self.install_syslinux(removable_drive_device, removable_drive_path) == False:
            self.msg_error(_("Error while installing syslinux bootloader! Installation aborted."))
            return
        #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("button4").clicked()
                #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("button4").clicked()
                #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("button4").clicked()
                    #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("button4").clicked()
                    #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("button4").clicked()
                #return   
            #self.msg_info(_("Syslinux and Wingrub installed successfully!"))
            #self.widgets.get_widget("button4").clicked()
    #### 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:
            try:
                import pyudev
                context = pyudev.Context()
                enumerator = pyudev.Enumerator(context)
                enumerator.match(ID_TYPE="cd")
                for device in enumerator:
                    mountpoint = os.popen('mount | grep %s | cut -d" " -f3' % device['DEVNAME']).read().strip()
                    drives.append([device['DEVNAME'], mountpoint])
                return drives
            except:
                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()
                        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):
        m = re.search('(.*\/sd[a-z])\d?', dev)
        if m != None:
            return m.group(1)
        else:
            return dev
        
    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).strip()
            if value == '':
                return default
        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

def check_version():
    try:
        html = urllib.urlopen('http://live.learnfree.eu/version.txt').read()
    except:
        return []
    
    try:
        NEW_APP_VERSION = re.search('APP_VERSION=(.*)', html).group(1)
        DOWNLOAD_URL = re.search('DOWNLOAD_URL=(.*)', html).group(1)
    except:
        return []
        
    if version.StrictVersion(NEW_APP_VERSION) > version.StrictVersion(appversion.APP_VERSION):
        return [NEW_APP_VERSION, DOWNLOAD_URL]
    else:
        return []

def update_presets(presets_dir):
    app_update = False
    html = ''
    try:
        html = urllib.urlopen('http://live.learnfree.eu/version.txt').read()
    except:
        pass
    
    if html:
        try:
            NEW_APP_VERSION = re.search('APP_VERSION=(.*)', html).group(1)
            DOWNLOAD_URL = re.search('DOWNLOAD_URL=(.*)', html).group(1)
            if version.StrictVersion(NEW_APP_VERSION) > version.StrictVersion(appversion.APP_VERSION):
                app_update = [NEW_APP_VERSION, DOWNLOAD_URL]
        except:
            pass
        

    remote_presets = {}
    local_presets = {}
    updated_presets = {}
    deleted_presets = {}
    if os.path.exists(os.path.join(presets_dir,'timestamp')):
        data = open(os.path.join(presets_dir,'timestamp')).read()
        data = data.split('\n')
        for row in data:
            if row != '':
                row = row.split('|')
                local_presets[row[0]] = row[1]
        
    try:
        data = urllib.urlopen('http://live.learnfree.eu/backends/presets/timestamp').read()
    except:
        return False
    data = data.split('\n')
    for row in data:
        if row != '':
            row = row.split('|')
            name = row[0]
            timestamp = row[1]
            remote_presets[row[0]] = row[1]
            if row[0] in local_presets:
                if int(row[1]) > int(local_presets[row[0]]):
                    updated_presets[row[0]] = row[1]
            else:
                updated_presets[row[0]] = row[1]
    
    for preset in local_presets:
        if preset not in remote_presets:
            deleted_presets[preset] = local_presets[preset]
            
    try:
        default = urllib.urlopen('http://live.learnfree.eu/backends/presets/default').read()
        default_f = open(presets_dir+'/default', 'w+')
        default_f.write(default)
        default_f.close()
    except:
        pass
        
    return {'updated': updated_presets, 'deleted': deleted_presets, 'app_update': app_update}
    
class UpdaterThread(Thread):
    def __init__ (self, callback_done):
        super(UpdaterThread, self).__init__()
        self.callback_done = callback_done
        
    def run(self):
        result = check_version()
        if result != []:
            gobject.idle_add(self.callback_done, result)

class PresetUpdaterThread(Thread):
    def __init__ (self, callback_done, presets_dir):
        super(PresetUpdaterThread, self).__init__()
        self.callback_done = callback_done
        self.presets_dir = presets_dir
        
    def run(self):
        result = update_presets(self.presets_dir)
        if result != []:
            gobject.idle_add(self.callback_done, result)


class StatsThread(Thread):
    def __init__ (self, distribution, version):
        super(StatsThread, self).__init__()
        self.distribution = distribution
        self.version = version
        
    def run(self):
        params = urllib.urlencode({
            'distribution': self.distribution
            , 'version': self.version
        })
        f = urllib.urlopen("http://live.learnfree.eu/report-stats.php?%s" % params)

def copytree(src, dst, symlinks=False, ignore=None):
    names = os.listdir(src)
    if ignore is not None:
        ignored_names = ignore(src, names)
    else:
        ignored_names = set()

    if not os.path.isdir(dst): # This one line does the trick
        os.makedirs(dst)
    errors = []
    for name in names:
        if name in ignored_names:
            continue
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks, ignore)
            else:
                # Will raise a SpecialFileError for unsupported file types
                copy2(srcname, dstname)
        # catch the Error from the recursive copytree so that we can
        # continue with other files
        except Error, err:
            errors.extend(err.args[0])
        except EnvironmentError, why:
            errors.append((srcname, dstname, str(why)))
    try:
        copystat(src, dst)
    except OSError, why:
        if WindowsError is not None and isinstance(why, WindowsError):
            # Copying file access times may fail on Windows
            pass
        else:
            errors.extend((src, dst, str(why)))
    if errors:
        raise Error, errors
    

def tryint(s):
    try:
        return int(s)
    except:
        return s
    
def alphanum_key(s):
    """ Turn a string into a list of string and number chunks.
        "z23a" -> ["z", 23, "a"]
    """
    return [ tryint(c) for c in re.split('([0-9]+)', s) ]

def sort_nicely(l):
    """ Sort the given list in the way that humans expect.
    """
    l.sort(key=alphanum_key)

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')
        elif os.system('which sudo')==0:
            password = getText('Enter your password','Password:','Password')
            if password:
                os.popen('sudo -S ./live-usb-install.py','w').write(password)
        else:
            dialog = gtk.MessageDialog(
                None,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_ERROR,
                gtk.BUTTONS_OK,
                None
            )
            dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
            dialog.set_markup(_("You need to install sudo, gksu or kdesudo!"))
            response = dialog.run()
            dialog.destroy()
    else:
        app = appgui()
        gtk.main()



