root/trunk/src/KitInstaller.py @ 60

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