root/trunk/src/kitInstaller.py @ 77

Revision 77, 21.7 KB (checked in by pcabido, 5 years ago)
Line 
1# -*- coding: utf-8 -*-
2from repositoryhandler import repHandler
3
4import warnings
5warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
6
7import pygtk
8pygtk.require('2.0')
9import gtk
10import gtk.glade
11
12import os
13import sys
14import gobject
15import copy
16#import threading
17
18from util import util, aptutil, xmlutil
19from util import SearchWidget
20from PackageWorker import PackageWorker
21
22from gettext import textdomain, gettext as _
23
24__title__ = _("Kits Installer")
25__version__ = "0.0.1"
26__comments__ = _("GTK frontend for Kits Installer.")
27__authors__= ["Paulo Cabido <paulo.cabido@gmail.com>"]
28__copyright__ = "Paulo Cabido"
29__license__ = _("GNU GPL v3")
30
31#gtk.gdk.threads_init()
32
33class kitInstallerGTK:#(threading.Thread):
34   
35    def delete(self, widget, event, data=None):
36        """
37        Exits gtk.
38        """
39        gtk.main_quit()
40        return False
41   
42    def errorDialog(self, header, msg):
43         """
44         Shows a error message.
45         """
46
47         dialog = gtk.MessageDialog(parent=self.window,
48                               flags=gtk.DIALOG_MODAL,
49                               type=gtk.MESSAGE_ERROR,
50                               buttons=gtk.BUTTONS_CLOSE)
51         dialog.set_title("")
52         dialog.set_markup("<big><b>%s</b></big>\n\n%s" % (header, msg))
53         dialog.realize()
54         #dialog.window.set_functions(gtk.gdk.FUNC_MOVE)
55         dialog.run()
56         dialog.destroy()
57   
58    def sucessDialog(self, header, msg):
59        """
60        Shows a sucess/info message.
61        """
62
63        dialog = gtk.MessageDialog(parent=self.window,
64                               flags=gtk.DIALOG_MODAL,
65                               type=gtk.MESSAGE_INFO,
66                               buttons=gtk.BUTTONS_CLOSE)
67        dialog.set_title("")
68        dialog.set_markup("<big><b>%s</b></big>\n\n%s" % (header, msg))
69        dialog.realize()
70        #dialog.window.set_functions(gtk.gdk.FUNC_MOVE)
71        dialog.run()
72        dialog.destroy()
73   
74    def choiceDialog(self, header, msg):
75        """
76        Shows a choice dialog (yes/no) message.
77        """
78        dialog = gtk.MessageDialog(parent=self.window,
79                               flags=gtk.DIALOG_MODAL,
80                               type=gtk.MESSAGE_QUESTION,
81                               buttons=gtk.BUTTONS_YES_NO)
82        dialog.set_title("")
83        dialog.set_markup("<big><b>%s</b></big>\n\n%s" % (header, msg))
84        #cdialog.window.set_functions(gtk.gdk.FUNC_MOVE)
85        response = dialog.run()
86   
87        if response == gtk.RESPONSE_YES:
88            dialog.destroy()
89            return True
90        else:
91            dialog.destroy()
92            return False
93           
94       
95    #
96    # aboutdialog
97    #
98    def closeAbout(self, widget, data=None):
99        """
100        Closes the about dialog.
101        """
102        self.aboutDialog.hide()
103        return True
104   
105    def showAbout(self, widget, data=None):
106        """
107        Create the about dialog.
108        @param widget: Current widget
109        @type widget: gtk widget
110        """
111       
112        #self.aboutDialogIcon = gtk.gdk.pixbuf_new_from_file("pixmaps/kitsalinex.svg")
113        self.aboutDialog = self.wTree.get_widget("aboutdialogKitInstaller")
114        self.aboutDialog.set_name(__title__)
115        self.aboutDialog.set_version(__version__)
116        self.aboutDialog.set_comments(__comments__)
117        self.aboutDialog.set_copyright(__copyright__)
118        self.aboutDialog.set_authors(__authors__)
119        self.aboutDialog.set_license(__license__)
120        #self.aboutDialog.set_logo(self.aboutDialogIcon)
121       
122        self.aboutDialog.connect("destroy", self.closeAbout)
123        self.aboutDialog.connect("delete_event", self.closeAbout)
124        self.aboutDialog.connect("response", self.closeAbout)
125        self.aboutDialog.show()
126        return True
127   
128    #
129    #views
130    #
131    def rowCickedPackages(self, treeview):
132        """
133        Shows the kits info
134        """
135       
136        path = treeview.get_cursor()[0]
137        iter = treeview.get_model().get_iter(path)
138
139        (mark, name, version, sdesc) = treeview.get_model()[iter]
140        sdesc = aptutil.shortDescFromDic(self.packageList, name, version)
141        ldesc = aptutil.longDescFromDic(self.packageList, name, version).replace(".\n","\n")
142        self.textPackagesLDesc.get_buffer().set_text(sdesc + "\n" + ldesc )
143        return
144   
145    def rowSection(self, treeview):
146        """
147        Shows the kits that are in the selected (row) section
148        """
149       
150        path = treeview.get_cursor()[0]
151        if path:
152            model = treeview.get_model()
153            iter = treeview.get_model().get_iter(path)
154            section = model.get_value(iter,0)
155        else:
156            section = _("All packages")
157       
158        #mostrar apenas os pacotes da section caso nao seja o all
159        self.storePackages.clear()
160        if section != _("All packages"):
161            self.selectedSection = util.dicKey(self.parseSection.getSections(), section)
162        else:
163            self.selectedSection = "all"
164       
165        if self.selectedSection != "all" :
166            if self.setSearch:
167                self.sectionPackageList = aptutil.getSectionPackages(util.dicKey(self.parseSection.getSections(), section), self.searchPackageList)
168            else:
169                self.sectionPackageList = aptutil.getSectionPackages(util.dicKey(self.parseSection.getSections(), section), self.packageList)
170           
171            for pkg in self.sectionPackageList:
172                self.storePackages.append([pkg['Installed'], pkg['Package'], pkg['Version'], pkg['ShortDesc']])
173            self.treeviewPackages.set_model(self.storePackages)
174            self.treeviewPackages.set_search_column(1)
175        else:
176            if self.setSearch:
177                pkgList = self.searchPackageList
178            else:
179                pkgList = self.packageList
180               
181            for pkg in pkgList:
182                self.storePackages.append([pkg['Installed'], pkg['Package'], pkg['Version'], pkg['ShortDesc']])
183            self.treeviewPackages.set_model(self.storePackages)
184            self.treeviewPackages.set_search_column(1)
185        return
186   
187    def searchPackagesList(self, widget, query):
188        """
189        Searches the packages lists and sets the Treeviews with the results.
190        """
191       
192        if query:
193            self.searchPackageList = []
194            self.setSearch = True
195            for val in self.packageList:
196                if (query in val['Package']) or (query in val['Version']) or (query in val['ShortDesc']) \
197                or (query in val['LongDesc']) or (query in val['Maintainer']):
198                    self.searchPackageList.append(val)
199            self.rowSection(self.treeviewSections)   
200        else:
201            self.setSearch = False
202            self.rowSection(self.treeviewSections)
203           
204        return True
205         
206    def colToggledClicked( self, cell, path, model ):
207        """
208        Changes the toggle value in the treeview
209        """
210       
211        model[path][0] = not model[path][0]
212       
213        for pkg in self.packageList:
214            if pkg['Package'] == model[path][1] and pkg['Version'] == model[path][2]:
215                pkg['Installed'] = model[path][0]
216   
217    def setupPackagesView(self):
218        """
219        Defines the columns in the treeview
220        """
221       
222        self.rendererToggle = gtk.CellRendererToggle()
223        self.rendererToggle.set_property('activatable', True)
224        self.rendererToggle.connect('toggled', self.colToggledClicked, self.storePackages)
225       
226        self.colToggle = gtk.TreeViewColumn("", self.rendererToggle )
227        self.colToggle.add_attribute(self.rendererToggle, "active", 0)
228       
229        self.colPacote = gtk.TreeViewColumn(_("Kit"), self.rendererText, text=1)
230        self.colPacote.set_resizable(True)
231        self.colPacote.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
232        self.colPacote.set_fixed_width( 160 )
233        self.colPacote.set_sort_column_id(1)
234       
235        self.colVersion = gtk.TreeViewColumn(_("Version"), self.rendererText, text=2)
236        self.colVersion.set_resizable(True)
237        self.colVersion.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
238        self.colVersion.set_fixed_width( 150 )
239        #self.colVersion.set_sort_column_id(2)
240       
241        self.colDesc = gtk.TreeViewColumn(_("Description"), self.rendererText, text=3)
242        self.colDesc.set_resizable(True)
243        self.colDesc.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
244        self.colDesc.set_fixed_width( 350 )
245        #self.colDesc.set_sort_column_id(3)
246       
247        self.treeviewPackages.append_column(self.colToggle)
248        self.treeviewPackages.append_column(self.colPacote)
249        self.treeviewPackages.append_column(self.colVersion)
250        self.treeviewPackages.append_column(self.colDesc)
251        return
252       
253    def setupPackageList(self):
254        """
255        Builds the package list
256        """
257       
258        self.dialogProgress.realize()
259        self.dialogProgress.set_transient_for(self.window)
260        self.pbar.set_fraction(0)
261        self.dialogProgress.show()
262       
263        self.window.set_sensitive(False)
264        while gtk.events_pending():
265                    gtk.main_iteration()
266       
267        self.pbar.set_fraction(0.1)
268        while gtk.events_pending():
269                    gtk.main_iteration()
270                   
271        result = self.rep.update()
272       
273        if not result:
274            self.errorDialog(_("Error"),
275                             _("The package list download failed."))
276            return False
277       
278        self.pbar.set_fraction(0.5)
279        while gtk.events_pending():
280                    gtk.main_iteration()
281        result = self.rep.loadPackages()
282                   
283        if not result:
284            return False
285       
286        self.pbar.set_fraction(0.7)
287        while gtk.events_pending():
288                    gtk.main_iteration()
289                   
290        self.rep.checkInstalled()
291       
292        while gtk.events_pending():
293                    gtk.main_iteration()
294        self.pbar.set_fraction(0.8)
295        self.packageList = self.rep.getPackages()   
296        self.storePackages.clear() 
297        for pkg in self.packageList:
298            self.storePackages.append([pkg['Installed'], pkg['Package'], pkg['Version'], pkg['ShortDesc']])
299           
300                   
301        self.treeviewPackages.set_model(self.storePackages)
302        self.treeviewPackages.set_search_column(1)       
303       
304        while gtk.events_pending():
305                    gtk.main_iteration()
306        self.pbar.set_fraction(0.95)
307       
308        self.sections = self.rep.getSections()
309        self.storeSections.clear()
310        for stn in self.sections:
311            if stn == "all":
312                self.storeSections.append([_("All packages")])
313            else:
314                self.storeSections.append([self.parseSection.getSections()[stn]])
315           
316        self.treeviewSections.set_model(self.storeSections)
317        self.treeviewSections.set_search_column(0)
318
319        self.origPkgList = copy.deepcopy(self.packageList)
320           
321        #gtk.gdk.threads_leave()
322        #self.cpbar.close()
323        self.dialogProgress.hide()
324        self.window.set_sensitive(True)
325       
326        return True
327   
328    def updateRepository(self, widget, data=None):
329        """
330        Forces a repository update
331        """
332        self.rep.clean()
333        self.setupPackageList()
334       
335   
336    def doInstallRemove(self, widget, data=None):
337        """
338        Installs or removes the selected packages
339        """
340       
341        pkgs_add = []
342        pkgs_rm = []
343        cache = ""
344       
345        for pkg in self.packageList:
346            for opkg in self.origPkgList:
347                if pkg['Package'] == opkg['Package'] and pkg['Version'] == opkg['Version'] and pkg['Installed'] != opkg['Installed']:
348                    if pkg["Installed"]:
349                         pkgs_add.append(pkg['Package'])
350                    else:
351                        pkgs_rm.append(pkg['Package'])
352       
353        result = self.packageWorker.perform_action(self.window,
354                                                   cache,
355                                                   None,
356                                                   None,
357                                                   1)
358       
359        result = self.packageWorker.perform_action(self.window,
360                                                   cache,
361                                                   pkgs_add,
362                                                   pkgs_rm)
363       
364        erroInst = ""
365        for pkg in pkgs_add:
366            print aptutil.isInstalled(pkg, False)
367            if not aptutil.isInstalled(pkg, False):
368                if not erroInst:
369                    erroInst += pkg
370                else:
371                    erroInst += ", " + pkg
372                   
373                for val in self.packageList:
374                    if val['Package'] == pkg:
375                        val['Installed'] = False
376                        break
377                   
378                item = self.storePackages.get_iter_first()
379                while ( item != None ):
380                    if self.storePackages.get_value(item, 1,) == pkg:
381                        self.storePackages.set_value(item, 0, False)
382                        break
383                    item = self.storePackages.iter_next(item)
384            else:
385                for val in self.origPkgList:
386                    if val['Package'] == pkg:
387                        val['Installed'] = True
388                        break
389       
390       
391        erroRm = ""
392        for pkg in pkgs_rm:
393            if aptutil.isInstalled(pkg, False):
394                if not erroRm:
395                    erroRm += pkg
396                else:
397                    erroRm += ", " + pkg
398               
399                for val in self.packageList:
400                    if val['Package'] == pkg:
401                        val['Installed'] = True
402                        break
403                   
404                item = self.storePackages.get_iter_first()
405                while ( item != None ):
406                    if self.storePackages.get_value(item, 1,) == pkg:
407                        self.storePackages.set_value(item, 0, True)
408                        break
409                    item = self.storePackages.iter_next(item)
410            else:
411                for val in self.origPkgList:
412                    if val['Package'] == pkg:
413                        val['Installed'] = False
414                        break
415               
416               
417        if erroInst and erroRm:
418            self.errorDialog(_("Error"),
419                             (_("Error while installing the following kits <b>%s</b> and while removing <b>%s</b>.") % (erroInst, erroRm)))
420        elif erroInst:
421            self.errorDialog(_("Error"),
422                             _("Error while installing the following kits <b>%s</b>.") % erroInst)
423        elif erroRm:
424            self.errorDialog(_("Error"),
425                             _("Error while removing the following kits <b>%s</b>.") % erroRm)
426        else:
427            self.sucessDialog(_("Success"),
428                              _("All kits where installed/removed with success."))
429       
430        return True 
431       
432       
433    def openKit(self, widget, data=None):
434        pkgs_add = []
435        pkgs_rm = []
436        dialog = gtk.FileChooserDialog(_("Open Kit"),
437                               None,
438                               gtk.FILE_CHOOSER_ACTION_OPEN,
439                               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
440                                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
441       
442        dialog.set_default_response(gtk.RESPONSE_OK)
443       
444        filter = gtk.FileFilter()
445        filter.set_name("Kits")
446        filter.add_pattern("*.deb")
447        dialog.add_filter(filter)
448       
449        response = dialog.run()
450        kitType = ""
451        if response == gtk.RESPONSE_OK:
452            kitFile = dialog.get_filename()
453            tmpKitFile = os.path.splitext(kitFile)
454           
455            if tmpKitFile[1] != "":
456                if tmpKitFile[1] == ".deb":
457                    kitType = "deb"
458                else:
459                    print "error"
460        else:
461            dialog.destroy()
462            return
463       
464        dialog.destroy()
465       
466        filename = (tmpKitFile[0] +  tmpKitFile[1])
467       
468        if aptutil.isInstalled(filename):
469            if aptutil.upgradable(filename):
470                upgrade = self.choiceDialog(_("Update Kit"),
471                                            _("<b>%s</b> is already installed, but this version is newer.\nDo you wish to update?")
472                                            % aptutil.pkgInfo(filename, "Package"))
473               
474                if upgrade:
475                    result = aptutil.install(filename)
476               
477                    if result:
478                        self.sucessDialog(_("Update Kit"),
479                                          _("<b>%s</b> was successfully updated.") % aptutil.pkgInfo(filename, "Package"))
480                        return True
481                    else:
482                        self.errorDialog(_("Error"),
483                                         _("Error while updating <b>%s</b>.") % aptutil.pkgInfo(filename, "Package"))
484                        return False
485            else:
486                self.sucessDialog(_("Update Kit"),
487                                  _("The <b>%s</b> Kit is already updated.") % aptutil.pkgInfo(filename, "Package"))
488                return True
489        else:
490            install = self.choiceDialog(_("Install Kit"),
491                                        _("Do you wish to install <b>%s</b>?") % aptutil.pkgInfo(filename, "Package"))
492            if install:
493                result = aptutil.install(filename)
494                if result:
495                    self.sucessDialog(_("Kit installed"),
496                                      _("Kit <b>%s</b> was installed with success.") % aptutil.pkgInfo(filename, "Package"))
497                    return True
498                else:
499                    self.errorDialog(_("Error"),
500                                     _("Error while installing <b>%s</b>.") % aptutil.pkgInfo(filename, "Package"))
501                    return False
502    #
503    # __init__
504    #
505   
506    def __init__(self):
507        self.localPath = os.path.realpath(os.path.dirname(sys.argv[0]))
508       
509        self.tmpDir = "/tmp/kitsalinex/sourcelist"
510        self.localDir = os.getenv('HOME')
511        self.sourcelist = self.localPath + "/data/sources.list"
512       
513        self.packageList = []
514       
515        self.sectionPackageList = []
516        self.sectionsFile = self.localPath + "/data/sections.xml"
517        self.parseSection = xmlutil.parseSection(self.sectionsFile)
518        self.parseSection.run()
519       
520        self.sections = []
521        self.selectedSection = "all"
522       
523        self.setSearch = False
524        self.searchPackageList = []
525       
526        self.rep = repHandler.rephandle(self.sourcelist, self.tmpDir)
527       
528        self.gladefile = self.localPath + "/data/kitInstaller.glade"
529        self.wTree = gtk.glade.XML(self.gladefile)
530       
531        self.notebook = self.wTree.get_widget("notebook")
532       
533        self.quitMenu = self.wTree.get_widget("quitMenu")
534        self.aboutMenu = self.wTree.get_widget("aboutMenu")
535        self.openMenu = self.wTree.get_widget("openMenu")
536        self.updateRepMenu = self.wTree.get_widget("updateRepMenu")
537       
538        self.buttonAplicar = self.wTree.get_widget("buttonAplicar")
539       
540        self.vboxSearch = self.wTree.get_widget("vboxSearch")
541        self.entrySearchbox = SearchWidget.SearchEntry(gtk.icon_theme_get_default())
542        self.vboxSearch.add(self.entrySearchbox)
543        self.entrySearchbox.connect("terms-changed", self.searchPackagesList)
544        self.entrySearchbox.show()
545       
546        self.treeviewSections = self.wTree.get_widget("treeviewSection")
547        self.treeviewPackages = self.wTree.get_widget("treeviewPackages")
548        self.textPackagesLDesc = self.wTree.get_widget("textPackagesLDesc")
549       
550        self.storeSections = gtk.ListStore(str)
551        self.storePackages = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str, str)
552       
553        #renderer's
554        self.rendererText = gtk.CellRendererText()
555       
556        #sections
557        self.colSection = gtk.TreeViewColumn(_("Section"), self.rendererText, text=0)
558        self.colSection.set_resizable(True)
559        self.colSection.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
560        self.colSection.set_fixed_width( 210 )
561        self.treeviewSections.append_column(self.colSection)
562       
563        #package lists
564        self.setupPackagesView()
565       
566        #Progress dialog   
567        self.dialogProgress = self.wTree.get_widget("dialogProgress")
568        self.pbar = self.wTree.get_widget("pbarCache")
569       
570        self.window = self.wTree.get_widget("window_installkits")
571        if (self.window):
572            self.window.set_title(__title__)
573            self.window.connect("destroy", gtk.main_quit)
574            self.window.connect("delete_event", self.delete)
575           
576            self.buttonAplicar.connect('clicked', self.doInstallRemove, None)
577               
578            #menubar
579            self.quitMenu.connect('activate', gtk.main_quit)
580            self.aboutMenu.connect('activate', self.showAbout)
581            self.openMenu.connect('activate', self.openKit)
582            self.updateRepMenu.connect('activate', self.updateRepository)
583           
584            self.treeviewPackages.connect("cursor-changed", self.rowCickedPackages)
585            self.treeviewSections.connect("cursor-changed", self.rowSection)
586           
587            self.setupPackageList()
588            self.packageWorker = PackageWorker()
589           
590           
591def main():
592    hwg = kitInstallerGTK()
593    gtk.main()
594    return 0
595
596#if __name__ == "__main__":
597#    hwg = KitInstallerGTK()
598#    main()
599   
Note: See TracBrowser for help on using the browser.