source: lliurex-remote-installer/trunk/fuentes/lliurex-remote-installer-gui.install/usr/share/lliurex-remote-installer/AptBox.py @ 4625

Last change on this file since 4625 was 4625, checked in by daduve, 2 years ago

Only show mirror APT if exists in server

File size: 14.6 KB
Line 
1import gi
2gi.require_version('Gtk', '3.0')
3from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio, GObject,GLib
4
5import copy
6import gettext
7import Core
8
9import Dialog
10import time
11import threading
12import sys
13import subprocess
14from pprint import pprint
15
16
17gettext.textdomain('lliurex-remote-installer-gui')
18_=gettext.gettext
19
20
21RSRC="./"
22
23
24class AptBox(Gtk.VBox):
25       
26        def __init__(self):
27               
28                Gtk.VBox.__init__(self)
29               
30                self.core=Core.Core.get_core()
31               
32                builder=Gtk.Builder()
33                builder.set_translation_domain('lliurex-remote-installer-gui')
34                ui_path=RSRC + "lliurex-remote-installer.ui"
35
36                builder.add_from_file(ui_path)
37                self.main_box=builder.get_object("section_box")
38                self.list_box=builder.get_object("list_box")
39                self.package_list_box=builder.get_object("package_list_box")
40                self.package_list_vp=builder.get_object("package_list_viewport")
41                self.add_package_button=builder.get_object("add_package_button")
42                self.delete_apt_button=builder.get_object("delete_button")
43                self.add_apt_button=builder.get_object("add_button")
44                self.apply_button=builder.get_object("apply_button")
45                self.url_entry=builder.get_object("url_entry")
46                self.data_box=builder.get_object("apt_data_box")
47                self.data_vp=builder.get_object("apt_data_viewport")
48                self.package_label=builder.get_object("package_label")
49                self.url_label=builder.get_object("url_label")
50                self.new_package_window=builder.get_object("new_package_window")
51                self.new_apt_window=builder.get_object("new_apt_window")
52                self.cancel_apt_button=builder.get_object("cancel_apt_button")
53                self.accept_apt_button=builder.get_object("accept_apt_button")
54                self.cancel_add_package_button=builder.get_object("cancel_add_package_button")
55                self.accept_add_package_button=builder.get_object("accept_add_package_button")
56                self.apt_name_entry=builder.get_object("apt_name_entry")
57                self.apt_url_entry=builder.get_object("apt_url_entry")
58                self.apt_msg_label=builder.get_object("apt_msg_label")
59                self.package_msg_label=builder.get_object("package_msg_label")
60                self.apply_changes_button=builder.get_object("apply_changes_button")
61                self.package_list_entry=builder.get_object("package_list_entry")
62               
63               
64                self.stack=Gtk.Stack()
65                self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
66                self.stack.set_transition_duration(250)
67                hbox=Gtk.HBox()
68                hbox.show()
69                self.stack.add_titled(hbox,"empty","Empty Box")
70                self.stack.add_titled(self.data_box,"apt_data","Apt Data Box")
71                self.data_vp.add(self.stack)
72               
73                self.pack_start(self.main_box,True,True,0)
74               
75               
76                self.connect_signals()
77                self.set_css_info()
78               
79                self.core.current_var=None
80                self.current_id=None
81               
82                self.thread=threading.Thread()
83                self.thread_ret=None
84               
85               
86               
87        #def __init__
88       
89
90        def set_css_info(self):
91               
92                self.style_provider=Gtk.CssProvider()
93                f=Gio.File.new_for_path("lliurex-remote-installer.css")
94                self.style_provider.load_from_file(f)
95                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
96                self.package_label.set_name("OPTION_LABEL")
97                self.url_label.set_name("OPTION_LABEL")
98               
99                       
100        #def set-css_info
101       
102       
103        def connect_signals(self):
104               
105                self.add_apt_button.connect("clicked",self.add_apt_button_clicked)
106                self.delete_apt_button.connect("clicked",self.delete_apt_button_clicked)
107                self.add_package_button.connect("clicked",self.add_package_clicked)
108               
109                self.accept_add_package_button.connect("clicked",self.accept_add_package_button_clicked)
110                self.cancel_add_package_button.connect("clicked",self.cancel_add_package_button_clicked)
111               
112                self.accept_apt_button.connect("clicked",self.accept_apt_button_clicked)
113                self.cancel_apt_button.connect("clicked",self.cancel_apt_button_clicked)
114               
115                self.apply_changes_button.connect("clicked",self.apply_changes_button_clicked)
116                self.url_entry.connect("changed",self.url_entry_changed)
117               
118                self.new_package_window.connect("delete_event",self.hide_window)
119                self.new_apt_window.connect("delete_event",self.hide_window)
120               
121        #def connect_signals
122       
123       
124        def hide_window(self,widget,event):
125               
126                widget.hide()
127                return True
128               
129        #def new_package_window
130
131
132        def check_changes(self,widget=True,event=True,manage_dialog=False):
133               
134               
135                if not manage_dialog:
136                        if self.core.current_var==None:
137                                return False
138                        return self.core.current_var != self.core.var
139               
140               
141                if self.core.current_var!=None and self.core.current_var != self.core.var:
142                        if not self.changes_detected_dialog(False):
143                                return True
144               
145                sys.exit(0)
146                       
147
148        #def check_changes
149               
150       
151        def set_info(self,info):
152               
153                #Empty list
154                for x in self.list_box.get_children():
155                        self.list_box.remove(x)
156               
157                self.core.var=info
158               
159                times=1
160               
161                for t in range(0,times):
162                        if self.core.var["apt"] not in [{},"",None,'{}']:
163                                for x in self.core.var["apt"]:
164                                        #Only show Mirror if exist in server
165                                        if x in ['Mirror']:
166                                                exists=self.core.n4d.lliurex_mirror()
167                                                exists=exists[1]
168                                                print exists
169                                                if exists.strip() == 'True':
170                                                        self.new_apt_button(x)
171                                        else:
172                                                self.new_apt_button(x)
173                       
174                self.core.current_var=copy.deepcopy(self.core.var)
175                self.list_box.show_all()
176               
177
178        #def set_info
179       
180
181        def new_apt_button(self,source_name):
182               
183                new_source_name=source_name
184               
185                if len(source_name) > 8:
186                       
187                        new_source_name=source_name[0:7]+"..."
188               
189                b=Gtk.Button(new_source_name)
190                b.connect("clicked",self.apt_clicked,source_name)
191                b.set_size_request(100,100)
192                b.set_halign(Gtk.Align.START)
193                b.set_name("OPTION_BUTTON")
194                b.show_all()
195                self.list_box.pack_start(b,False,False,5)
196                b.queue_draw()
197                b.set_tooltip_text(source_name)
198               
199                return b
200               
201        #def new_apt_button
202
203       
204        def new_package_button(self,pkg_name):
205               
206                hbox=Gtk.HBox()
207                label=Gtk.Label(pkg_name)
208                b=Gtk.Button()
209                i=Gtk.Image.new_from_file("trash.svg")
210                b.add(i)
211                b.set_halign(Gtk.Align.CENTER)
212                b.set_valign(Gtk.Align.CENTER)
213                b.set_name("DELETE_ITEM_BUTTON")
214                b.connect("clicked",self.delete_package_clicked,hbox)
215                hbox.pack_start(label,False,False,0)
216                hbox.pack_end(b,False,False,10)
217                hbox.show_all()
218                label.set_margin_right(20)
219                label.set_margin_left(20)
220                label.set_margin_top(20)
221                label.set_margin_bottom(20)
222                hbox.set_name("PKG_BOX")
223                self.package_list_box.pack_start(hbox,False,False,5)
224                self.package_list_box.queue_draw()
225                hbox.queue_draw()
226               
227        #def new_package_button
228       
229       
230        # ## APT ### ################################################
231       
232        def apt_clicked(self,widget,apt_id,ignore_changes=False):
233               
234               
235                if not ignore_changes:
236                       
237                        if self.core.current_var!=None:
238                                if self.check_changes():
239                                        if not self.changes_detected_dialog(False):
240                                                return
241                       
242                        if apt_id !=self.current_id:
243                                self.core.current_var=copy.deepcopy(self.core.var)
244                               
245                self.current_id=apt_id
246               
247                self.stack.set_visible_child_name("apt_data")
248
249                for b in self.list_box.get_children():
250                        b.set_name("OPTION_BUTTON")
251                       
252                widget.set_name("SELECTED_OPTION_BUTTON")
253                       
254               
255                for x in self.package_list_box.get_children():
256                        self.package_list_box.remove(x)
257                       
258                self.url_entry.set_text(self.core.current_var["apt"][apt_id]["url"])
259                       
260                for x in self.core.current_var["apt"][apt_id]["packages"]:
261                        self.new_package_button("%s"%x)
262                               
263                               
264                self.package_list_box.show_all()
265               
266                if not ignore_changes:
267               
268                        for apt in self.list_box:
269                                if apt.get_tooltip_text() not in self.core.current_var["apt"]:
270                                        self.list_box.remove(apt)
271                       
272               
273               
274                #self.core.lri.main_window.connect("delete_event",self.check_changes,True)
275               
276               
277        #def apt_clicked
278       
279        def add_apt_button_clicked(self,widget):
280               
281                self.apt_name_entry.set_text("")
282                self.apt_url_entry.set_text("")
283                self.apt_msg_label.set_text("")
284                self.new_apt_window.show()
285               
286        #def add_button_clicked
287       
288       
289        def delete_apt_button_clicked(self,widget):
290               
291                if self.current_id==None:
292                        return
293                       
294                if self.current_id in ['LliureX', 'Mirror']:
295                        return
296               
297                if self.delete_apt_dialog(self.current_id):
298                        for apt_button in self.list_box.get_children():
299                               
300                                if apt_button.get_tooltip_text() == self.current_id:
301                                        self.list_box.remove(apt_button)
302                                        self.stack.set_visible_child_name("empty")
303                                        self.core.var["apt"].pop(self.current_id)
304                                        self.current_id=None
305                                        self.core.current_var=None
306                                        self.core.n4d.set_variable(self.core.var)
307               
308        #def add_button_clicked
309       
310        def accept_apt_button_clicked(self,widget):
311               
312               
313                name=self.apt_name_entry.get_text()
314                source=self.apt_url_entry.get_text()
315               
316                if len(name) < 1 or len(source) < 8:
317                        self.apt_msg_label.set_markup("<span foreground='red'>"+"Invalid values"+"</span>")
318                        return
319                if name in self.core.var["apt"]:
320                        self.apt_msg_label.set_markup("<span foreground='red'>"+"Apt name already exists"+"</span>")
321                        return
322               
323                if len(name) > 0 and len(source)>0 and name not in self.core.var:
324                        name=(name.lower())
325                        b=self.new_apt_button(name)
326                       
327                        if self.core.current_var ==None:
328                                self.core.current_var=copy.deepcopy(self.core.var)
329                               
330                        self.core.current_var["apt"][name]={}
331                        self.core.current_var["apt"][name]["packages"]=[]
332                        self.core.current_var["apt"][name]["url"]=source
333                        self.new_apt_window.hide()
334                       
335                        self.core.var=copy.deepcopy(self.core.current_var)
336                        self.core.n4d.set_variable(self.core.var)
337                       
338                        self.apt_clicked(b,name,True)
339                       
340
341               
342        #def accept_apt_button_clicked
343       
344       
345        def cancel_apt_button_clicked(self,widget):
346               
347                self.new_apt_window.hide()
348               
349        #def cancel_apt_button_clicked
350       
351        # #################################################### #####
352       
353       
354       
355        # #### PACKAGE CHANGES ################### #
356       
357       
358        def add_package_clicked(self,widget):
359               
360                self.package_list_entry.set_text("")
361                self.new_package_window.show()
362               
363        #def add_package_clicked
364       
365       
366        def delete_package_clicked(self,button,hbox):
367               
368                pkg=hbox.get_children()[0].get_text()
369               
370                if self.delete_package_dialog(pkg):
371               
372                        self.package_list_box.remove(hbox)
373                               
374                        for p in range(len(self.core.current_var["apt"][self.current_id]["packages"])-1,-1,-1):
375                                if self.core.current_var["apt"][self.current_id]["packages"][p]==pkg:
376                                        self.core.current_var["apt"][self.current_id]["packages"].pop(p)
377                                        self.core.var=self.core.current_var
378                                        self.core.n4d.set_variable(self.core.var)
379                                       
380                        # STORE VALUE IN N4D HERE IF NEEDED
381                       
382                        # ######### #
383       
384        #def delete_package_clicked
385       
386       
387        def url_entry_changed(self,widget):
388               
389                if self.current_id in ['LliureX', 'Mirror']:
390                        return
391               
392                if self.core.current_var !=None:
393                        txt=widget.get_text()
394                        if len(txt)>6:
395                                self.core.current_var["apt"][self.current_id]["url"]=txt
396
397        #def url_entry_changed 
398       
399       
400        def accept_add_package_button_clicked(self,widget):
401               
402               
403                self.package_list_entry.grab_focus()
404                txt=self.package_list_entry.get_text()
405               
406                for pkg in txt.split(","):
407                       
408                        pkg=pkg.strip(" ")
409                        if pkg not in self.core.current_var["apt"][self.current_id]["packages"]:
410                                self.core.current_var["apt"][self.current_id]["packages"].append(pkg)
411                        self.new_package_button(pkg)
412                       
413                self.new_package_window.hide()
414               
415        #def accept_add_package_button_clicked
416       
417       
418        def cancel_add_package_button_clicked(self,widget):
419               
420                self.new_package_window.hide()
421               
422        #def cancel_add_package_button_clicked
423       
424       
425        def apply_changes_button_clicked(self,widget):
426               
427                self.thread=threading.Thread(target=self.apply_changes_thread)
428                self.thread.daemon=True
429                self.thread.start()
430               
431                main_window=self.core.lri.main_window
432                dialog=Dialog.ApplyingChangesDialog(main_window,"Lliurex Remote installer",_(u"Updating repositories and testing packages..."))
433                dialog.show()
434                GLib.timeout_add(500,self.check_apply_thread,dialog)
435               
436        #def apply_changes_button_clicked
437       
438       
439        def apply_changes_thread(self):
440               
441                try:
442                        self.core.dprint("Updating repositories and testing packages...")
443               
444                        # SAMPLE CODE
445                       
446                        #self.core.n4d.lliurex_version()
447                        #print "testeando....."
448                        #time.sleep(1.5)
449                        # ######### #
450                        #self.core.current_var=copy.deepcopy(self.core.var)
451                        self.core.var=copy.deepcopy(self.core.current_var)
452                        self.test_apt=self.core.n4d.test_apt_list(self.core.var)
453                        self.thread_ret={"status":True,"msg":"BROKEN"}
454       
455                        # store return value here
456                       
457                       
458                       
459                except Exception as e:
460                        print e
461                        return False
462               
463               
464        #def apply_changes_thread
465       
466        def check_apply_thread(self,dialog):
467               
468               
469                if self.thread.is_alive():
470                        return True
471               
472                dialog.destroy()
473               
474                #self.test_apt=[True,False, n4d_var, listado_apt_accesibles, listado_apt_no_instalbles, comentario]
475                if self.test_apt[0]:
476                        if self.test_apt[3] not in [None,"","[]",[]]:
477                                if self.delete_test_apt_dialog(self.test_apt[3]):
478                                        self.core.n4d.set_variable(self.test_apt[1])
479                                        self.core.var=copy.deepcopy(self.test_apt[1])
480                                        self.core.current_var=copy.deepcopy(self.test_apt[1])
481                                else:
482                                        self.core.n4d.set_variable(self.core.var)
483                        else:
484                                self.core.n4d.set_variable(self.core.var)
485                        self.core.dprint("Done")
486                else:
487                        self.core.dprint("Test Error: variable remains unset")
488               
489               
490                for b in self.list_box:
491                        if b.get_tooltip_text()==self.current_id:
492                                break
493               
494               
495                self.apt_clicked(b,self.current_id)
496               
497               
498               
499                if not self.thread_ret["status"]:
500                        mw=self.core.lri.main_window
501                        d=Dialog.ErrorDialog(mw,"",self.thread_ret["msg"])
502                        d.run()
503                        d.destroy()
504               
505
506                return False
507               
508        #def check_thread
509       
510       
511        # ######################################################### #
512       
513
514        # ### DIALOGS ##### ##################
515       
516        def delete_apt_dialog(self,pkg_name):
517               
518                main_window=self.core.lri.main_window
519               
520                dialog=Dialog.QuestionDialog(main_window,_(u"Delete apt list"),_(u"Do you want to delete '%s' packages list?")%pkg_name)
521                response=dialog.run()
522                dialog.destroy()
523               
524                if response== Gtk.ResponseType.OK:
525                        return True
526               
527                return False
528               
529        #def delete_package_dialog
530       
531        def delete_test_apt_dialog(self,pkg_name_orig):
532               
533                main_window=self.core.lri.main_window
534                pkg_name='\n'.join(pkg_name_orig)
535                dialog=Dialog.QuestionDialog(main_window,_(u"Delete apt list"),_(u"This pakage list is unavaiable from your repos:\n%s\nDo you want delete it?")%pkg_name)
536                response=dialog.run()
537                dialog.destroy()
538               
539                if response== Gtk.ResponseType.OK:
540                        return True
541               
542                return False
543               
544        #def delete_package_dialog
545       
546        def delete_package_dialog(self,pkg_name):
547               
548                main_window=self.core.lri.main_window
549                dialog=Dialog.QuestionDialog(main_window,_(u"Delete package"),_(u"Do you want to delete '%s'?")%pkg_name)
550                response=dialog.run()
551                dialog.destroy()
552               
553                if response== Gtk.ResponseType.OK:
554                        return True
555               
556                return False
557               
558        #def delete_package_dialog
559       
560        def changes_detected_dialog(self,force_exit=False):
561               
562                main_window=self.core.lri.main_window
563               
564                dialog=Dialog.QuestionDialog(main_window,_(u"Changes detected"),_(u"There are unsaved changes. Do you want to discard them?"))
565                response=dialog.run()
566                dialog.destroy()
567               
568                if response== Gtk.ResponseType.OK:
569                        if force_exit:
570                                sys.exit(0)
571                               
572                        return True
573               
574                return False
575               
576        #def changes_detected_dialog
577       
578        # #####################################################
579               
580       
581       
582       
583#class aptbox
Note: See TracBrowser for help on using the repository browser.