root/trunk/src/CreateKit.py @ 34

Revision 34, 18.7 KB (checked in by pcabido, 5 years ago)
  • Property svn:executable set to *
Line 
1# -*- coding: utf-8 -*-
2from metapackagehandler import mtpkgHandler
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 threading
16import sexy
17
18import apt
19import apt_pkg
20
21from util import util
22from util import aptutil
23from util import SearchWidget
24
25__title__ = "Criador de Kits"
26__version__ = "0.0.1"
27__authors__= ["Paulo Cabido <paulo.cabido@gmail.com>"]
28
29gtk.gdk.threads_init()
30
31#controla o dialog da progressbar
32class ProgressBar():
33    def __init__(self, dialogName, pbobj):
34        self._progressbar = pbobj
35        self._dialog = dialogName
36   
37    def progressbarTimeout(self, pbobj):
38        pbobj.pulse()
39        return True
40   
41    def start(self):
42        self._dialog.show()
43       
44    def active(self):
45        self._timer = gobject.timeout_add(100, self.progressbarTimeout, self._progressbar)
46   
47    def stop(self):
48        gobject.source_remove(self._timer)
49        self._timer = 0
50        self._dialog.hide()     
51
52#main function
53class CreateKitGTK(threading.Thread):
54   
55    def delete(self, widget, event, data=None):
56        """
57        Exits gtk.
58        """
59        gtk.main_quit()
60        return False
61   
62    def loadImage(self, image, path):
63        """
64        Sets a image.
65        """
66        try:
67            image.set_from_file(path)
68            return True
69        except:
70            pass
71            return False
72   
73    def errorDialog(self, header, msg):
74         """
75         Show an error message.
76         """
77
78         d = gtk.MessageDialog(parent=self.window,
79                               flags=gtk.DIALOG_MODAL,
80                               type=gtk.MESSAGE_ERROR,
81                               buttons=gtk.BUTTONS_CLOSE)
82         d.set_title("")
83         d.set_markup("<big><b>%s</b></big>\n\n%s" % (header, msg))
84         d.realize()
85         d.window.set_functions(gtk.gdk.FUNC_MOVE)
86         d.run()
87         d.destroy()
88   
89    #
90    # Package list
91    #       
92    def setupPackageList(self, ignore=True):
93        """
94        Creates the package list from the current system cache.
95        """
96        gtk.gdk.threads_enter()
97        self.window.set_sensitive(False)
98        self.cpbar.active()
99
100        self.pkgCache = aptutil.getCachePackages()       
101       
102        self.pkgCache.sort()
103        self.pkgCache = util.removeDuplicates(self.pkgCache)
104       
105        for elm in self.pkgCache:
106            self.listStore.append(elm)
107       
108        self.rendererText = gtk.CellRendererText()
109       
110        self.rendererToggle = gtk.CellRendererToggle()
111        self.rendererToggle.set_property('activatable', True)
112        self.rendererToggle.connect('toggled', self.colToggledClicked, self.listStore)
113       
114        self.colToggle = gtk.TreeViewColumn("", self.rendererToggle )
115        self.colToggle.add_attribute( self.rendererToggle, "active", 0)
116       
117        self.treeview.append_column(self.colToggle)
118       
119        colPacote = gtk.TreeViewColumn("Pacote", self.rendererText, text=1)
120        colPacote.set_resizable(True)
121        colPacote.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
122        colPacote.set_fixed_width( 125 )
123        #colPacote.set_sort_column_id(1)
124       
125        colVersion = gtk.TreeViewColumn("Versão", self.rendererText, text=2)
126        colVersion.set_resizable(True)
127        colVersion.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
128        colVersion.set_fixed_width( 125 )
129        #colVersion.set_sort_column_id(2)
130       
131        colDesc = gtk.TreeViewColumn("Descrição", self.rendererText, text=3)
132        colDesc.set_resizable(True)
133        colDesc.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
134        colDesc.set_fixed_width( 350 )
135        #colDesc.set_sort_column_id(3)
136       
137        self.treeview.append_column(colPacote)
138        self.treeview.append_column(colVersion)
139        self.treeview.append_column(colDesc)
140       
141        self.treeview.set_model(self.listStore)
142        self.treeview.set_search_column(1)
143       
144        gtk.gdk.threads_leave()
145        self.stopthread.set()
146       
147        self.stopthread.set()
148        self.cpbar.stop()
149        self.window.set_sensitive(True)
150        return True
151       
152    def colToggledClicked( self, cell, path, model ):
153        """
154        Sets the toggled state on the toggle button to true or false.
155        """
156
157        if self.setListStoreSearch:
158                model = self.listStoreSearch
159         
160        model[path][0] = not model[path][0]
161        if model[path][0]:
162            #add version here
163            self.packageList[model[path][1]] = model[path][2]
164   
165            util.changePackageListValue(self.pkgCache, 1, model[path][1], 2, model[path][2], 0, model[path][0])
166        else:
167            del self.packageList[model[path][1]]
168            util.changePackageListValue(self.pkgCache, 1, model[path][1], 2, model[path][2], 0, model[path][0])
169           
170        return
171   
172    def searchPackageList(self, widget, query):
173        """
174        Searches the packages list and sets the Treeview with the results.
175        """
176        self.listStoreSearch = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str, str)
177       
178        if query:
179            for elm in self.pkgCache:
180                if (query in elm[1]) or (query in elm[2]) or (query in elm[3]):
181                    self.listStoreSearch.append(elm)
182                   
183            self.treeview.set_model(self.listStoreSearch)
184            self.treeview.set_search_column(1)
185            self.setListStoreSearch = True
186        else:
187            self.listStore.clear()
188            for elm in self.pkgCache:
189                if (query in elm[1]) or (query in elm[2]) or (query in elm[3]):
190                    self.listStore.append(elm)
191                   
192            self.treeview.set_model(self.listStore)
193            self.treeview.set_search_column(1)
194            self.setListStoreSearch = False
195           
196        return True
197   
198    #
199    # aboutdialog
200    #
201    def closeAbout(self, widget, data=None):
202        """
203        Closes the about dialog.
204        """
205        self.aboutDialog.hide()
206        return True
207   
208    def showAbout(self, widget, data=None):
209        """
210        Create the about dialog.
211        @param widget: Current widget
212        @type widget: gtk widget
213        """
214       
215        #self.aboutDialogIcon = gtk.gdk.pixbuf_new_from_file("pixmaps/kitsalinex.svg")
216        self.aboutDialog = self.wTree.get_widget("aboutdialogCriarkits")
217        self.aboutDialog.set_name(__title__)
218        self.aboutDialog.set_version(__version__)
219        #self.aboutDialog.set_comments("GTK frontend para Criar Kits.")
220        #self.aboutDialog.set_copyright("Copyright (C) Paulo Cabido 2008")
221        self.aboutDialog.set_authors(__authors__)
222        #self.aboutDialog.set_logo(self.aboutDialogIcon)
223       
224        self.aboutDialog.connect("destroy", self.closeAbout)
225        self.aboutDialog.connect("delete_event", self.closeAbout)
226        self.aboutDialog.connect("response", self.closeAbout)
227        self.aboutDialog.show()
228        return True
229   
230    #
231    #funcoes relacionadas com os metapacotes
232    #
233    def newMetapackage(self, widget, data=None):
234        pass
235   
236    def generateMetapackage(self, widget, data=None):
237        tmpDirRoot = "/tmp/kitsalinex"
238        tmpDir = "/tmp/kitsalinex/metapackage"
239       
240        self._filename = self.entryFilename.get_text()
241        if not self._filename:
242            self.errorDialog("Nome do Ficheiro", "É necessário definir o nome do ficheiro.")
243            self.entryFilename.grab_focus()
244            return False
245        else:
246            self._filename.replace(' ','-')
247       
248        self._path = self.buttonPath.get_filename()
249        if not self._path:
250            self.errorDialog("Localização", "É necessário definir um local onde salvar o Kit.")
251            self.buttonPath.grab_focus()
252            return False
253        else:
254            self._path.replace(' ','\ ')
255       
256        self._name = self.entryName.get_text()
257        if not self._name:
258            self.errorDialog("Nome do Kit", "É necessário definir o nome do Kit.")
259            self.notebook.set_current_page(0)
260            self.entryName.grab_focus()
261            return False
262        elif util.iligalChars(self._name):
263            self.errorDialog("Nome do Kit", "O nome do Kit tem caracteres ilegais.")
264            self.notebook.set_current_page(0)
265            self.entryName.grab_focus()
266            return False
267        else:
268            self._name.replace(' ','-')
269       
270        self._priority = self.cmbPriority.get_active_text()
271        if not self._priority:
272            self.errorDialog("Prioridade", "A Prioridade tem que estar definida.")
273            self.notebook.set_current_page(0)
274            self.cmbPriority.grab_focus()
275            return False
276       
277        self._section = aptutil.setSection(self.cmbSection.get_active_text())
278        if not self._section:
279            self.errorDialog("Secção", "A Secção tem que estar definida.")
280            self.notebook.set_current_page(0)
281            self.cmbSection.grab_focus()
282            return False
283       
284        self._version = self.entryVersion.get_text()
285        if not self._version:
286            self.errorDialog("Versão", "A Versão tem que estar definida.")
287            self.notebook.set_current_page(0)
288            self.entryVersion.grab_focus()
289            return False
290        elif util.iligalChars(self._version):
291            self.errorDialog("Versão", "A versão tem caracteres ilegais.")
292            self.notebook.set_current_page(0)
293            self.entryVersion.grab_focus()
294            return False
295       
296        self._arch = self.cmbArch.get_active_text()
297        if not self._arch:
298            self.errorDialog("Arquitectura", "A Arquitectura do Kit tem que estar definida.")
299            self.notebook.set_current_page(0)
300            self.cmbArch.grab_focus()
301            return False
302       
303        self._maintainer = self.entryMaintainer.get_text()
304        if not self._maintainer:
305            self.errorDialog("Maintainer", "O Maintainer do Kit tem que estar definido.")
306            self.notebook.set_current_page(0)
307            self.entryMaintainer.grab_focus()
308            return False
309        elif util.iligalChars(self._maintainer, [':']):
310            self.errorDialog("Maintainer", "O Maintainer do Kit tem caracteres ilegais.")
311            self.notebook.set_current_page(0)
312            self.entryMaintainer.grab_focus()
313            return False
314           
315        start = self.textviewLDesc.get_buffer().get_start_iter()
316        end = self.textviewLDesc.get_buffer().get_end_iter()
317        sdesc = self.entrySDesc.get_text()
318        ldesc = self.textviewLDesc.get_buffer().get_text(start,end, True)
319        if not sdesc:
320            self.errorDialog("Descrição Curta", "A Descrição Curta do Kit tem que estar definida.")
321            self.notebook.set_current_page(1)
322            self.entrySDesc.grab_focus()
323            return False
324        elif util.iligalChars(sdesc, [':']):
325            self.errorDialog("Descrição Curta", "A Descrição Curta do Kit tem caracteres ilegais.")
326            self.notebook.set_current_page(1)
327            self.entrySDesc.grab_focus()
328            return False
329       
330        if not ldesc:
331            self.errorDialog("Descrição Longa", "A Descrição Longa do Kit tem que estar definida.")
332            self.notebook.set_current_page(1)
333            self.textviewLDesc.grab_focus()
334            return False
335        elif util.iligalChars(ldesc, [':']):
336            self.errorDialog("Descrição Longa", "A Descrição Longa do Kit tem caracteres ilegais.")
337            self.notebook.set_current_page(1)
338            self.textviewLDesc.grab_focus()
339            return False
340        #esta tudo ok com as desc's
341        self._desc = aptutil.setDescription(sdesc, ldesc)
342       
343        self._depends = aptutil.getDependsFromDic(self.packageList)
344        if not self._depends:
345            self.errorDialog("Pacotes", "Pelo menos um pacote tem que ser escolhido.")
346            self.notebook.set_current_page(2)
347            return False
348       
349        start = self.textPostinst.get_buffer().get_start_iter()
350        end = self.textPostinst.get_buffer().get_end_iter()
351        self._postinst = self.textPostinst.get_buffer().get_text(start,end, True)
352       
353        mtpkg = mtpkgHandler.metapackage('/' + self._filename,
354                                         self._path,
355                                         self._name,
356                                         self._priority,
357                                         self._section,
358                                         self._version,
359                                         self._arch,
360                                         self._maintainer,
361                                         "",
362                                         "",
363                                         self._desc,
364                                         self._depends,
365                                         self._postinst)
366       
367        result = mtpkg.createBaseFiles(tmpDir)
368        if result == 0:
369            self.errorDialog("Criar Kit", "Ocorreu um erro durante a criação do Kit.")
370            return False
371       
372        result = mtpkg.generateMetapackage(tmpDirRoot, tmpDir)
373        if result == 0:
374            self.errorDialog("Criar Kit", "Ocorreu um erro durante a criação do Kit.")
375            return False
376       
377        return True
378       
379       
380    #
381    # __init__
382    #
383    def __init__(self):
384        #gtk.gdk.threads_init()
385        self.stopthread = threading.Event()
386
387        self.gladefile = "CreateKit.glade"
388        self.wTree = gtk.glade.XML(self.gladefile)
389       
390        #menu
391        self.aboutMenu = self.wTree.get_widget("aboutMenu")
392        self.quitMenu = self.wTree.get_widget("quitMenu")
393       
394        #botoes do notebook
395        self.buttonNext = self.wTree.get_widget("buttonNext")
396        self.buttonNext2 = self.wTree.get_widget("buttonNext2")
397        self.buttonNext3 = self.wTree.get_widget("buttonNext3")
398        self.buttonNext4 = self.wTree.get_widget("buttonNext4")
399        self.buttonBack = self.wTree.get_widget("buttonBack")
400        self.buttonBack2 = self.wTree.get_widget("buttonBack2")
401        self.buttonBack3 = self.wTree.get_widget("buttonBack3")
402        self.buttonBack4 = self.wTree.get_widget("buttonBack4")
403       
404        self.notebook = self.wTree.get_widget("notebook")
405        self.imageDadosGerais = self.wTree.get_widget("imageDadosGerais")
406        self.imageDesc = self.wTree.get_widget("imageDesc")
407        self.imagePackages = self.wTree.get_widget("imagePackages")
408        self.imagePostInst = self.wTree.get_widget("imagePostInst")
409        self.imageGenerate = self.wTree.get_widget("imageGenerate")
410       
411        self.treeview = self.wTree.get_widget("treeviewPackages")
412        self.listStore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str, str)
413        self.packageList = {}
414        self.setListStoreSearch = False
415       
416        #entry's (textboxes)
417        self.entryName = self.wTree.get_widget("entryName")
418        self.entryMaintainer = self.wTree.get_widget("entryMaintainer")
419        self.entryVersion = self.wTree.get_widget("entryVersion")
420       
421        #combo boxes
422        self.cmbArch = self.wTree.get_widget("cmbArch")
423        self.cmbSection = self.wTree.get_widget("cmbSection")
424        self.cmbPriority = self.wTree.get_widget("cmbPriority")
425       
426        #desc
427        self.entrySDesc = self.wTree.get_widget("entrySDesc")
428        self.textviewLDesc = self.wTree.get_widget("textviewLDesc")
429       
430        #postinst
431        self.textPostinst = self.wTree.get_widget("textPostinst")
432       
433        self.entryFilename = self.wTree.get_widget("entryFilename")
434        self.buttonPath = self.wTree.get_widget("buttonPath")
435        self.buttonGenerateKit = self.wTree.get_widget("buttonGenerateKit")
436       
437        #Progress dialog   
438        self.window_progress = self.wTree.get_widget("window_progress")
439        self.dialogProgress = self.wTree.get_widget("dialogProgress")
440        self.pbar = self.wTree.get_widget("pbarCache")
441       
442        self.window = self.wTree.get_widget("window_criarkit")
443        if (self.window):
444            self.window.set_title(__title__)
445            self.window.connect("destroy", gtk.main_quit)
446            self.window.connect("delete_event", self.delete)
447           
448            #self.buttonQuit.connect("clicked", gtk.main_quit)
449             
450            #define as imagens dos tabs
451            self.loadImage(self.imageDadosGerais, "icons/package_development.png")
452            self.loadImage(self.imageDesc, "icons/emblem-documents.png")
453            self.loadImage(self.imagePackages, "icons/file-roller.png")
454            self.loadImage(self.imagePostInst, "icons/emblem-package.png")
455            self.loadImage(self.imageGenerate, "icons/application-x-deb.png")
456           
457            #init progress dialog
458            self.cpbar = ProgressBar(self.dialogProgress, self.pbar)
459            self.cpbar.start()
460           
461            #searchbox
462            self.hboxSearch = self.wTree.get_widget("hboxSearch")
463            self.entrySearchbox = SearchWidget.SearchEntry(gtk.icon_theme_get_default())
464            self.hboxSearch.add(self.entrySearchbox)
465            self.entrySearchbox.connect("terms-changed", self.searchPackageList)
466            self.entrySearchbox.show()
467           
468            #notebook navigation
469            self.buttonNext.connect("clicked", lambda w: self.notebook.next_page())
470            self.buttonNext2.connect("clicked", lambda w: self.notebook.next_page())
471            self.buttonNext3.connect("clicked", lambda w: self.notebook.next_page())
472            self.buttonNext4.connect("clicked", lambda w: self.notebook.next_page())
473            self.buttonBack.connect("clicked", lambda w: self.notebook.prev_page())
474            self.buttonBack2.connect("clicked", lambda w: self.notebook.prev_page())
475            self.buttonBack3.connect("clicked", lambda w: self.notebook.prev_page())
476            self.buttonBack4.connect("clicked", lambda w: self.notebook.prev_page())
477            #o glade poe o expand False, e preciso mudar manualmente
478            for n in range(self.notebook.get_n_pages()):
479                self.notebook.set_tab_label_packing(self.notebook.get_nth_page(n), True, True, gtk.PACK_START)
480               
481            #menubar
482            self.quitMenu.connect('activate', gtk.main_quit)
483            self.aboutMenu.connect('activate', self.showAbout)
484           
485            #other buttons
486            self.buttonGenerateKit.connect('clicked', self.generateMetapackage)
487           
488            #inicia a thread para obter os pacotes da cache e coloca-los na treeview
489            threading.Thread(name="self.setupPackageList", target=self.setupPackageList).start()
490           
491def main():
492    gtk.main()
493    return 0
494
495if __name__ == "__main__":
496    hwg = CreateKitGTK()
497    main()
Note: See TracBrowser for help on using the browser.