#!/usr/bin/env python
# vim:et:sta:sts=4:sw=4:ts=8:tw=79:

import gtk
import os
import sys
import subprocess
import errno
import hashlib
import threading
import gzip
import urllib2
import urlgrabber
import urlgrabber.progress as urlp
from simpleconfig import SimpleConfig

# Internationalization
import locale
import gettext
locale.setlocale(locale.LC_ALL, '')
locale.bindtextdomain("salix-codecs-installer", "/usr/share/locale")
gettext.bindtextdomain("salix-codecs-installer", "/usr/share/locale")
gettext.textdomain("salix-codecs-installer")
_ = gettext.gettext

# Initializing the gtk's thread engine
gtk.gdk.threads_init()

spkg = '/sbin/spkg'

canceltask = False


def threaded(f):
    def wrapper(*args):
        t = threading.Thread(target=f, args=args)
        t.start()
    return wrapper


class DownloadMeter(urlp.BaseMeter):

    def __init__(self, fo=sys.stderr):
        urlp.BaseMeter.__init__(self)
        self.fo = fo

    def _do_update(self, amount_read, now=None):
        if not canceltask:
            rate = urlp.format_number(self.re.average_rate())
            frac = self.re.fraction_read()
            app.progressbar_repo.set_fraction(frac)
            app.label_repo_rate.set_text(
                _('Download rate:') + ' ' + rate + 'B/s')
        else:
            raise KeyboardInterrupt


