Source

vlmaddon / app.py

Full commit
#!/usr/bin/env python

#    This file is part of the vectorlinux multimedia bonus disc.
#
#    This file is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License v2 as published by
#    the Free Software Foundation.
#
#    This file 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 file.  If not, see <http://www.gnu.org/licenses/>.


import gtk
import time
import threading
from utils import repository
from utils import vl
from view import widgets
from view import dialog
from view import message
import os
import tempfile as tmp

__author__ = 'Moises Henriquez'
__author_email__ = 'moc.liamg@xnl.E0M'[::-1]

def _(str):
    return str

def get_repo_path():
    basepath = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(basepath, 'data/repo/PACKAGES.TXT')

def make_slapt_config():
    """Generate a temporary file containing slapt-get rc stuff"""
    basepath = os.path.dirname(get_repo_path())
    rc = """
    WORKINGDIR=/var/cache/slapt-get \n
    EXCLUDE=kernel,kernel-ide,kernel-source,kernel-headers,kernel-modules,vl-hot\n
    SOURCE=file://%s\n"""%basepath
    
    f = tmp.NamedTemporaryFile()
    f.writelines([s.strip() + '\n' for s in rc.split('\n')])
    f.seek(0)
    return f

class Window(gtk.Window):
    """ Top-level window for the vectorlinux multimedia
    add-on"""
    def _get_menubar(self):
        mb = gtk.MenuBar()
        filemenu = gtk.Menu()
        filem = gtk.MenuItem('_%s'% _('File'))
        filem.set_submenu(filemenu)
        exit = gtk.MenuItem('_%s'% _('Exit'))
        exit.connect('activate', self.exit)
        filemenu.append(exit)

        mb.append(filem)

        return mb

    def __init__(self):
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        self.set_title(_('Vectorlinux Multimedia Bonus Disc'))
        self.connect('destroy', self.exit)
        self.set_position(gtk.WIN_POS_CENTER)

        body = gtk.VBox()
        menu = self._get_menubar()
        body.pack_start(menu, False, True, 0)
        banner = gtk.Label()
        banner.set_property('use-markup', True)
        banner.set_markup(
                '<span font_size="xx-large">%s</span>' 
                        % _('Vectorlinux Multimedia Bonus Disc'))
        body.pack_start(banner, False, True, 4)
        self.add(body)

        pane = gtk.HPaned()
        pane.set_position(150)
        body.pack_start(pane, True, True, 0)
        self.body = body

        # Create temporary slapt-getrc
        self.slaptgetrc = make_slapt_config()

        app_pool = repository.repository(get_repo_path())

        # Categories
        rpane = gtk.VBox()
        scrolled = gtk.ScrolledWindow()
        scrolled.set_policy(gtk.POLICY_AUTOMATIC,
                gtk.POLICY_AUTOMATIC)
        app_display = widgets.FancyAppList()
        self.display = app_display
        scrolled.add(app_display)
        rpane.pack_start(scrolled, True, True, 0)
        cache = vl.PackageCache()

        lpane = widgets.CategoryPanel(
                app_pool,
                cache,
                app_display)
        lpane.add_category(icon = 'data/icons/All-apps.png',
                label = _('All'), overlay = False)
        lpane.add_category(icon = 'data/icons/Audio.png',
                label = _('Audio'), overlay = False)
        lpane.add_category(icon = 'data/icons/Video.png',
                label = _('Video'), overlay = False)
        lpane.add_category(icon = 'data/icons/Graphics.png',
                label = _('Graphics'), overlay = False)
        lpane.add_category(icon = 'data/icons/Other.png',
                label = _('Bonus'), overlay = False)
        lpane.add_category(icon = 'data/icons/applications-other.png',
                label = _('Installed Only'),
                overlay = True)
        self.categoriespanel = lpane
        vpanel = gtk.VBox()
        vpanel.pack_start(lpane, True, True, 0)

        pane.pack1(vpanel)
        pane.pack2(rpane)
        self._catpanel = lpane
        bottombar = gtk.HBox()
        btSelectAll = gtk.Button(_('Select All'))
        btSelectAll.connect('clicked', self.selectall_event)
        img = gtk.Image()
        img.set_from_stock(gtk.STOCK_REFRESH,
                gtk.ICON_SIZE_BUTTON)
        btSelectAll.set_image(img)
        self.selbtn = btSelectAll
        bottombar.pack_start(btSelectAll, False, False, 2)
        rpane.pack_start(bottombar, False, False, 2)

        btInstallSelected = gtk.Button(_('Install Selected'))
        self.actionbtn = btInstallSelected
        self.actionbtn.connect('clicked', self.install_btn_event)
        img = gtk.Image()
        img.set_from_stock(gtk.STOCK_APPLY,
                gtk.ICON_SIZE_BUTTON)
        btInstallSelected.set_image(img)
        bottombar.pack_end(btInstallSelected, False, False, 2)

        self.statusbar = gtk.Statusbar()
        body.pack_start(self.statusbar, False, False, 0)

        self.resize(600, 400)
        self._stop_monitor = False
        self.monitor_thread = threading.Thread(
                target = self.monitor)

    def exit(self, caller):
        """ Exit procedure. Necessary because we cannot call
        gtk.main_quit directly when we have threads running
        in the background, so these must be killed first.
        """
        if self.slaptgetrc:
            self.slaptgetrc.close() # Delete the temporary slapt-getrc file
        self._stop_monitor = True
        time.sleep(0.25)
        gtk.main_quit()
        return

    def monitor(self):

        # Get the number of selected items
        i = 0
        rimg = gtk.Image()
        rimg.set_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_BUTTON)
        iimg = gtk.Image()
        iimg.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
        model = self.display.get_model()
        if self._stop_monitor is True:
           return
        while self._stop_monitor is False:
            time.sleep(0.25)
            try:

                i = len(self._do_get_selected_items())
            except:
                model = self.display.get_model()
                for item in model:
                    if item[0] is True:
                        i += 1
            if i > 0:
                if self._stop_monitor is True:
                    return
                gtk.gdk.threads_enter()
                self.statusbar.push(0, '%i %s'% (i,
                    _('items selected')))
                self.actionbtn.set_property('sensitive', True)
                gtk.gdk.threads_leave()
            else:
                if self._stop_monitor is True:
                    return
                gtk.gdk.threads_enter()
                self.statusbar.push(0, '%i %s'% (
                    len(model), _('items displayed')))
                self.actionbtn.set_property('sensitive', False)
                gtk.gdk.threads_leave()
            if self.categoriespanel._get_selected() == _('Installed Only'):
                gtk.gdk.threads_enter()
                self.actionbtn.set_property('label', _('Uninstall Selected'))
                self.actionbtn.set_image(rimg)
                gtk.gdk.threads_leave()
            else:
                gtk.gdk.threads_enter()
                self.actionbtn.set_property('label', _('Install Selected'))
                self.actionbtn.set_image(iimg)
                gtk.gdk.threads_leave()

    def selectall_event(self, widget):
        if widget.get_label() == _('Select All'):
            widget.set_property('label', _('Un-select All'))
            self._do_select('All')
        else:
            widget.set_property('label', _('Select All'))
            self._do_select(None)
            return
        return

    def _do_select(self, selection):
        model = self.display.get_model()
        if selection is None:
            for item in model:
                item[0] = False
                self.statusbar.push(0, '')
        else:
            for item in model:
                item[0] = True
                self.statusbar.push(0,
                        '%s items selected' % len(model))
        return

    def install_btn_event(self, widget):
        todo = self._do_get_selected_items()
        if self.categoriespanel._get_selected() == _('Installed Only'):
            #        if widget.get_label() in (_('Installed Only')):
            #           if _('Installed') in widget.get_label():
            dia = message.Error(parent = self,
                    text = _('Uninstall function not yet implemented'))
        else:
            dia = dialog.InstallWindow(
                    parent = self,
                    pkglist = todo,
                    slaptconfig = self.slaptgetrc)
        if dia.run():
            self.body.set_property('sensitive', False)
            dia.destroy()
#        gtk.gdk.threads_enter()
        self.body.set_property('sensitive', True)
        self.categoriespanel.cache = vl.PackageCache()
        self.categoriespanel.refresh_view()
        self.selbtn.set_property('label', _('Select All'))
#        gtk.gdk.threads_leave()

    def _do_get_selected_items(self):
        ret = []
        try:
            model = self.display.get_model()
        except:
            return ret
        for item in model:
            if item[0] is True:
                (app, desc) = item[1].split('\n')
                # Remove the formatting garbage from the string
                app = app.replace('<b>', '').replace('</b>','').strip()
                ret.append(app.strip())
        return ret



if __name__ == '__main__':
    gtk.gdk.threads_init()
    w = Window()
    w.show_all()
    w.monitor_thread.start()
    gtk.gdk.threads_enter()
    gtk.main()
    gtk.gdk.threads_leave()