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

Last change on this file since 3984 was 3984, checked in by daduve, 3 years ago

Fix bug: Executables with equal name but not equal md5

File size: 13.4 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 os
14import subprocess
15
16_=gettext.gettext
17
18
19RSRC="./"
20
21
22class ExecBox(Gtk.VBox):
23       
24       
25        def __init__(self):
26               
27                Gtk.VBox.__init__(self)
28               
29                self.core=Core.Core.get_core()
30               
31                builder=Gtk.Builder()
32                ui_path=RSRC + "lliurex-remote-installer.ui"
33                builder.add_from_file(ui_path)
34                self.main_box=builder.get_object("exec_data_box")
35                self.add_exec_button=builder.get_object("add_exec_button")
36                self.package_label=builder.get_object("package_label_exec")
37                self.package_list_box=builder.get_object("exec_list_box")
38                self.package_list=builder.get_object("exec_list_box")
39                self.data_vp=builder.get_object("exec_list_viewport")
40                self.apply_exec_button=builder.get_object("apply_exec_button")
41               
42               
43
44                self.add(self.main_box)
45               
46                self.connect_signals()
47                self.set_css_info()
48               
49                self.core.current_var=None
50                self.current_id=None
51               
52                self.thread=threading.Thread()
53                self.thread_ret=None
54               
55               
56               
57        #def __init__
58       
59       
60        def set_css_info(self):
61               
62                self.style_provider=Gtk.CssProvider()
63                f=Gio.File.new_for_path("lliurex-remote-installer.css")
64                self.style_provider.load_from_file(f)
65                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
66                self.package_label.set_name("OPTION_LABEL")
67               
68                       
69        #def set-css_info
70       
71       
72        def set_info(self,info):
73               
74                #Empty list
75                for c in self.package_list_box.get_children():
76                        self.package_list_box.remove(c)
77                       
78                self.core.var=info
79                self.core.current_var=copy.deepcopy(self.core.var)
80                for (x,y) in self.core.var["sh"]["packages"]:
81                        self.new_package_button("%s"%x)
82                       
83               
84        #def set_info
85       
86       
87        def connect_signals(self):
88               
89               
90                self.add_exec_button.connect("clicked",self.add_exec_button_clicked)
91                self.apply_exec_button.connect("clicked",self.apply_exec_button_clicked)
92               
93               
94        #def connect_signals
95       
96       
97        def exec_list_init(self):
98               
99                try:
100                        self.new_execs
101                        return True
102                except Exception as e:
103                        #print "inicializando variables de listas"
104                        self.new_execs=[]
105                        self.list_new_execs=[]
106                        return True
107               
108        #def exec_list_init
109       
110       
111        def add_exec_button_clicked(self,widget):
112               
113               
114               
115                fcb=Dialog.FileDialog(self.core.lri.main_window,"Please choose a file")
116                response=fcb.run()
117                #Creo las listas de ayuda para anyadir paquetes si no existen antes
118                self.exec_list_init()
119               
120                if response==Gtk.ResponseType.OK:
121                        exec_url=fcb.get_filename()
122                        fcb.destroy()
123                        pkg=os.path.basename(exec_url)
124                        lines=subprocess.Popen(["LAGUAGE=en_EN; md5sum %s | awk '{print $1}'"%exec_url],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()[0]
125                        for line in lines.splitlines():
126                                md5=line
127                        pkg_tupla=[pkg,md5]
128                        #Compruebo si existe el paquete en la lista
129                        if any(pkg in element for element in self.core.current_var["sh"]["packages"]):
130                                #No es nuevo, compruebo si coincide su md5sum y lo apunto a subir de nuevo
131                                if pkg_tupla not in self.core.current_var["sh"]["packages"]:
132                                        #he de eliminar la tupla de la lista que contiene mi elemento con mismo pkg pero con nuevo md5sum
133                                        for i,[pkg_for,md5_for] in enumerate(self.core.current_var["sh"]["packages"]):
134                                                if pkg == pkg_for:
135                                                        self.core.current_var["sh"]["packages"].pop(i)
136                                        #self.core.current_var["sh"]["packages"].remove(pkg_tupla)
137                                        self.core.current_var["sh"]["packages"].append(pkg_tupla)
138                                        self.new_execs.append([pkg,exec_url])
139                                        self.list_new_execs.append(pkg)
140                        else:
141                                self.core.current_var["sh"]["packages"].pop(pkg_tupla)
142                                self.new_package_button(pkg)
143                                #print "paquete nuevo en lista, esta subido??"
144                                #Compruebo que es accesible via apache, sino lo apunto para copiar cuando aplique.
145                                exist_in_server=self.core.n4d.app_deb_exist(pkg, self.core.current_var["sh"]["url"])
146                                if not exist_in_server[0]:
147                                        #print "No existe este exec lo debo de subir"
148                                        self.new_execs.append([pkg,exec_url])
149                                        self.list_new_execs.append(pkg)
150                                       
151
152                        # ###### #
153                        #print self.core.current_var
154                        #print self.core.var
155                        return True
156                else:
157                        fcb.destroy()
158                        return False
159                       
160        #def add-exec_button_clicked
161       
162       
163        def hide_window(self,widget,event):
164               
165                widget.hide()
166                return True
167               
168        #def new_package_window
169
170
171       
172        def check_changes(self,widget=True,event=True,manage_dialog=False):
173               
174               
175                if not manage_dialog:
176                        if self.core.current_var==None:
177                                return False
178                        return self.core.current_var != self.core.var
179               
180                               
181                if self.core.current_var!=None and self.core.current_var != self.core.var:
182                        if not self.changes_detected_dialog(False):
183                                return True
184               
185                sys.exit(0)
186                       
187
188        #def check_changes
189               
190       
191
192       
193        def new_package_button(self,pkg_name):
194               
195                hbox=Gtk.HBox()
196                label=Gtk.Label(pkg_name)
197                b=Gtk.Button()
198                i=Gtk.Image.new_from_file("trash.svg")
199                b.add(i)
200                b.set_halign(Gtk.Align.CENTER)
201                b.set_valign(Gtk.Align.CENTER)
202                b.set_name("DELETE_ITEM_BUTTON")
203                b.connect("clicked",self.delete_package_clicked,hbox)
204                hbox.pack_start(label,False,False,0)
205                hbox.pack_end(b,False,False,10)
206                hbox.show_all()
207                label.set_margin_right(20)
208                label.set_margin_left(20)
209                label.set_margin_top(20)
210                label.set_margin_bottom(20)
211                hbox.set_name("PKG_BOX")
212                self.package_list_box.pack_start(hbox,False,False,5)
213                self.package_list_box.queue_draw()
214                hbox.queue_draw()
215               
216        #def new_package_button
217       
218       
219       
220        # #### PACKAGE CHANGES ################### #
221       
222       
223        def delete_package_clicked(self,button,hbox):
224               
225                pkg=hbox.get_children()[0].get_text()
226               
227                if self.delete_package_dialog(pkg):
228                        self.package_list_box.remove(hbox)
229                       
230                        for p in range(len(self.core.current_var["sh"]["packages"])-1,-1,-1):
231                                if self.core.current_var["sh"]["packages"][p][0]==pkg:
232                                        self.core.current_var["sh"]["packages"].pop(p)
233                                               
234                        #Compruebo que es accesible via apache, y pregunto si lo borro tambien del servidor
235                        exist_in_server=self.core.n4d.app_deb_exist(pkg, self.core.current_var["sh"]["url"])
236                        if exist_in_server[0]:
237                                if self.remove_file_dialog(pkg):
238                                        self.thread=threading.Thread(target=self.delete_package_thread(pkg))
239                                        self.thread.daemon=True
240                                        self.thread.start()
241                                       
242                                        main_window=self.core.lri.main_window
243                                        dialog=Dialog.ApplyingChangesDialog(main_window,title="Lliurex Remote Installer",msg="Deleting files.......")
244                                        dialog.show()
245                                        GLib.timeout_add(500,self.check_delete_thread,dialog)
246                        else:
247                                self.check_delete_thread
248                       
249                        # ######### #
250       
251       
252        #def delete_package_clicked
253       
254        def delete_package_thread(self,pkg):
255       
256                try:
257                        self.core.dprint("Deleting file...")
258       
259                        url_dest="/var/www/llx-remote/"+str(pkg)
260                        self.deleted=self.core.n4d.remove_file(url_dest)
261                        if not self.deleted[0]:
262                                comment="The file %s cannot be deleted"%pkg
263                                self.remove_file_info_dialog(comment)
264                               
265                        self.thread_ret={"status":True,"msg":"SE HA ROTO"}
266                       
267                except Exception as e:
268                        print e
269                        return False
270                       
271        #def delete_package_thread
272       
273        def check_delete_thread(self,dialog):
274               
275                if self.thread.is_alive():
276                        return True
277               
278                dialog.destroy()
279                for c in self.package_list_box.get_children():
280                        self.package_list_box.remove(c)
281                for (x,md5) in self.core.current_var["sh"]["packages"]:
282                        self.new_package_button("%s"%x)
283                if self.deleted[0]:
284                        self.core.var=copy.deepcopy(self.core.current_var)
285                        self.core.n4d.set_variable(self.core.var)
286                       
287                       
288               
289        #check_delete_thread
290       
291       
292        def apply_exec_button_clicked(self,widget):
293               
294                self.exec_list_init()
295                self.thread=threading.Thread(target=self.apply_changes_thread)
296                self.thread.daemon=True
297                self.thread.start()
298               
299                #Se crea el mensaje de Apply segun si sse suben ficheros o no.
300                self.msg1="Applying changes......."
301                if  self.new_execs not in [None,"",[]]:
302                        self.msg1="Updating files and applying changes......."
303                else:
304                        self.msg1="Applying changes......."
305               
306                main_window=self.core.lri.main_window
307                dialog=Dialog.ApplyingChangesDialog(main_window,title="Lliurex Remote Installer",msg=self.msg1)
308                dialog.show()
309                GLib.timeout_add(500,self.check_apply_thread,dialog)
310               
311        #def apply_changes_button_clicked
312       
313               
314       
315        def apply_changes_thread(self):
316               
317                try:
318                       
319                        print "Testing....."
320                        self.not_sended_execs=[]
321                       
322
323                        if  self.new_execs not in [None,"",[]]:
324                                self.core.dprint("Sending files to server...")
325                                for sh in self.new_execs:
326                                        pkg=sh[0]
327                                        exec_url=sh[1]
328                                        if self.core.current_var["sh"]["url"] in [None,"",[]]:
329                                                self.core.current_var["sh"]["url"]="http://server/llx-remote/"
330                                        url_dest=self.core.current_var["sh"]["url"].split('http://server/')[1]
331                                        url_dest="/var/www/"+str(url_dest)
332                                        response=self.core.n4d.send_file("server",exec_url,url_dest)
333                                        #Ha fallado la subida del fichero
334                                        if not response:
335                                                self.not_sended_execs.append(pkg)
336                                                for (pkg_list,md5) in self.core.current_var["sh"]["packages"]:
337                                                        if pkg_list in {pkg}:
338                                                                self.core.current_var["sh"]["packages"].remove([pkg_list,md5])
339
340                                #Inicializo de nuevo la lista de paquetes, ya esta subido todo lo que se queria.
341                                self.new_execs=[]
342                                self.list_new_execs=[]
343                       
344                        self.core.dprint("Applying changes...")
345                        self.test_exec=self.core.n4d.test_list(self.core.current_var,'sh')
346                        self.core.var=copy.deepcopy(self.core.current_var)
347                        self.thread_ret={"status":True,"msg":"SE HA ROTO"}
348
349                       
350                except Exception as e:
351                        print e
352                        return False
353               
354               
355        #def apply_changes_thread
356       
357        def check_apply_thread(self,dialog):
358               
359               
360                if self.thread.is_alive():
361                        return True
362               
363                dialog.destroy()
364                #Se pudo testear la lista de execs, es un  [True,dict,list_execs_ok,list_execs_fail]
365                if self.test_exec[0]:
366                        if self.test_exec[3] not in [None,"","[]",[]]:
367                                if self.delete_test_exec_dialog(self.test_exec[3]):
368                                        self.core.n4d.set_variable(self.test_exec[1])
369                                        self.core.var=copy.deepcopy(self.test_exec[1])
370                                        self.core.current_var=copy.deepcopy(self.test_exec[1])
371                                else:
372                                        self.core.var["sh"]["url"]="http://server/llx-remote/"
373                                        self.core.n4d.set_variable(self.core.var)
374                        else:
375                                        self.core.var["sh"]["url"]="http://server/llx-remote/"
376                                        self.core.n4d.set_variable(self.core.var)
377                       
378                else:
379                        self.core.dprint("Error en el test, no se guarda la variable")
380                       
381                self.set_info(self.core.var)
382                self.core.dprint("Done")
383               
384                if not self.thread_ret["status"]:
385                        mw=self.core.lri.main_window
386                        d=Dialog.ErrorDialog(mw,"asdasd",self.thread_ret["msg"])
387                        d.run()
388                        d.destroy()
389               
390                if self.not_sended_execs not in [None,"",[]]:
391                        self.error_send_dialog(self.not_sended_execs)
392                       
393                return False
394               
395        #def check_thread
396       
397       
398        # ######################################################### #
399       
400       
401        # #### DIALOGS ################### #
402       
403        def error_send_dialog(self,pkg_name):
404               
405                main_window=self.core.lri.main_window
406                dialog=Dialog.ErrorDialog(main_window,"Sending Package Error","This list %s cannot be sended to server\nPlease review your share directory\n\n/var/www/llx-remote"%pkg_name)
407                response=dialog.run()
408                dialog.destroy()
409               
410               
411                return True
412               
413        #def delete_package_dialog
414       
415       
416       
417        def delete_package_dialog(self,pkg_name):
418               
419                main_window=self.core.lri.main_window
420                dialog=Dialog.QuestionDialog(main_window,"Delete package","Do you want to delete '%s'?"%pkg_name)
421                response=dialog.run()
422                dialog.destroy()
423               
424                if response== Gtk.ResponseType.OK:
425                        return True
426               
427                return False
428               
429        #def delete_package_dialog
430       
431        def remove_file_dialog(self,pkg_name):
432               
433                main_window=self.core.lri.main_window
434                dialog=Dialog.QuestionDialog(main_window,"Delete package","IMPORTANT\nDo you want to delete this Executable from your server?\n'%s'"%pkg_name)
435                response=dialog.run()
436                dialog.destroy()
437               
438                if response== Gtk.ResponseType.OK:
439                        return True
440               
441                return False
442               
443        #def remove_file_dialog
444       
445        def remove_file_info_dialog(self,comment):
446               
447                main_window=self.core.lri.main_window
448                dialog=Dialog.ErrorDialog(main_window,"Delete package",comment)
449                response=dialog.run()
450                dialog.destroy()
451                               
452                return True
453               
454        #def remove_file_info_dialog
455       
456        def send_file_dialog(self,pkg_name):
457               
458                main_window=self.core.lri.main_window
459                dialog=Dialog.QuestionDialog(main_window,"Executable not in Server","Do you want to send to the server this Executable '%s' ?"%pkg_name)
460                response=dialog.run()
461                dialog.destroy()
462               
463                if response== Gtk.ResponseType.OK:
464                        return True
465               
466                return False
467               
468        #def delete_package_dialog
469       
470        def send_list_dialog(self,pkg_name_orig):
471                main_window=self.core.lri.main_window
472                pkg_name='\n'.join(pkg_name_orig)
473                dialog=Dialog.QuestionDialog(main_window,"Executable not in Server","Do you want to send to the server this Executable list?\n%s\n"%pkg_name)
474                response=dialog.run()
475                dialog.destroy()
476               
477                if response== Gtk.ResponseType.OK:
478                        return True
479               
480                return False
481               
482        #def send_list_dialog
483       
484       
485        def changes_detected_dialog(self,force_exit=False):
486               
487                main_window=self.core.lri.main_window
488               
489                dialog=Dialog.QuestionDialog(main_window,"Changes detected","There are unsaved changes. Do you want to discard them?")
490                response=dialog.run()
491                dialog.destroy()
492               
493                if response== Gtk.ResponseType.OK:
494                        if force_exit:
495                                sys.exit(0)
496                               
497                        return True
498               
499                return False
500               
501        #def changes_detected_dialog
502       
503       
504       
505        def delete_test_exec_dialog(self,pkg_list_tupla):
506               
507                main_window=self.core.lri.main_window
508                lista=[]
509                for (pkg_name_orig,md5) in pkg_list_tupla:
510                        lista.append(pkg_name_orig)
511                pkg_name='\n'.join(lista)
512                dialog=Dialog.QuestionDialog(main_window,"Delete Executable list","This Executable list is unavaiable from your server:\n%s\nDo you want delete it?"%pkg_name)
513                response=dialog.run()
514                dialog.destroy()
515               
516                if response== Gtk.ResponseType.OK:
517                        return True
518               
519                return False
520               
521        #def delete_package_dialog
522       
523       
524#class execbox
Note: See TracBrowser for help on using the repository browser.