class SalixCodecsInstaller:
    c = SimpleConfig('/etc/slapt-get/slapt-getrc')
    working_dir = c.get('WORKINGDIR')
    sources = c.get_all('SOURCE')

    def __get_head(self, url):
        u = urllib2.urlopen(url)
        head = u.headers['last-modified']
        return 'Last-Modified: ' + head

    def __local_head(self, working_dir, url):
        fname = self.__mangled_url(url)
        try:
            f = open(working_dir + '/' + fname + '.head')
            return f.read().replace('\n', '')
        except IOError:
            return None

    def __store_head(self, working_dir, filename, head):
        f = open(working_dir + '/' + filename, 'w')
        f.write(head)
        f.close()

    def __mangled_url(self, url):
        mangled = '.' + url.replace('/', '#')
        return mangled

    def __unmangled_url(self, repo):
        working_dir = self.working_dir
        if not working_dir.endswith('/'):
            working_dir = working_dir + '/'
        unmangled = repo.replace('#', '/').partition(working_dir + '.')[2]
        return unmangled

    def create_dir(self, dir):
        try:
            os.makedirs(dir)
        except OSError as exc:
            if exc.errno == errno.EEXIST:
                pass
            else:
                raise

    def download_repofile(self, working_dir, url):
        new = self.__get_head(url)
        local = self.__local_head(working_dir, url)
        murl = self.__mangled_url(url)
        if new == local:
            # file is already there
            self.progressbar_repo.set_fraction(1)
        else:
            urlgrabber.urlgrab(url, filename=working_dir +
                               '/' + murl, progress_obj=meter)
            self.__store_head(working_dir, murl + '.head', new)

    def get_sources(self):
        sources = []
        for i in self.sources:
            if i.rstrip(' ').upper().endswith(':DEFAULT'):
                priority = 0
                url = i.rpartition(':')[0]
            elif i.rstrip(' ').upper().endswith(':OFFICIAL'):
                priority = 2
                url = i.rpartition(':')[0]
            elif i.rstrip(' ').upper().endswith(':PREFERRED'):
                priority = 4
                url = i.rpartition(':')[0]
            elif i.rstrip(' ').upper().endswith(':CUSTOM'):
                priority = 6
                url = i.rpartition(':')[0]
            else:
                priority = 0
                url = i
            sources.append([url, priority])
        return sources

    def url_exists(self, url):
        try:
            u = urllib2.urlopen(url)
            return True
        except urllib2.HTTPError, urllib2.URLError:
            return False

    def verify_checksum(self, working_dir, file):
        cmd = 'gpg --verify ' + working_dir + '/' + \
            file + '.asc ' + working_dir + '/' + file
        retval = subprocess.call(cmd, shell=True)
        if retval == 0:
            # successful verification
            return True
        elif retval == 2:
            # no gpg key found
            return True
        elif retval == 512:
            # no gpg key found (different error code?)
            return True
        else:
            return False

    def write_package_data_file(self, pkgtxt_file, mirror, priority,
                                checksums_list):
        working_dir = self.working_dir
        f = open(working_dir + '/package_data', 'a')
        has_mirror_line = False
        is_extra = False
        pkgname = ''
        for line in pkgtxt_file:
            if line.startswith('PACKAGE NAME'):
                pkgname = line.partition('PACKAGE NAME:')[2].strip()
                has_mirror_line = False
                is_extra = False
                f.write(line)
            elif line.startswith('PACKAGE MIRROR'):
                has_mirror_line = True
                if line.rpartition('\n')[0].rstrip('/').endswith('extra'):
                    is_extra = True
                f.write(line)
            elif line.startswith('PACKAGE LOCATION'):
                if not has_mirror_line:
                    f.write('PACKAGE MIRROR:  ' + mirror + '\n')
                f.write('PACKAGE PRIORITY:  ' + str(priority) + '\n')
                if is_extra:
                    location = './' + \
                        line.partition('PACKAGE LOCATION:')[2].lstrip(
                            ' ').partition('/extra/')[2]
                    f.write('PACKAGE LOCATION:  ' + location)
                else:
                    f.write(line)
            elif line.startswith('PACKAGE SUGGESTS'):
                f.write(line)
                for sum in checksums_list:
                    if sum[1] == pkgname:
                        f.write('PACKAGE MD5SUM:  ' + sum[0] + '\n')
                        break
            else:
                f.write(line)
        f.close()

    def create_package_data(self, repos):
        working_dir = self.working_dir
        # Make sure the package_data file is empty
        f = open(working_dir + '/package_data', 'w')
        f.close()
        for i in repos:
            pkgtxtpath = i[0]
            priority = i[1]
            patchespath = i[2]
            checksumspath = i[3]
            # Read all checksums in a list
            checksums_list = []
            if checksumspath.endswith('.gz'):
                f = gzip.open(checksumspath, 'rb')
                checksums_file = f.readlines()
                f.close()
            else:
                f = open(checksumspath)
                checksums_file = f.readlines()
            for line in checksums_file:
                line = line.rpartition('\n')[0]
                checksum = line.partition('  ')[0]
                pkgname = line.partition('  ')[2].rpartition('/')[2]
                checksums_list.append([checksum, pkgname])
            mirror = self.__unmangled_url(pkgtxtpath).rpartition('/')[0] + '/'
            # Read PACKAGES.TXT files and add the info to the package_data file
            if pkgtxtpath.endswith('.gz'):
                f = gzip.open(pkgtxtpath, 'rb')
                pkgtxt_file = f.readlines()
                f.close()
            else:
                f = open(pkgtxtpath)
                pkgtxt_file = f.readlines()
                f.close(i)
            self.write_package_data_file(
                pkgtxt_file, mirror, priority, checksums_list)
            # Read PACKAGES.TXT from patches dir
            if patchespath is not None:
                if patchespath.endswith('.gz'):
                    f = gzip.open(patchespath, 'rb')
                    pkgtxt_file = f.readlines()
                    f.close()
                else:
                    f = open(patchespath)
                    pkgtxt_file = f.readlines()
                    f.close(i)
                self.write_package_data_file(
                    pkgtxt_file, mirror, priority + 1, checksums_list)
        self.progressbar_repo_total.set_fraction(1)
        self.label_repo_desc.set_text(_('Reading package lists...'))

    def download_repo_info(self):
        global canceltask
        sources = self.get_sources()
        working_dir = self.working_dir
        allrepos = []
        # There are 6 different files to (try to) download for every
        # repo + one final step for reading the package lists into the
        # package_data file
        steps = len(sources) * 6.0 + 1
        step = 0

        for repo in sources:
            if not canceltask:
                repo_files = []
                self.label_repo_rate.set_text('')
                repo_url = repo[0]
                if not repo_url.endswith('/'):
                    repo_url = repo_url + '/'
                repo_priority = repo[1]
                self.label_repo_name.set_text(repo_url)
                # Retrieve package data
                if self.url_exists(repo_url + 'PACKAGES.TXT.gz'):
                    url = repo_url + 'PACKAGES.TXT.gz'
                elif self.url_exists(repo_url + 'PACKAGES.TXT'):
                    url = repo_url + 'PACKAGES.TXT'
                else:
                    self.dialog_update.hide()
                    self.messagedialog_sources_error.show()
                self.label_repo_desc.set_text(_('Retrieving package data...'))
                self.download_repofile(working_dir, url)
                fullpath = working_dir + '/' + self.__mangled_url(url)
                repo_files.append(fullpath)
                repo_files.append(repo_priority)
                step += 1
                self.progressbar_repo_total.set_fraction(step / steps)
                self.progressbar_repo.set_fraction(1)
            if not canceltask:
                # Retrieve patch list
                patches = False
                if self.url_exists(repo_url + 'patches/PACKAGES.TXT.gz'):
                    url = repo_url + 'patches/PACKAGES.TXT.gz'
                    patches = True
                elif self.url_exists(repo_url + 'patches/PACKAGES.TXT'):
                    url = repo_url + 'patches/PACKAGES.TXT'
                    patches = True
                if patches:
                    self.label_repo_desc.set_text(
                        _('Retrieving patch list...'))
                    self.download_repofile(working_dir, url)
                    fullpath = working_dir + '/' + self.__mangled_url(url)
                    repo_files.append(fullpath)
                    self.progressbar_repo.set_fraction(1)
                else:
                    repo_files.append(None)
                step += 1
                self.progressbar_repo_total.set_fraction(step / steps)
            if not canceltask:
                # Retrieve checksum list
                if self.url_exists(repo_url + 'CHECKSUMS.md5.gz'):
                    url = repo_url + 'CHECKSUMS.md5.gz'
                elif self.url_exists(repo_url + 'CHECKSUMS.md5'):
                    url = repo_url + 'CHECKSUMS.md5'
                else:
                    self.dialog_update.hide()
                    self.messagedialog_sources_error.show()
                self.label_repo_desc.set_text(_('Retrieving checksum list...'))
                self.download_repofile(working_dir, url)
                fullpath = working_dir + '/' + self.__mangled_url(url)
                repo_files.append(fullpath)
                step += 1
                self.progressbar_repo_total.set_fraction(step / steps)
                self.progressbar_repo.set_fraction(1)
            if not canceltask:
                # Retrieve checksum signature
                checksumsig = False
                if self.url_exists(repo_url + 'CHECKSUMS.md5.gz.asc'):
                    url = repo_url + 'CHECKSUMS.md5.gz.asc'
                    checksumsig = True
                elif self.url_exists(repo_url + 'CHECKSUMS.md5.asc'):
                    url = repo_url + 'CHECKSUMS.md5.asc'
                    checksumsig = True
                if checksumsig:
                    self.label_repo_desc.set_text(
                        _('Retrieving checksum signature...'))
                    self.download_repofile(working_dir, url)
                    self.progressbar_repo.set_fraction(1)
                step += 1
                self.progressbar_repo_total.set_fraction(step / steps)
            if not canceltask:
                # Verify checksum
                if checksumsig:
                    checksum = self.__mangled_url(url.rpartition('.asc')[0])
                    self.label_repo_desc.set_text(
                        _('Verifying checksum signature...'))
                    if not self.verify_checksum(working_dir, checksum):
                        self.dialog_update.hide()
                        self.messagedialog_repo_checksum.show()
                step += 1
                self.progressbar_repo_total.set_fraction(step / steps)
            if not canceltask:
                # Retrieve ChangeLog.txt
                if self.url_exists(repo_url + 'ChangeLog.txt'):
                    url = repo_url + 'ChangeLog.txt'
                    self.label_repo_desc.set_text(
                        _('Retrieving ChangeLog.txt...'))
                    self.download_repofile(working_dir, url)
                    self.progressbar_repo.set_fraction(1)
                step += 1
            if not canceltask:
                self.progressbar_repo_total.set_fraction(step / steps)
                allrepos.append(repo_files)
        return allrepos

    def pkg_deps_and_sugs(self, pkgname):
        cmd = ['LANG=C /usr/sbin/slapt-get --show ' + pkgname +
               '|grep "^Package Required:\|^Package Suggests:"']
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
        output = process.communicate()[0]
        pkgs = []
        for line in output.split('\n'):
            if line.startswith('Package'):
                for i in line.rpartition('Package Required:')[2]\
                                        .rpartition('Package Suggests:')[2]\
                                        .lstrip(' ').rstrip(' ')\
                                        .replace(' ', ',')\
                                        .replace('|', ' ').split(','):
                    if i is not '':
                        pkgs.append(i)
        return pkgs

    def pkglist(self):
        pkgs = ['gstreamer', 'gst-plugins-base', 'gst-plugins-good',
                'gst-plugins-bad', 'gst-plugins-ugly', 'gst-python',
                'gst0-python', 'gst-ffmpeg',
                'gstreamer0', 'gst-plugins-base0', 'gst-plugins-good0',
                'gst-plugins-bad0', 'gst-plugins-ugly0', 'gst-libav',
                'libdvdcss', 'flash-plugin']
        deps = []
        for pkg in pkgs:
            for i in self.pkg_deps_and_sugs(pkg):
                deps.append(i)
        for i in pkgs:
            deps.append(i)
        return set(deps)

    def pkg_uris(self, pkglist):
        pkgstr = ' '.join(pkglist)
        cmd = ['/usr/sbin/slapt-get --print-uris -s -i ' +
               pkgstr + '|grep "^http:\|^ftp:\|^file:"']
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
        output = process.communicate()[0].split()
        return output

    def pkg_detailed_list(self, uris):
        working_dir = self.working_dir
        f = open(working_dir + '/package_data')
        package_data = f.readlines()
        f.close()
        uri_list = []
        for i in uris:
            pkgname = i.rpartition('/')[2]
            uri_list.append([pkgname, i])
        pkgfilename = ''
        pkgname = ''
        pkgver = ''
        pkgname_match = False
        location = ''
        location_found = False
        md5sum = ''
        md5sum_found = False
        description = ''
        description_found = False
        detailed_list = []
        for line in package_data:
            if line.startswith('PACKAGE NAME'):
                pkgfilename = line.partition('PACKAGE NAME:')[2].strip()
                for i in uri_list:
                    if pkgfilename == i[0]:
                        pkgname = pkgfilename.rpartition(
                            '-')[0].rpartition('-')[0].rpartition('-')[0]
                        pkgver = pkgfilename.partition(
                            pkgname)[2].lstrip('-').rpartition('.')[0]
                        uri = i[1]
                        pkgname_match = True
                        location_found = False
            elif line.startswith('PACKAGE LOCATION'):
                location = line.partition('PACKAGE LOCATION:')[2].strip()
                location_found = True
            elif line.startswith('PACKAGE MD5SUM'):
                md5sum = line.partition('PACKAGE MD5SUM:')[2].strip()
                md5sum_found = True
            elif line.startswith(pkgname + ':'):
                if description_found is False:
                    description = line.partition(
                        pkgname + ': ')[2].rstrip('\n')
                    description_found = True
            if pkgname_match and location_found and md5sum_found and \
                    description_found:
                detailed_list.append([pkgname, pkgver, pkgfilename, uri,
                                      location, md5sum, description])
                pkgname = ''
                pkgver = ''
                pkgname_match = False
                location = ''
                location_found = False
                md5sum = ''
                md5sum_found = False
                description = ''
                description_found = False
        return sorted(detailed_list)

    @threaded
    def on_button_infowindow_yes_clicked(self, widget):
        try:
            gtk.gdk.threads_enter()
            self.infowindow.hide()
            self.dialog_update.show()
            self.dialog_update.set_title(_('Updating local package cache'))
            gtk.gdk.threads_leave()
            repos = self.download_repo_info()
            self.create_package_data(repos)
            pkglist = self.pkglist()
            uris = self.pkg_uris(pkglist)
            to_be_installed = self.pkg_detailed_list(uris)
            if len(to_be_installed) == 0:
                gtk.gdk.threads_enter()
                self.dialog_update.hide()
                self.messagedialog_nopkgs.show()
                gtk.gdk.threads_leave()
            else:
                gtk.gdk.threads_enter()
                self.dialog_update.hide()
                self.dialog_pkglist.show()
                gtk.gdk.threads_leave()
                for i in to_be_installed:
                    # Passing checkbox state (True), changed state (False),
                    # pkgname, pkgver, pkgfilename,
                    # uri, location, md5sum, descrption
                    self.liststore_pkglist.append(
                        [True, False,
                         i[0], i[1], i[2], i[3], i[4], i[5], i[6]])
        except KeyboardInterrupt:
            self.dialog_update.hide()
        except IOError:
            self.dialog_update.hide()
            self.messagedialog_dir_error.show()

    def on_button_infowindow_no_clicked(self, widget):
        gtk.main_quit()

    @threaded
    def on_button_update_cancel_clicked(self, widget):
        global canceltask
        canceltask = True
        gtk.gdk.threads_enter()
        self.dialog_update.hide()
        gtk.main_quit()
        gtk.gdk.threads_leave()

    @threaded
    def on_dialog_update_delete_event(self, widget, event):
        global canceltask
        canceltask = True
        gtk.gdk.threads_enter()
        self.dialog_update.hide()
        gtk.main_quit()
        gtk.gdk.threads_leave()

    def md5sum_check(self, filename, md5sum):
        md5 = hashlib.md5()
        f = open(filename, 'rb')
        while True:
            data = f.read(8192)
            if not data:
                break
            md5.update(data)
        f.close()
        local_md5 = md5.hexdigest()
        if local_md5 == md5sum:
            return True
        else:
            return False

    @threaded
    def on_button_dlg_pkglist_exec_clicked(self, widget):
        try:
            working_dir = self.working_dir
            gtk.gdk.threads_enter()
            self.dialog_pkglist.hide()
            self.dialog_update.show()
            self.progressbar_repo_total.set_fraction(0)
            self.progressbar_repo.set_fraction(0)
            self.dialog_update.set_title(_('Downloading packages'))
            gtk.gdk.threads_leave()
            steps = 0
            step = 0.0
            # count how many packages are to be downloaded/installed
            for i in self.liststore_pkglist:
                enabled = i[0]
                if enabled:
                    steps += 1
            # *2 because we download the md5sum too
            steps = steps * 2
            # download packages
            for i in self.liststore_pkglist:
                if not canceltask:
                    enabled = i[0]
                    pkgname = i[2]
                    pkgver = i[3]
                    pkgfilename = i[4]
                    uri = i[5]
                    location = i[6]
                    md5sum = i[7]
                    pkgdesc = i[8]
                    if enabled:
                        destdir = working_dir + '/' + location
                        dest = destdir + '/' + pkgfilename
                        self.create_dir(destdir)
                        if os.path.isfile(dest):
                            if self.md5sum_check(dest, md5sum):
                                download = False
                            else:
                                download = True
                        else:
                            download = True
                        gtk.gdk.threads_enter()
                        self.label_repo_desc.set_text(pkgfilename)
                        self.label_repo_name.set_text(pkgdesc)
                        self.progressbar_repo_total.set_fraction(step / steps)
                        self.progressbar_repo.set_fraction(0)
                        gtk.gdk.threads_leave()
                        if download:
                            urlgrabber.urlgrab(
                                uri, filename=dest, progress_obj=meter)
                            if not self.md5sum_check(dest, md5sum):
                                # FIXME
                                # check if this actually works right
                                # I'll need to make a temp repo with a bad pkg
                                # md5sum
                                gtk.gdk.threads_enter()
                                self.dialog_update.hide()
                                self.messagedialog_pkg_checksum.show()
                                gtk.gdk.threads_leave()
                        step += 1
            gtk.gdk.threads_enter()
            self.progressbar_repo_total.set_fraction(1)
            # install packages
            self.progressbar_repo_total.set_fraction(0)
            self.progressbar_repo.hide()
            self.dialog_update.set_title(_('Installing packages'))
            gtk.gdk.threads_leave()
            success = True
            for i in self.liststore_pkglist:
                if not canceltask:
                    enabled = i[0]
                    pkgname = i[2]
                    pkgver = i[3]
                    pkgfilename = i[4]
                    location = i[6]
                    pkgdesc = i[8]
                    if enabled:
                        gtk.gdk.threads_enter()
                        self.label_repo_desc.set_text(pkgfilename)
                        self.label_repo_name.set_text(pkgdesc)
                        self.progressbar_repo_total.set_fraction(step / steps)
                        gtk.gdk.threads_leave()
                        pkg = working_dir + '/' + location + '/' + pkgfilename
                        retval = subprocess.call(
                            [spkg, '-u', '--install-new', pkg])
                        if retval is not 0:
                            success = False
                            gtk.gdk.threads_enter()
                            self.dialog_update.hide()
                            self.messagedialog_pkginstall_error.show()
                            gtk.gdk.threads_leave()
                            break
                    step += 1
            if success:
                self.dialog_update.hide()
                self.messagedialog_uninstall.show()
            else:
                # FIXME
                # check if this actually pops up as it's supposed to, after
                # a package has been downloaded succesfully, but spkg can't
                # install it for some reason
                self.dialog_update.hide()
                self.messagedialog_pkginstall_error.show()
        except KeyboardInterrupt:
            self.dialog_update.hide()
        except OSError:
            self.dialog_update.hide()
            self.messagedialog_dir_error.show()
        except IOError:
            self.dialog_update.hide()
            self.messagedialog_dir_error.show()

    def on_button_dlg_pkglist_cancel_clicked(self, widget):
        gtk.main_quit()

    def on_dialog_pkglist_delete_event(self, widget, event):
        gtk.main_quit()

    def on_checkbox_toggled(self, widget, data=None):
        selectedpkg = self.treeview_pkglist.get_selection()
        self.liststore_pkglist, iter = selectedpkg.get_selected()
        selectedpkgname = self.liststore_pkglist.get_value(iter, 2)
        for i in self.liststore_pkglist:
            if i[2] == selectedpkgname:
                i[1] = True
                if i[0] == True:
                    i[0] = False
                else:
                    i[0] = True

    @threaded
    def on_button_uninstall_clicked(self, widget):
        gtk.gdk.threads_enter()
        self.messagedialog_uninstall.hide()
        gtk.gdk.threads_leave()
        cmd = ['/sbin/spkg', '-d', 'salix-codecs-installer']
        process = subprocess.Popen(cmd)
        process.wait()
        gtk.main_quit()

    def on_messagedialog_delete_event(self, widget, event):
        gtk.main_quit()

    def on_messagedialog_response(self, widget, event):
        gtk.main_quit()

    def on_messagedialog_dir_error_response(self, widget, event):
        gtk.main_quit()

    def gtk_main_quit(self, widget, data=None):
        gtk.main_quit()

    def __init__(self):
        builder = gtk.Builder()
        builder.set_translation_domain("salix-codecs-installer")
        if os.path.exists('salix-codecs-installer.ui'):
            builder.add_from_file('salix-codecs-installer.ui')
        elif os.path.exists('/usr/share/salix-codecs-installer/salix-codecs-installer.ui'):
            builder.add_from_file('/usr/share/salix-codecs-installer/salix-codecs-installer.ui')
        self.window = builder.get_object('salix-codecs-installer')

        #
        # Info window
        #
        self.infowindow = builder.get_object('infowindow')
        self.button_infowindow_yes = builder.get_object(
            'button_infowindow_yes')
        self.button_infowindow_no = builder.get_object('button_infowindow_no')
        self.button_infowindow_yes.set_flags(gtk.CAN_DEFAULT)
        self.infowindow.set_default(self.button_infowindow_yes)

        #
        # Update package cache dialog
        #
        self.dialog_update = builder.get_object('dialog_update')
        self.button_update_cancel = builder.get_object('button_update_cancel')
        self.progressbar_repo_total = builder.get_object(
            'progressbar_repo_total')
        self.progressbar_repo = builder.get_object('progressbar_repo')
        self.label_repo_rate = builder.get_object('label_repo_rate')
        self.label_repo_desc = builder.get_object('label_repo_desc')
        self.label_repo_name = builder.get_object('label_repo_name')

        # Error dialogs
        self.messagedialog_sources_error = builder.get_object(
            'messagedialog_sources_error')
        self.messagedialog_pkginstall_error = builder.get_object(
            'messagedialog_pkginstall_error')
        self.messagedialog_dir_error = builder.get_object(
            'messagedialog_dir_error')
        self.messagedialog_repo_checksum = builder.get_object(
            'messagedialog_repo_checksum')
        self.messagedialog_pkg_checksum = builder.get_object(
            'messagedialog_pkg_checksum')

        #
        # Package list dialog
        #
        self.dialog_pkglist = builder.get_object('dialog_pkglist')
        self.treeview_pkglist = builder.get_object('treeview_pkglist')
        self.liststore_pkglist = builder.get_object('liststore_pkglist')
        self.button_dlg_pkglist_exec = builder.get_object(
            'button_dlg_pkglist_cancel')
        self.button_dlg_pkglist_cancel = builder.get_object(
            'button_dlg_pkglist_cancel')
        self.button_dlg_pkglist_exec.set_flags(gtk.CAN_DEFAULT)
        self.treeviewcolumn_checkbox = builder.get_object(
            'treeviewcolumn_checkbox')
        self.treeviewcolumn_checkbox.set_title(_('Install'))
        self.treeviewcolumn_pkgname = builder.get_object(
            'treeviewcolumn_pkgname')
        self.treeviewcolumn_pkgname.set_title(_('Name'))
        self.treeviewcolumn_pkgver = builder.get_object(
            'treeviewcolumn_pkgver')
        self.treeviewcolumn_pkgver.set_title(_('Version'))
        self.treeviewcolumn_pkgdesc = builder.get_object(
            'treeviewcolumn_pkgdesc')
        self.treeviewcolumn_pkgdesc.set_title(_('Description'))

        #
        # Remove package dialog
        #
        self.messagedialog_uninstall = builder.get_object(
            'messagedialog_uninstall')

        #
        # All packages are already installed dialog
        #
        self.messagedialog_nopkgs = builder.get_object('messagedialog_nopkgs')

        builder.connect_signals(self)

        self.create_dir(self.working_dir)


if __name__ == "__main__":
    app = SalixCodecsInstaller()
    meter = DownloadMeter()
    app.infowindow.show()
    gtk.main()
