source: lliurex-up/trunk/fuentes/lliurex-up-gui/lliurex-up @ 2674

Last change on this file since 2674 was 2674, checked in by jrpelegrina, 4 years ago

WIP in new gui

File size: 16.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import gi
5gi.require_version('Gtk', '3.0')
6gi.require_version('PangoCairo', '1.0')
7gi.require_version('Vte', '2.91')
8
9import cairo
10import os
11import threading
12import ConfigParser
13import platform
14import subprocess
15import sys
16import time
17import commands
18
19from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib, PangoCairo, Pango, Vte
20
21import signal
22signal.signal(signal.SIGINT, signal.SIG_DFL)
23
24import gettext
25gettext.textdomain('lliurex-up')
26_ = gettext.gettext
27
28
29
30RSRC_DIR="rsrc/"
31CACHED_ICON="rsrc/cached.png"
32DONE_ICON="rsrc/done.png"
33ERROR_ICON="rsrc/error.png"
34
35class Package:
36
37        def __init__(self,name,version,size,desktop_file,changelog_file):
38
39                self.name=name
40                self.version=version
41                self.size=size
42                self.parse_desktop(desktop_file)
43                self.parse_changelog(changelog_file)
44                self.parse_installed_icon(CACHED_ICON)
45
46        #def__init__
47       
48        def parse_desktop(self,desktop_file):
49               
50                try:
51                        config = ConfigParser.ConfigParser()
52                        config.optionxform=str
53                        config.read(desktop_file)
54                       
55                        if config.has_section("Desktop Entry") and config.has_option("Desktop Entry","Icon"):
56                                self.icon=config.get("Desktop Entry","Icon")
57                        else:
58                                self.icon="package"
59                               
60                except Exception as e:
61                       
62                        self.icon="package"
63                       
64        #def parse_desktop
65       
66        def parse_changelog(self,changelog_file):
67               
68                try:
69                       
70                        f=open(changelog_file,"r")
71                        self.changelog=f.readlines()
72                        f.close()
73                                               
74                except Exception as e:
75                       
76                        self.changelog="Changelog not found"
77
78        #def parse_changelog
79       
80        def parse_installed_icon(self, icon_file):
81                        image=Gtk.Image()
82                        image.set_from_file(icon_file)         
83                        self.installed=image.get_pixbuf()
84                       
85        #def parse_installed_icon
86
87class LliurexUp:
88
89        def __init__(self):
90
91
92                self.start_gui()
93       
94        #def __init__           
95
96        def start_gui(self):
97               
98                builder=Gtk.Builder()
99               
100                glade_path=RSRC_DIR+"lliurex-up.ui"
101                builder.add_from_file(glade_path)
102
103                self.stack = Gtk.Stack()
104                self.stack.set_transition_duration(1000)
105                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
106
107
108                self.window=builder.get_object("main_window")
109                self.main_box=builder.get_object("main_box")
110                self.pbar=builder.get_object("progressbar")
111                self.pbar_label=builder.get_object("progressbar_label")
112               
113
114                self.cancel_button_box=builder.get_object("cancel_button_box")
115                self.cancel_eb=builder.get_object("cancel_button_eventbox")
116                self.cancel_eb.connect("button-press-event", self.quit)
117                self.cancel_label=builder.get_object("cancel_button_label")
118
119
120                self.gather_box=builder.get_object("gather_box")
121                self.yes_button_box=builder.get_object("yes_button_box")
122                self.yes_button_eb=builder.get_object("yes_button_eventbox")
123                self.yes_button_eb.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
124                self.yes_button_eb.connect("button-release-event", self.yes_button_clicked)
125                self.yes_button_label=builder.get_object("yes_button_label")
126                self.no_button_box=builder.get_object("no_button_box")
127                self.no_button_eb=builder.get_object("no_button_eventbox")
128                self.no_button_eb.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
129                self.no_button_eb.connect("button-release-event", self.no_button_clicked)
130                self.no_button_label=builder.get_object("no_button_label")
131                self.gather_logo_box=builder.get_object("gather_logo_box")
132                self.gather_label=builder.get_object("gather_label")
133
134                self.update_box=builder.get_object("update_box")
135                self.version_available_label=builder.get_object("version_available_label")
136                self.version_update_label=builder.get_object("version_update_label")
137                self.number_packages_label=builder.get_object("number_packages_label")
138                self.size_update_label=builder.get_object("size_update_label")
139                self.view_packages_button_box=builder.get_object("view_packages_button_box")
140                self.view_packages_eb=builder.get_object("view_packages_eventbox")
141                self.view_packages_eb.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
142                self.view_packages_eb.connect("button-release-event", self.view_packages_clicked)
143                self.view_packages_label=builder.get_object("view_packages_label")
144
145                self.update_button_box=builder.get_object("update_button_box")
146                self.update_button_eb=builder.get_object("update_button_eventbox")
147                self.update_button_eb.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
148                self.update_button_eb.connect("button-release-event", self.install_packages)
149                self.update_button_label=builder.get_object("update_button_label")
150                self.terminal_label=builder.get_object("terminal_label")
151                self.viewport=builder.get_object("viewport")
152                self.terminal_scrolled=builder.get_object("terminalScrolledWindow")
153                self.vterminal=Vte.Terminal()
154                font_terminal = Pango.FontDescription("monospace normal 10")
155                self.vterminal.set_font(font_terminal)
156                self.terminal_scrolled.add(self.vterminal)
157               
158
159                self.packages_box=builder.get_object("packages_box")
160                self.return_arrow_box=builder.get_object("return_arrow_box")
161                self.return_arrow_eb=builder.get_object("return_arrow_eventbox")
162                self.return_arrow_eb.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
163                self.return_arrow_eb.connect("button-release-event", self.arrow_clicked)
164                self.packages_label=builder.get_object("packages_label")
165                self.packages_tv=builder.get_object("packages_treeview")
166                self.changelog_texview=builder.get_object("changelog_textview")
167
168                self.packages_store=Gtk.ListStore(str,str,str,GdkPixbuf.Pixbuf)
169                self.packages_tv.set_model(self.packages_store)
170                column=Gtk.TreeViewColumn("")
171                cell=Gtk.CellRendererPixbuf()
172                cell.set_property("stock-size",Gtk.IconSize.DIALOG)
173                column.pack_start(cell,True)
174                column.add_attribute(cell,"icon-name",0)
175                self.packages_tv.append_column(column)
176               
177                column=Gtk.TreeViewColumn("Package")
178                cell=Gtk.CellRendererText()
179                column.pack_start(cell,True)
180                column.add_attribute(cell,"markup",1)
181                column.set_expand(True)
182
183               
184                self.packages_tv.append_column(column)
185               
186                self.packages_tv.connect("button-release-event",self.package_clicked)
187               
188                column=Gtk.TreeViewColumn("Size")
189                cell=Gtk.CellRendererText()
190                cell.set_property("alignment",Pango.Alignment.CENTER)
191                column.pack_start(cell,False)
192                column.add_attribute(cell,"markup",2)
193                self.packages_tv.append_column(column)         
194
195
196                done_icon=Gtk.Image()
197                done_icon.set_from_file(CACHED_ICON)
198                pixbuf=done_icon.get_pixbuf()
199                column=Gtk.TreeViewColumn("Installed")
200                cell=Gtk.CellRendererPixbuf()
201                #cell.set_property("stock-size",Gtk.IconSize.DIALOG)
202                column.pack_start(cell,True)
203                column.add_attribute(cell,"pixbuf",3)
204                self.packages_tv.append_column(column)
205               
206                self.changelog_textview=builder.get_object("changelog_textview")
207                self.changelog_label=builder.get_object("changelog_label")
208
209
210                self.stack.add_titled(self.gather_box,"gather","Gather")
211                self.stack.add_titled(self.update_box,"update", "Update")
212                self.stack.add_titled(self.packages_box, "packages", "Packages")
213
214                self.main_box.pack_start(self.stack,True,False,5)
215
216                self.window.show_all()
217                self.terminal_scrolled.hide()
218                self.viewport.hide()
219                self.terminal_label.hide()
220                self.cancel_button_box.hide()
221                self.yes_button_box.hide()
222                self.no_button_box.hide()
223
224                self.pbar_label.show()
225                self.pbar.show()
226               
227                self.window.connect("destroy",self.quit)
228               
229               
230                self.set_css_info()
231               
232
233
234                GLib.timeout_add(100,self.pulsate_gathering_info)
235               
236                self.t=threading.Thread(target=self.gather_info)
237                self.t.daemon=True
238                self.t.start()
239                self.no_mirror=False
240
241                self.package_list=[]
242
243                GObject.threads_init()
244                Gtk.main()
245
246        #def start_gui
247       
248        def set_css_info(self):
249       
250                css = """
251
252
253                #WHITE_BACKGROUND {
254                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff),  to (#ffffff));;
255               
256                }
257
258                #BUTTON_LABEL{
259                        color:white;
260                        font: Roboto 10;
261                }
262
263                #DISABLED_BUTTON_OVER{
264                        background-image:-gtk-gradient (linear, left top, left bottom, from (#888888),  to (#888888));;
265                }
266               
267                #DISABLED_BUTTON{
268                        background-image:-gtk-gradient (linear, left top, left bottom, from (#666666),  to (#666666));;
269                }
270               
271                #CANCEL_BUTTON{
272                        background-image:-gtk-gradient (linear, left top, left bottom, from (#D32F2F),  to (#D32F2F));;
273                }
274               
275                #CANCEL_BUTTON_OVER{
276                        background-image:-gtk-gradient (linear, left top, left bottom, from (#F44336),  to (#F44336));;
277                }
278
279                #BUTTON_COLOR {
280                        background-image:-gtk-gradient (linear, left top, left bottom, from (#448AFF),  to (#448AFF));;
281               
282                }
283               
284                #UPDATE_BUTTON_LABEL{
285                        color:white;
286                        font: Roboto 11;
287                }
288               
289                #UPDATE_BUTTON_COLOR {
290                        background-image:-gtk-gradient (linear, left top, left bottom, from (#43A047),  to (#43A047));;
291               
292                }
293               
294                #GATHER_ICON_COLOR {
295                        background-image:-gtk-gradient (linear, left top, left bottom, from (#b0bec5),  to (#b0bec5));;
296               
297                }
298               
299               
300                #BLUE_FONT {
301                        color: #3366cc;
302                        font: Roboto 10;
303                       
304                }       
305               
306
307                #CHANGELOG_FONT {
308                        color: #3366cc;
309                        font: Roboto 11;
310                       
311                }
312
313                #LABEL_OPTION{
314               
315                        color: #808080;
316                        font: Roboto 11;
317                }
318               
319                """
320
321                self.style_provider=Gtk.CssProvider()
322                self.style_provider.load_from_data(css)
323                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
324               
325                self.window.set_name("WHITE_BACKGROUND")
326                self.update_box.set_name("WHITE_BACKGROUND")
327                self.gather_box.set_name("WHITE_BACKGROUND")
328                self.packages_box.set_name("WHITE_BACKGROUND")
329                self.gather_label.set_name("CHANGELOG_FONT")
330                self.pbar_label.set_name("CHANGELOG_FONT")
331
332                self.yes_button_box.set_name("BUTTON_COLOR")
333                self.yes_button_label.set_name("BUTTON_LABEL")
334
335                self.no_button_box.set_name("BUTTON_COLOR")
336                self.no_button_label.set_name("BUTTON_LABEL")
337
338                self.view_packages_button_box.set_name("BUTTON_COLOR")
339                self.view_packages_label.set_name("BUTTON_LABEL")
340
341                self.cancel_button_box.set_name("BUTTON_COLOR")
342                self.cancel_label.set_name("BUTTON_LABEL")     
343
344                self.version_available_label.set_name("LABEL_OPTION")
345                self.version_update_label.set_name("LABEL_OPTION")     
346                self.number_packages_label.set_name("LABEL_OPTION")
347                self.size_update_label.set_name("LABEL_OPTION")
348                self.update_button_label.set_name("UPDATE_BUTTON_LABEL")
349                self.update_button_box.set_name("UPDATE_BUTTON_COLOR")
350                self.terminal_label.set_name("LABEL_OPTION")
351
352
353                self.packages_label.set_name("LABEL_OPTION")
354                self.changelog_label.set_name("LABEL_OPTION")
355                self.changelog_texview.set_name("CHANGELOG_FONT")
356                self.return_arrow_box.set_name("BUTTON_COLOR")
357               
358        #def set_css_info       
359
360        def check_lliurexup_version(self):
361
362                print "Checking lliurex-up version"
363                msg_gather="<span><b>"+_("Checking for new version of lliurex-up")+"</b></span>"
364                self.gather_label.set_markup(msg_gather)
365                time.sleep(2)
366                return True
367       
368        #def check_lliurexup_version
369
370        def check_mirror(self):
371                print "Checking mirror"
372                self.response=-1
373                t=0
374                self.yes_button_box.show()
375                self.no_button_box.show()
376                msg_gather="<span><b>"+_("Do you want to update your mirror?")+"</b></span>"
377                self.gather_label.set_markup(msg_gather)
378               
379                while self.response==-1:
380                        time.sleep(t)
381                        t=t+1
382
383                self.yes_button_box.hide()
384                self.no_button_box.hide()       
385                return True
386
387        #def check_mirror
388       
389        def gather_info(self):
390
391                self.check_lliurexup_version()
392                self.check_mirror()
393                               
394
395                msg_gather="<span><b>"+_("Checking for new updates")+"</b></span>"
396                self.gather_label.set_markup(msg_gather)
397               
398                #p=subprocess.Popen([cmd],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)     
399                #output=p.communicate()
400                try:
401                        p1=subprocess.Popen(["llxcfg-upgrade-version-scripts","details"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
402                        output=p1.communicate()[0]
403                        f=open("/tmp/.lliurex_up_log","w")
404                        if output!=None:
405                                f.write(output)
406                        f.close()
407       
408                except:
409                        pass 
410
411        #def gather_info
412
413
414        def pulsate_gathering_info(self):
415               
416                self.pbar.pulse()
417               
418                if not self.t.is_alive():
419                       
420                        self.parse_simulate_output("/tmp/.lliurex_up_log")
421                        self.populate_packages_tv()     
422                        self.get_update_info()
423                        self.pbar.hide()
424                        self.pbar_label.hide()
425                        if len(self.package_list)==0:
426                                msg_gather="<span><b>"+_("Your system is update")+"</b></span>"
427                                self.gather_label.set_markup(msg_gather)
428
429                        else:
430                               
431                                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
432                                self.stack.set_visible_child_name("update")     
433                       
434                        self.cancel_button_box.show()
435
436                return self.t.is_alive()       
437
438        #def pulsate_gathering_ingo     
439               
440        def populate_packages_tv(self):
441               
442                for package in self.package_list:
443                        print package
444                        self.packages_store.append((package.icon,"<span font='Roboto'><b>"+package.name+"</b></span>\n"+"<span font='Roboto' size='small'>"+package.version+"</span>","<span font='Roboto' size='large'><b>"+package.size+"</b></span>",package.installed))
445                       
446                       
447                print len(self.packages_store) 
448               
449        #def populate_packages_tv
450       
451        def parse_simulate_output(self,test_file=None):
452               
453                if test_file!=None:
454                        f=open(test_file,"r")
455                       
456                        for line in f:
457                                if line.find("#")==0:
458                                        pass
459                                else:
460                                        tmp=line.split(";")
461                                        if len(tmp)>4:
462                                                package=Package(tmp[0],tmp[1],tmp[2],tmp[3],tmp[4])
463                                                self.package_list.append(package)
464
465                       
466                else:
467                        #to be done later
468                        pass   
469
470        #def parse_simulate_output
471       
472        def package_clicked(self,x,y):
473               
474                selection=self.packages_tv.get_selection()
475                model,iter=selection.get_selected()
476                name=self.packages_store.get_value(iter,1)
477                name=name[name.find("<b>")+3:name.find("</b>")]
478                               
479                for package in self.package_list:
480                       
481                        if package.name==name:
482                                self.changelog_textview.get_buffer().set_text("".join(package.changelog))
483                               
484                                break
485       
486        #def package_clicked                   
487
488        def execute(self):
489               
490                self.vterminal.spawn_sync(
491                        Vte.PtyFlags.DEFAULT,
492                        os.environ['HOME'],
493                        ["/usr/sbin/dpkg-reconfigure", "xdm"],
494                        [],
495                        GLib.SpawnFlags.DO_NOT_REAP_CHILD,
496                        None,
497                        None,
498                )
499
500                self.update_installed_icon()
501       
502        #def execute           
503                               
504        def install_packages(self,widget, event=None):
505                self.t=threading.Thread(target=self.execute,args=())
506                self.t.daemon=True
507                self.t.start()
508                GLib.timeout_add(100,self.pulsate_pbar)
509                self.pbar.show()
510                self.pbar_label.show()
511                self.viewport.show()
512                self.terminal_scrolled.show()
513                self.terminal_label.show()
514                msg_terminal=_("Update process details")
515                self.terminal_label.set_markup(msg_terminal)
516       
517        #def install_packages
518
519        def get_update_info(self):
520                self.version_available="16.160916"
521                self.version_update="16.160915"
522                self.number_pkg="15"
523                self.size_update="100 Mb"
524               
525                msg_version_available=_("Version available: ")+"<span foreground='#3366cc'><b>"+self.version_available+"</b></span>"
526                msg_version_update=_("Version to update: ")+"<span foreground='#3366cc'><b>"+self.version_update+"</b></span>"
527
528                msg_number=_("Number packages: ")+"<span foreground='#3366cc'><b>"+self.number_pkg+"</b></span>"
529                msg_size=_("Size of update: ")+"<span foreground='#3366cc'><b>"+self.size_update+"</b></span>"
530               
531                self.version_available_label.set_markup(msg_version_available)
532                self.version_update_label.set_markup(msg_version_update)
533                self.number_packages_label.set_markup(msg_number)
534                self.size_update_label.set_markup(msg_size)
535               
536        #def get_update_info   
537               
538
539        def pulsate_pbar(self):
540                if not self.t.is_alive():
541                        self.pbar.pulse()
542                else:
543                        self.pbar.hide()
544                       
545        #def pulsate_pbar
546                       
547        def view_packages_clicked(self,widget,event):
548                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
549                self.stack.set_visible_child_name("packages")
550               
551        #def view_packages_clicked     
552       
553
554        def no_button_clicked(self,widget,event):
555               
556                self.response=1 
557               
558        def yes_button_clicked(self,widget,event):
559               
560                msg_gather="<span><b>"+_("Updating mirror in progess?")+"</b></span>"
561                self.gather_label.set_markup(msg_gather)
562                self.yes_button_box.hide()
563                self.no_button_box.hide()
564               
565                command='/usr/share/lliurex-flavours-selector/lliurex-flavours-selector.py'
566                p=subprocess.Popen([command],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
567                output=p.communicate()
568                self.thread_ret=p.returncode
569                self.flavour_error=output[1]
570               
571               
572                if self.thread_ret==0:
573                        self.response=1
574               
575        #def no_button_clicked 
576
577        def arrow_clicked(self,widget,event):
578                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
579                self.stack.set_visible_child_name("update")     
580               
581        #def arrow_clicked
582
583        def update_installed_icon(self):
584                image=Gtk.Image()
585                image.set_from_file(ERROR_ICON)         
586                icon=image.get_pixbuf()
587
588                for item in self.packages_store:
589                        item[3]=icon
590                       
591        #def update_installed_icon     
592
593        def quit(self,widget,event=None):
594               
595                Gtk.main_quit() 
596
597#class LliurexMirror
598
599at=LliurexUp()         
Note: See TracBrowser for help on using the repository browser.