from shell.Plugin import Plugin
from main import USERHOME
from utils import dialog
from Package import Package
from Downloader import Downloader

import os
import tempfile
import thread
import gtk


#
# Installer for desklet packages.
#
class Installer_Package(Plugin):

    def init(self):
        self.__downloader = Downloader(self._get_path())

        menu = self._get_plugin("UI_Menu")
        menu.set_item("File/Slot", gtk.STOCK_OPEN, _("_Install package..."),
                      self.__on_file_open)



    #
    # Installs from the given URI.
    #
    def install_from(self, path):

        thread.start_new_thread(self.__install_file, (path,))


    def __on_file_open(self):

        def f(fsel, self):
            file = fsel.get_filename()
            fsel.destroy()
            self.install_from(file)

        dialog.fileselector("", f, None, self)


    #
    # Installs the given file.
    #
    def __install_file(self, url):

        if (url.startswith("/")):
            path = url
            is_local = True
        else:
            path = tempfile.mktemp()
            self.__downloader.download(url, path)
            is_local = False
            
        try:
            pkg = Package(path)
        except IOError:
            gtk.timeout_add(0, dialog.warning, _("Invalid package"),
                            _("The supplied file could not be opened as a "
                              "package. It is either corrupted or not of "
                              "the correct file type."),
                            False, True)
            return
            
        display_paths = self.__install_displays(pkg)
        control_paths = self.__install_controls(pkg)
        sensor_paths = pkg.find_sensors()
        pkg.close()
        if (not is_local): os.unlink(path)

        query = ""
        if (display_paths):
            query = "(MATCH 'path' '*/%s/*')" \
                    % (os.path.basename(display_paths[0]))

        if (not display_paths and not control_paths and not sensor_paths):
            gtk.timeout_add(0, dialog.info, _("Installation failed"),
                            _("The package could not be installed because "
                              "it contained no installable files."))
        else:
            gtk.timeout_add(0, dialog.info, _("Installation complete"),
                            "The package has been installed successfully.")

        collection = self._get_plugin("Core_DisplayCollection")
        displaybrowser = self._get_plugin("UI_DisplayBrowser")
        gtk.timeout_add(0, collection.reload)
        gtk.timeout_add(0, displaybrowser.set_location, query)



    #
    # Installs the displays from the given package.
    #
    def __install_displays(self, pkg):

        dirs = pkg.find_displays()
        for d in dirs:
            os.system("cp -r %s %s/" % (d, os.path.join(USERHOME, "Displays")))
        sensors = pkg.find_sensors()
        for s in sensors:
            os.system("python %s --nomsg" % (s))

        return dirs


    #
    # Installs the controls from the given package.
    #
    def __install_controls(self, pkg):

        import time
        name = str(time.time())
        dirs = pkg.find_controls()
        path = os.path.join(USERHOME, "Controls")
        if (not os.path.exists(path)): os.mkdir(path)
        for d in dirs:
            os.system("cp -r %s %s/"
                      % (d, os.path.join(path, name)))

        return dirs

    

def get_class(): return Installer_Package
