source: zero-center/trunk/fuentes/install-files/usr/share/zero-center/zero-center.py @ 6596

Last change on this file since 6596 was 6596, checked in by hectorgh, 3 years ago

making sure there is at least 3 characters when filtering zmds using the search box

  • Property svn:executable set to *
File size: 34.1 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*
3 
4
5import os
6import multiprocessing
7import time
8import random
9import xmlrpclib
10import cairo
11import grp
12import sys
13import subprocess
14import json
15
16try:
17        import gi
18        gi.require_version('Gtk', '3.0')
19        gi.require_version('PangoCairo', '1.0')
20        from gi.repository import Gtk, Gdk, GObject, GLib, PangoCairo, Pango
21       
22except Exception as e:
23        print e
24        #zero-server-wizard initialization forces me to do this
25
26import signal
27signal.signal(signal.SIGINT, signal.SIG_DFL)
28
29import gettext
30gettext.textdomain('zero-center')
31_ = gettext.gettext
32
33
34BAR_HEIGHT=90
35CONF_X=5
36
37if os.path.exists("/home/lliurex/banners/"):
38        BANNER_PATH="/home/lliurex/banners/"
39else:
40        BANNER_PATH="/usr/share/banners/lliurex-neu/"
41       
42
43class CategoriesParser:
44       
45        CATEGORIES_PATH="/usr/share/zero-center/categories/"
46       
47        def __init__(self):
48               
49                self.parse_categories()
50               
51        #def init
52       
53        def parse_categories(self,path=None):
54               
55                self.categories=[]
56               
57                if path==None:
58                        path=self.CATEGORIES_PATH
59                       
60                for item in os.listdir(path):
61                        file_path=path+item
62                       
63                        f=open(file_path)
64                        lines=f.readlines()
65                        f.close()
66                       
67                        cat={}
68                       
69                        for line in lines:
70                                key,value=line.split("=")
71                                cat[key]=value.strip("\n")
72                                if key=="level":
73                                        cat[key]=int(cat[key])
74                       
75                        self.categories.append(cat)
76                       
77                tmp=[]
78               
79                while len(self.categories)>0:
80                        selected_index=0
81                        index=0
82                        level=0
83                        for item in self.categories:
84                                if item["level"]>level:
85                                        level=item["level"]
86                                        selected_index=index
87                                       
88                               
89                                index+=1
90                       
91                        tmp.append(self.categories[selected_index])
92                        self.categories.pop(selected_index)
93                       
94                self.categories=tmp
95               
96        #def parse_categories
97               
98               
99#class CategoriesParser
100
101
102class AppParser:
103       
104        BASE_DIR="/usr/share/zero-center/"
105        APP_PATH=BASE_DIR+"applications/"
106        ZMD_PATH=BASE_DIR+"zmds/"
107       
108       
109        def __init__(self):
110               
111                self.categories=["ID","Name","Comment","Icon","Category","Icon","ScriptPath","Groups","Service","Locks"]
112                self.apps={}
113                self.app_list=[]
114                self.configured=[]
115                #print("[ZeroCenter] Parsing apps...")
116                self.parse_all()
117               
118        #def init
119
120       
121        def add_app(self,app):
122               
123                try:
124                        if app["Category"].lower() not in self.apps:
125                                self.apps[app["Category"].lower()]=[]
126                       
127                        self.apps[app["Category"].lower()].append(app)
128                        self.app_list.append(app["ID"])
129                except:
130                        pass
131                       
132        #def add_app
133       
134        def parse_all(self,dir=None):
135               
136                if dir==None:
137                        dir=self.APP_PATH
138       
139                for item in os.listdir(dir):
140                        file_path=self.APP_PATH+item
141                        app=self.parse_file(file_path)
142                        self.add_app(app)
143                       
144        #def parse_all
145
146       
147        def parse_file(self,file_path):
148               
149                f=open(file_path)
150                lines=f.readlines()
151                f.close()
152                id=file_path.split("/")[-1].split(".")[0]
153                app={}
154                for item in lines:
155                        try:
156                                key,value=item.split("=")
157                                app[key]=value.strip("\n")
158                        except:
159                                pass
160               
161                app["ID"]=id
162                app["configured"]=-1
163                app["custom_msg"]=""
164               
165                app["bar_height"]=BAR_HEIGHT
166                app["conf_alpha"]=1.0
167
168               
169                app["expanding"]=False
170                app["restoring"]=False
171
172                return app
173               
174        #def parse_file
175
176       
177#class AppParser
178
179
180class ZeroCenter:
181       
182        def __init__(self):
183               
184                self.client=xmlrpclib.ServerProxy("https://localhost:9779")
185                self.create_user_env()
186                self.categories_parser=CategoriesParser()
187                self.app_parser=AppParser()
188                self.configured_apps=[]
189                self.get_states()
190               
191                self.mprocess=multiprocessing.Process()
192                self.commands=["set-configured","set-non-configured","set-failed","set-custom-text","add-zero-center-notification","remove-zero-center-notification","help","add-pulsating-color","remove-pulsating-color","non-animated","animated"]
193                self.drawing_mode=True
194                self.msg_text=""
195                self.msg_x=0
196                self.scrolling=False
197               
198                try:
199                        self.msg_text=self.client.get_zc_messages("","ZCenterVariables",self.lang)
200                        if self.msg_text=="":
201                                txt=self.client.lliurex_version("","LliurexVersion")
202                                if type(txt)==type([]):
203                                        self.msg_text=str(txt[1])
204                                else:
205                                        f=open("/etc/lsb-release")
206                                        lines=f.readlines()
207                                        f.close()
208                                        for line in lines:
209                                                if "DISTRIB_DESCRIPTION" in line:
210                                                        self.msg_text=line.split("=")[1]
211                        #Load slave_blacklist
212                        self.blacklist=self.client.get_variable("","VariablesManager","SLAVE_BLACKLIST")
213
214                except:
215                        self.msg_text=""
216               
217                #self.msg_text="hi, i'm a long enough text so that it won't show in just one line. I wonder how many lines I can get inside the box. In my restless dreams I see that town, Silent Hill. I don't know what to type, but I have to keep typing"
218                #57
219               
220        #def init
221
222       
223        def get_states(self):
224               
225                try:
226                        var=self.client.get_all_states("","ZCenterVariables")
227                except:
228                        local_path="/var/lib/n4d/variables-dir/ZEROCENTER"
229                        if os.path.exists(local_path):
230                                f=open(local_path)
231                                var=json.load(f)["ZEROCENTER"]["value"]
232                                f.close()
233                        else:
234                                var={}
235                               
236                try:
237                        for cat in self.app_parser.apps:
238                       
239                                for app in self.app_parser.apps[cat]:
240                                        app["configured"]=0
241                                       
242                                        if app["ID"] in var:
243                                                for key in ["state","pulsating","time","custom_text"]:
244                                                        if key in var[app["ID"]]:
245                                                                app[key]=var[app["ID"]][key]
246               
247                                                       
248                                        if "state" in app:
249                                                app["configured"]=app["state"]
250                               
251                                        if app["configured"]==1:
252                                                self.configured_apps.append(app["ID"])
253                               
254                               
255                except Exception as e:
256                        print e
257                        pass
258                       
259        #def get_states
260
261       
262        def get_translation(self,text):
263               
264                for category in self.categories_parser.categories:
265                       
266                        if text.lower()==category["name"].lower():
267                                for lang in self.language:
268                                        try:
269                                                return category["name["+lang+"]"]
270                                        except Exception as e:
271                                                pass
272                                return category["name"]
273               
274                return text
275               
276        #def get_translation
277
278       
279        def get_name(self,app):
280               
281                for lang in self.language:
282                        try:
283                                return app["Name["+lang+"]"]
284                        except:
285                                pass
286                               
287                return app["Name"]
288               
289        #def get_name
290
291       
292        def get_comment(self,app):
293               
294                for lang in self.language:
295                        try:
296                                return app["Comment["+lang+"]"]
297                        except:
298                                pass
299                               
300                return app["Comment"]
301               
302        #def get_name
303
304       
305        def create_user_env(self):
306               
307                try:
308                        self.lang=os.environ["LANGUAGE"].replace(".UTF-8","").split(":")[0]
309                        self.language=os.environ["LANGUAGE"].replace(".UTF-8","").split(":")
310                        if "es_ES" in self.language and "es" not in self.language:
311                                self.language.insert(self.language.index("es_ES")+1,"es")
312                        self.lang=self.lang.split("_")[0]
313                       
314                        if "ca_ES@valencia" in self.language:
315                                self.language.insert(self.language.index("ca_ES@valencia"),"qcv")
316                except:
317                        try:
318                                self.lang=os.environ["LANG"].replace(".UTF-8","")
319                                self.language=[]
320                                self.language.append(self.lang)
321                                self.lang=self.lang.split("_")[0]
322                               
323                        except:
324                                self.lang="en"
325
326                       
327                groups={}
328               
329                for item in grp.getgrall():
330                        if len(item.gr_mem)>0:
331                                if item.gr_name not in groups:
332                                        groups[item.gr_name]=item.gr_mem
333                                else:
334                                        groups[item.gr_name]=list(groups[item.gr_name]+item.gr_mem)
335                       
336               
337                self.user_groups=[]
338                try:
339                        for item in groups:
340                                if os.environ["USER"] in groups[item]:
341                                        self.user_groups.append(item)
342                                       
343                        self.user_groups.append("*")
344                except:
345                        pass
346               
347        #def create_user_area
348
349       
350        def start_gui(self):
351               
352               
353                self.icon_theme=Gtk.IconTheme()
354                self.icon_theme.set_custom_theme("lliurex-neu")
355               
356                builder=Gtk.Builder()
357                if os.path.exists("/srv/svn/pandora/zero-center2/install-files/usr/share/zero-center/rsrc/zero-center.glade"):
358                        builder.add_from_file("/srv/svn/pandora/zero-center2/install-files/usr/share/zero-center/rsrc/zero-center.glade")
359                else:
360                        builder.add_from_file("/usr/share/zero-center/rsrc/zero-center.glade")
361                self.window=builder.get_object("window1")
362                self.window.connect("delete_event",self.close_window)
363                self.window.set_name("BLACK")
364                self.buttons_vbox=builder.get_object("buttons_vbox")
365                self.content_hbox=builder.get_object("main_box")
366                self.content_hbox.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0.2,0.2,0.2,1))
367                self.window_box=builder.get_object("window_box")
368                self.viewport=builder.get_object("viewport1")
369                self.viewport.set_name("ORANGE")
370                self.category_combobox=builder.get_object("category_combobox")
371                self.msg_label=builder.get_object("llx_label")
372                self.msg_label.connect("draw",self.drawing_label_event)
373                self.msg_label.set_tooltip_text(self.msg_text)
374               
375                self.hidden_button=builder.get_object("button1")
376                self.hidden_button.grab_focus()
377               
378                self.search_entry=builder.get_object("entry")
379                self.search_entry.connect("changed",self.entry_changed)
380               
381                self.progress_bar=builder.get_object("progressbar")
382                self.progress_label=builder.get_object("progress_label")
383                self.progress_label.set_name("WHITE")
384               
385                self.add_categories_to_window("All")
386                self.set_css_info()
387               
388                self.window.show()
389                GObject.threads_init()
390                Gtk.main()
391               
392        #def start_gui
393       
394       
395        def entry_changed(self,widget):
396                self.add_categories_to_window("",False)
397       
398        def scroll_me(self,img):
399               
400                if self.msg_x > (self.scroll_width)*-1:
401                        self.msg_x-=1
402                else:
403                        self.msg_x=401
404                img.queue_draw()
405                return self.scrolling
406               
407        #def scroll_me
408
409
410        def set_msg_label_text(self,txt):
411       
412                self.msg_text=txt
413                self.msg_label.queue_draw()
414               
415        #def set_msg_label_text()
416
417       
418        def drawing_label_event(self,widget,ctx):
419               
420                lg1 = cairo.LinearGradient(0.0,18.0, 400.0, 18.0)
421                lg1.add_color_stop_rgba(0, 0.38, 0.38, 0.38, 1)
422                lg1.add_color_stop_rgba(0.1, 0.2, 0.2, 0.2, 1)
423                lg1.add_color_stop_rgba(0.9, 0.2, 0.2, 0.2, 1)
424                lg1.add_color_stop_rgba(1, 0.38, 0.38, 0.38, 1)
425                ctx.rectangle(0, 0, 400, 18)
426                ctx.set_source(lg1)
427                ctx.fill()
428
429                tmp_text=self.msg_text
430
431                if len(tmp_text)>66:
432                        if self.drawing_mode:
433                                if not self.scrolling:
434                                        self.scrolling=True
435                                        self.msg_x=200
436                                        GLib.timeout_add(12,self.scroll_me,widget)
437                        else:
438                                tmp_text=tmp_text[:63]
439                                tmp_text="      " + tmp_text+u" …"
440                else:
441                        self.scrolling=False
442                        spaces=90-len(tmp_text)
443                        space="".join([" "]*(spaces/2))
444                        tmp_text=space+tmp_text+space
445                       
446               
447               
448                tmp_text=tmp_text.replace("[","<b>[")
449                tmp_text=tmp_text.replace("]","] </b>")
450               
451                x=self.msg_x
452                pctx = PangoCairo.create_layout(ctx)
453                desc = Pango.font_description_from_string ("Ubuntu 9")
454                pctx.set_font_description(desc)
455                ctx.set_source_rgb(0.9,0.9,0.9)
456                pctx.set_markup(tmp_text)
457                self.scroll_width=pctx.get_pixel_size()[0]
458                ctx.move_to(x,0)
459                PangoCairo.show_layout(ctx, pctx)
460               
461        #def set_msg_label
462       
463       
464        def set_css_info(self):
465               
466                css = """
467               
468                #BLACK {
469                        background-image: -gtk-gradient (linear,        left top, left bottom, from (#1a1a1a),  to (#616161));
470                       
471                }
472
473                #ORANGE {
474                        background-image: -gtk-gradient (linear,        left top, left bottom, from (#575757),  to (#373737));
475                       
476                }
477               
478                #BLACKEXPANDER {
479                        background-image: -gtk-gradient (linear,        left top, left bottom, from (#1a1a1a),  to (#1a1a1a));
480                        color: white;
481                        box-shadow: 50px 50px;
482                       
483                }
484               
485                #WHITE {
486                        color: white;
487                        text-shadow: 0px 1px black;
488                }               
489               
490                #WHITE-15 {
491                        color: white;
492                        font-size: 15px;
493                        text-shadow: 1px 2px black;
494                }
495
496               
497                #BLACKBUTTON{
498                        background-image: -gtk-gradient (linear,        left top, left bottom, from (#2a2a2a),  to (#616161));
499                        color: #e0e0e0;
500                        border-color: #000;
501                        border-style: none;
502                        border-radius: 10px;
503                       
504                }
505               
506               
507               
508                #APPBUTTON{
509
510                        padding: 0px 0px;
511                        border:none;
512                        background-image: none;
513                        box-shadow: none;
514                        background-color: transparent;
515                        box-shadow: 0px 2px 5px rgba(0,0,0,0.8);
516
517                }
518
519                #APPBUTTON:hover{
520
521                       
522                        border-width: 0;
523                        border-radius: 0px;
524                        border-color: transparent;
525                        border: none;   
526                        box-shadow: 0px 1px 8px rgba(0,0,0,1);
527                }
528               
529                GtkSeparator {
530                        color: rgba(255,255,255,0.8);
531                }
532               
533                """
534               
535                self.style_provider=Gtk.CssProvider()
536                self.style_provider.load_from_data(css)
537               
538                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
539               
540        #def set_css_info       
541       
542       
543        def get_banner_image(self,app):
544
545                package_rsrc_path=BANNER_PATH
546                img_path=package_rsrc_path+"package.png"
547               
548                for item in os.listdir(package_rsrc_path):
549                        f,ext=item.split(".")
550                        if app["Icon"] == f:
551                                img_path=package_rsrc_path+item
552               
553               
554                img=cairo.ImageSurface.create_from_png(img_path)
555                ctx=cairo.Context(img)
556
557                if not self.check_app_dependences(app):
558                        ctx.set_source_rgba(0.5,0.5,0.5,0.7)
559                        ctx.rectangle(0,0,235,110)
560                        ctx.fill()
561               
562
563                ctx.set_source_rgba(0,0,0,0.8)
564                ctx.rectangle(0,90,235,110)
565                ctx.fill()
566
567
568                show_status=True
569                if "Depends" in app:
570
571                        if not self.check_app_dependences(app):
572                               
573                                lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
574                                lg1.add_color_stop_rgba(0, 0.7, 0, 0, 1)
575                                lg1.add_color_stop_rgba(1, 1, 0.2, 0.2, 0)
576                                ctx.rectangle(0, 0, 200, 20)
577                                ctx.set_source(lg1)
578                                ctx.fill()
579                                                                                       
580                                ctx.select_font_face("Ubuntu")
581                                ctx.set_font_size(15)
582                                ctx.move_to(5,15)
583                                ctx.set_source_rgba(1,1,1,app["conf_alpha"])
584                                                                                       
585                                ctx.show_text(_("Unmet dependences"))
586                                ctx.stroke()
587                               
588                                show_status=False
589
590
591                if "Service" in app and show_status:
592
593                        if app["Service"].lower()=="true":
594
595                                if app["configured"]==1:
596
597                                        lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
598                                                               
599                                        lg1.add_color_stop_rgba(0, 0, 0.2, 0, 1)
600                                        lg1.add_color_stop_rgba(1, 0, 1, 0, 0)
601                                        ctx.rectangle(0, 0, 200, 20)
602                                        ctx.set_source(lg1)
603                                        ctx.fill()
604                                                       
605                                        ctx.select_font_face("Ubuntu")
606                                        ctx.set_font_size(15)
607                                        ctx.move_to(5,15)
608                                        ctx.set_source_rgb(1,1,1)
609                                                       
610                                        ctx.show_text(_("Configured"))
611                                        ctx.stroke()
612
613
614                                elif app["configured"]==0:
615
616                                        lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
617                                                               
618                                        lg1.add_color_stop_rgba(0, 0.7, 0, 0, 1)
619                                        lg1.add_color_stop_rgba(1, 1, 0.2, 0.2, 0)
620                                        ctx.rectangle(0, 0, 200, 20)
621                                        ctx.set_source(lg1)
622                                        ctx.fill()
623                                                       
624                                        ctx.select_font_face("Ubuntu")
625                                        ctx.set_font_size(15)
626                                        ctx.move_to(5,15)
627                                        ctx.set_source_rgb(1,1,1)
628                                                       
629                                        ctx.show_text(_("Not configured"))
630                                        ctx.stroke()
631                                       
632                                else:
633                                        lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
634                                        lg1.add_color_stop_rgba(0, 1, 0, 0, 1)
635                                        lg1.add_color_stop_rgba(1, 1, 0.2, 0.2, 0)
636                                        ctx.rectangle(0, 0, 200, 20)
637                                        ctx.set_source(lg1)
638                                        ctx.fill()
639                                                               
640                                        ctx.select_font_face("Ubuntu")
641                                        ctx.set_font_size(15)
642                                        ctx.move_to(5,15)
643                                        ctx.set_source_rgba(1,1,1,app["conf_alpha"])
644                                                               
645                                        ctx.show_text(_("Failed"))
646                                        ctx.stroke()
647
648                ctx.select_font_face("Ubuntu")
649                ctx.set_font_size(15)
650                ctx.move_to(5,105)
651                ctx.set_source_rgb(1,1,1)
652                txt=""
653                fix=True
654               
655                text=self.get_name(app)
656               
657               
658                for char in range(30):
659                        try:
660                                txt+=text[char]
661                        except:
662                                fix=False
663                                break
664                                                       
665                if fix:
666                        txt+="…"
667               
668                ctx.show_text(txt)
669                ctx.stroke()
670
671                #img.write_to_png(self.user_rsrc_path+item)
672                image=Gtk.Image()
673                #image.set_from_file(self.user_rsrc_path+item)
674                image.set_from_pixbuf(Gdk.pixbuf_get_from_surface(img,0,0,235,110))
675                image.set_name("BIMAGE")
676                return image
677               
678        #def get_image
679
680       
681        def drawing_banner_event(self,widget,ctx,app):
682               
683                package_rsrc_path=BANNER_PATH
684                img_path=package_rsrc_path+"package.png"
685                for item in os.listdir(package_rsrc_path):
686                        f,ext=item.split(".")
687                        if app["Icon"] == f:
688                                img_path=package_rsrc_path+item
689               
690       
691                img=cairo.ImageSurface.create_from_png(img_path)
692                ctx.set_source_surface(img,0,0)
693               
694                if not self.check_app_dependences(app):
695                        ctx.paint_with_alpha(0.2)
696                        ctx.set_source_rgba(0.5,0.5,0.5,0.7)
697                        ctx.rectangle(0,0,235,110)
698                        ctx.fill()
699                else:
700                        ctx.paint()
701
702
703                if "pulsating" in app and app["pulsating"]:
704                       
705                        '''
706                        if app["pulsating"]:
707                                ctx.set_source_rgba(1,1,1,app["pulsating_alpha"])
708                                ctx.rectangle(0,0,235,110)
709                                ctx.fill()             
710                        '''
711                       
712                        app.setdefault("pulsating_alpha",0.0)
713       
714                        lg1 = cairo.LinearGradient(0.0,10.0, 235.0, 10.0)
715                        lg1.add_color_stop_rgba(0, 0, 0.0, 0.8, 0.7)
716                        lg1.add_color_stop_rgba(app["pulsating_alpha"], 0.1, 0.7, 0.9, 1)
717                        lg1.add_color_stop_rgba(1, 0, 0, 0.8, 0.5)
718                        ctx.rectangle(0,app["bar_height"],235,20)
719                        ctx.set_source(lg1)
720                        ctx.fill()
721                        ctx.set_source_rgba(0,0,0,0.8)
722                        ctx.rectangle(0,app["bar_height"]+20,235,110)
723                        ctx.fill()                     
724                       
725                else:
726                       
727                        ctx.set_source_rgba(0,0,0,0.7)
728                        ctx.rectangle(0,app["bar_height"],235,110)
729                        ctx.fill()
730               
731                show_status=True
732                if "Depends" in app:
733
734                        if not self.check_app_dependences(app):
735                               
736                                lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
737                                lg1.add_color_stop_rgba(0, 0.7, 0, 0, 1)
738                                lg1.add_color_stop_rgba(1, 1, 0.2, 0.2, 0)
739                                ctx.rectangle(0, 0, 200, 20)
740                                ctx.set_source(lg1)
741                                ctx.fill()
742                                                                                       
743                                ctx.select_font_face("Ubuntu")
744                                ctx.set_font_size(15)
745                               
746                                ctx.move_to(6,16)
747                                ctx.set_source_rgba(0,0,0,app["conf_alpha"])
748                                ctx.show_text(_("Unmet dependences"))
749                                ctx.stroke()
750                               
751                               
752                                ctx.move_to(5,15)
753                                ctx.set_source_rgba(1,1,1,app["conf_alpha"])
754                                ctx.show_text(_("Unmet dependences"))
755                                ctx.stroke()
756                               
757                                show_status=False
758
759                if "Service" in app and show_status:
760                       
761                        if app["Service"].lower()=="true":
762
763                                if app["configured"]==1:
764
765                                        lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
766                                        lg1.add_color_stop_rgba(0, 0, 0.2, 0, 1)
767                                        lg1.add_color_stop_rgba(1, 0, 1, 0, 0)
768                                        ctx.rectangle(0, 0, 200, 20)
769                                        ctx.set_source(lg1)
770                                        ctx.fill()
771                                                       
772                                        ctx.select_font_face("Ubuntu")
773                                        ctx.set_font_size(15)
774                                       
775                                        ctx.set_source_rgba(0,0,0,app["conf_alpha"])
776                                        ctx.move_to(6,16)               
777                                        ctx.show_text(_("Configured"))
778                                        ctx.stroke()
779                                       
780                                       
781                                        ctx.set_source_rgba(1,1,1,app["conf_alpha"])
782                                        ctx.move_to(5,15)               
783                                        ctx.show_text(_("Configured"))
784                                        ctx.stroke()
785                                                       
786                                elif app["configured"]==-1:
787
788                                        lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
789                                        lg1.add_color_stop_rgba(0, 0.7, 0, 0, 1)
790                                        lg1.add_color_stop_rgba(1, 1, 0.2, 0.2, 0)
791                                        ctx.rectangle(0, 0, 200, 20)
792                                        ctx.set_source(lg1)
793                                        ctx.fill()
794                                                       
795                                        ctx.select_font_face("Ubuntu")
796                                        ctx.set_font_size(15)
797                                       
798                                        ctx.set_source_rgba(0,0,0,app["conf_alpha"])
799                                        ctx.move_to(6,16)               
800                                        ctx.show_text(_("Failed"))
801                                        ctx.stroke()
802                                       
803                                       
804                                        ctx.move_to(5,15)
805                                        ctx.set_source_rgba(1,1,1,app["conf_alpha"])
806                                        ctx.show_text(_("Failed"))
807                                        ctx.stroke()
808                                       
809                                else:
810                                       
811                                        lg1 = cairo.LinearGradient(0.0,110.0, 200.0, 110.0)
812                                        lg1.add_color_stop_rgba(0, 0.8, 0, 0, 1)
813                                        lg1.add_color_stop_rgba(1, 1, 0.2, 0.2, 0)
814                                        ctx.rectangle(0, 0, 200, 20)
815                                        ctx.set_source(lg1)
816                                        ctx.fill()
817
818                                        ctx.select_font_face("Ubuntu")
819                                        ctx.set_font_size(15)
820                                       
821                                        ctx.set_source_rgba(0,0,0,app["conf_alpha"])
822                                        ctx.move_to(6,16)               
823                                        ctx.show_text(_("Not configured"))
824                                        ctx.stroke()                                   
825                                       
826                                        ctx.move_to(5,15)
827                                        ctx.set_source_rgba(1,1,1,app["conf_alpha"])
828                                        ctx.show_text(_("Not configured"))
829                                        ctx.stroke()                                   
830
831
832                txt=""
833                fix=True
834                for char in range(30):
835                        try:
836                                txt+=self.get_name(app)[char]
837                        except:
838                                fix=False
839                                break
840                                                       
841                if fix:
842                        txt+="…"
843
844
845                ctx.select_font_face("Ubuntu")
846                ctx.set_font_size(15)
847               
848                ctx.move_to(6,app["bar_height"]+16)
849                ctx.set_source_rgb(0,0,0)
850                ctx.show_text(txt)
851                ctx.stroke()           
852               
853                ctx.move_to(5,app["bar_height"]+15)
854                ctx.set_source_rgb(0.9,0.9,0.9)
855                ctx.show_text(txt)
856                ctx.stroke()           
857
858               
859               
860               
861                y=app["bar_height"]+30
862                pctx = PangoCairo.create_layout(ctx)
863                desc = Pango.font_description_from_string ("Ubuntu 8")
864                pctx.set_font_description(desc)
865                pctx.set_alignment(Pango.Alignment.LEFT)
866                pctx.set_justify(True)
867                pctx.set_width(225000)
868                pctx.set_height(10)
869                ctx.set_source_rgb(1,1,0.8)
870                pctx.set_text(self.get_comment(app),-1)
871               
872
873                ctx.move_to(6,y)
874                PangoCairo.show_layout (ctx, pctx)
875               
876                if "custom_text" in app:
877                       
878                        ctx.set_source_rgb(0.5,0.5,1)
879                        pctx.set_text(app["custom_text"],-1)
880                        ctx.move_to(6,y+60)
881                        PangoCairo.show_layout (ctx, pctx)
882                       
883               
884        #def drawing_event
885       
886
887        def mouse_over(self,widget,event,app,img):
888               
889                if not app["expanding"]:
890                        app["restoring"]=False
891                        app["expanding"]=True
892                        GLib.timeout_add(10,self.expand_black_area,app,img)
893               
894        #def mouse_over
895
896       
897        def mouse_left(self,widget,event,app,img):
898               
899                if not app["restoring"]:
900                        app["expanding"]=False
901                        app["restoring"]=True
902                        GLib.timeout_add(10,self.restore_black_area,app,img)
903               
904        #def mouse_left
905
906       
907        def expand_black_area(self,app,img):
908               
909                while app["bar_height"]>0 and app["expanding"]:
910                        app["bar_height"]-=2
911                        if app["conf_alpha"]>0.0:
912                                app["conf_alpha"]-=0.025
913                        img.queue_draw()
914                        return True
915                       
916                if not app["expanding"]:
917                        return False
918                       
919                app["expanding"]=False
920                app["conf_alpha"]=0.0
921                img.queue_draw()
922                return False
923               
924        #def expand_black_area
925       
926       
927        def restore_black_area(self,app,img):
928               
929                while app["bar_height"]<BAR_HEIGHT and app["restoring"]:
930                        app["bar_height"]+=2
931                        if app["conf_alpha"]<1.0:
932                                app["conf_alpha"]+=0.025
933                        img.queue_draw()
934                        return True
935                       
936                if not app["restoring"]:
937                        return False
938                       
939                app["restoring"]=False
940                app["conf_alpha"]=1.0
941                img.queue_draw()
942                return False
943               
944        #def restore_black_area
945       
946       
947        def check_app_groups(self,app,verbose=True):
948               
949                if verbose:
950                        sys.stdout.write(" * Checking " + app["ID"] + " ... ")
951                groups=[]
952                if "Groups" not in app:
953                        if verbose:
954                                print("OK")
955                        return True
956               
957                try:
958                       
959                        if os.environ["USER"]=="root":
960                                if verbose:
961                                        print("OK")
962                                return True
963                       
964                        groups=app["Groups"].strip("\n").split(";")
965                        for group in groups:
966                                if group in self.user_groups:
967                                        if verbose:
968                                                print("OK")             
969                                        return True
970                       
971                except Exception as e:
972                        print e
973                        pass
974                       
975                if verbose:
976                        print "NOT ALLOWED"
977                        print "\t[!] App groups: ",sorted(groups)
978                return False
979               
980        #def check_app_groups
981
982       
983        def add_pulsating(self,app,image):
984               
985                GLib.timeout_add(70,self.pulsate_color,app,image)
986               
987        #def add_pulsating
988
989
990        def pulsate_color(self,app,image):
991               
992                app["pulsating_alpha"]+=app["pulsating_increment"]
993               
994                if app["pulsating_alpha"] >= 1.0 :
995                       
996                        app["pulsating_increment"]=-0.02
997                       
998                if app["pulsating_alpha"] <= 0.0 :
999                       
1000                        app["pulsating_increment"]=0.02
1001                       
1002                image.queue_draw()
1003                return app["pulsating"]
1004               
1005        #def pulsate_color
1006               
1007               
1008        def check_app_dependences(self,app):
1009               
1010                if "Depends" in app:
1011                        depends=app["Depends"].split(";")
1012                        for dep in depends:
1013                               
1014                                if dep not in self.configured_apps:
1015                                        return False
1016                               
1017                return True
1018               
1019        #def check_app_dependences
1020
1021       
1022        def add_categories_to_window(self,category,verbose=True):
1023               
1024                for child in self.content_hbox.get_children():
1025                        self.content_hbox.remove(child)
1026               
1027                for category in self.categories_parser.categories:
1028                       
1029                        icon=category["icon"]
1030                        category=category["name"].lower()
1031                       
1032                        once=True
1033                        hbox=Gtk.HBox()
1034                        hbox.set_margin_left(10)
1035                        hbox.set_margin_right(10)
1036                        count=0
1037                        if category in self.app_parser.apps:
1038                                for app in sorted(self.app_parser.apps[category]):
1039                                       
1040                                        if self.check_app_groups(app,verbose):
1041
1042                                                search_txt=self.search_entry.get_text().lower().strip()
1043
1044                                                if search_txt not in app["ID"] and search_txt not in self.get_translation(app["Category"]).lower() and search_txt not in self.get_name(app).lower() and len(search_txt)>2:
1045                                                        continue
1046                                                button=Gtk.Button()
1047                                                button.set_name("APPBUTTON")
1048                                                button.set_size_request(235,110)
1049                                               
1050                                                if not self.drawing_mode:
1051                                                        image=self.get_banner_image(app)
1052                                                else:
1053                                                        image=Gtk.DrawingArea()
1054                                                        image.show()
1055                                                        image.connect("draw",self.drawing_banner_event,app)
1056                                                       
1057                                                        if "pulsating" in app:
1058                                                                if app["pulsating"]:
1059                                                                        app["pulsating_alpha"]=0.0
1060                                                                        app["pulsating_increment"]=0.02
1061                                                                        self.add_pulsating(app,image)
1062                                                       
1063                                                       
1064                                                        button.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK)
1065                                                        button.connect("motion-notify-event",self.mouse_over,app,image)
1066                                                        button.connect("leave_notify_event",self.mouse_left,app,image)
1067                                                        #button.set_size_request(245,120)
1068                                               
1069                                                button.add(image)
1070                                                if "Name["+self.lang+"]" in app:
1071                                                        button.set_tooltip_text(app["Name["+self.lang+"]"])
1072                                                else:
1073                                                        button.set_tooltip_text(app["Name"])
1074                                                button.connect("clicked",self.app_clicked,app)
1075                                                app["gtk_button"]=button
1076                                                hbox.pack_start(button,True,False,0)
1077                                                count+=1
1078                                                if count==3:
1079                                                        hbox.show_all()
1080                                                        if once:
1081                                                                self.add_label(self.get_translation(category),icon)
1082                                                                once=False
1083                                                        self.content_hbox.pack_start(hbox,False,False,10)
1084                                                        count=0
1085                                                        hbox=Gtk.HBox()
1086                                                        hbox.set_margin_left(10)
1087                                                        hbox.set_margin_right(10)
1088                                               
1089                        if count!=0:
1090                                hbox.show_all()
1091                                if once:
1092                                        self.add_label(self.get_translation(category),icon)
1093                                        once=False
1094                                hbox.set_halign(Gtk.Align.START)
1095                                hbox.set_margin_left(20)
1096                                children=hbox.get_children()
1097                                if len(children)>1:
1098                                        for child in children[1:]:
1099                                                child.set_margin_left(20)
1100                                self.content_hbox.pack_start(hbox,False,False,5)
1101               
1102                if len(self.content_hbox.get_children()) > 0:
1103                        self.content_hbox.get_children()[-1].set_margin_bottom(10)
1104               
1105        #def add_categories_to_window
1106       
1107       
1108       
1109       
1110        def add_label(self,label_name,icon_name=None):
1111               
1112                if icon_name==None:
1113                        icon_name="system"
1114                       
1115                tmpbox=Gtk.HBox()
1116                img=Gtk.Image()
1117                img.set_from_icon_name(icon_name,Gtk.IconSize.MENU)
1118                label=Gtk.Label(label_name)
1119                label.set_name("WHITE-15")
1120                expander=Gtk.HSeparator()
1121                expander.set_margin_right(15)
1122                tmpbox.set_margin_left(10)
1123                tmpbox.set_margin_top(5)
1124                tmpbox.pack_start(img,False,False,0)
1125                tmpbox.pack_start(label,False,False,10)
1126                tmpbox.pack_start(expander,True,True,5)
1127                tmpbox.show_all()
1128                self.content_hbox.pack_start(tmpbox,False,False,5)             
1129               
1130        #def add_label
1131       
1132       
1133        def app_clicked(self,widget,app):
1134       
1135                if  self.client.get_variable("","VariablesManager","MASTER_SERVER_IP"):
1136                        if app["ID"] in self.blacklist:
1137                                result = self.open_dialog("Warning",_("We are in a center model and therefore should install this service on the master \n server to be accessible from any computer in the center, whether to continue \n with the installation on this computer the service is only available on computers \n that are in the internal network of this server."),True)
1138                                if result == Gtk.ResponseType.CANCEL:
1139                                        return -1
1140
1141                if app["ID"] in self.configured_apps:
1142                        ret=self.open_dialog("Warning",_("<b>%s</b> is already configured. Do you want to execute it again?")%self.get_name(app),True)
1143                        if ret==Gtk.ResponseType.CANCEL:
1144                                return -1
1145               
1146                if self.check_app_dependences(app):
1147               
1148                        cmd=""
1149                               
1150                        if "Using" in app:
1151                                cmd+=app["Using"].strip(" ").strip("\n") +" "
1152                                       
1153                        cmd+=self.app_parser.ZMD_PATH + app["ScriptPath"]
1154                       
1155                        gt=False
1156                        if "Gnome-terminal" in app:
1157                                if app["Gnome-terminal"].lower()=="true":
1158                                        cmd='gnome-terminal --command="'+cmd+'"'
1159                                        gt=True
1160                                       
1161                        if not gt:
1162                                if "gnome-terminal" in app:
1163                                        if app["gnome-terminal"].lower()=="true":
1164                                                cmd='gnome-terminal --command="'+cmd+'"'
1165                               
1166                               
1167                       
1168                        blocked=False
1169                        print(' * Executing "' + cmd + '" ...')
1170                        if "Modal" in app:
1171                                if app["Modal"].lower()=="true" and not self.mprocess.is_alive():
1172                                        GLib.timeout_add(250,self.pulse_progress)
1173                                        self.progress_bar.show()
1174                                       
1175                                        try:
1176                                                txt="Executing %s"%app["Name["+self.lang+"]"]
1177                                        except:
1178                                                txt="Executing %s"%app["Name"]
1179                                        self.progress_label.set_text(txt)
1180                                        self.progress_label.show()
1181                                        self.mprocess_app_name=app["Name"]
1182                                        blocked=True
1183                                else:
1184                                        self.open_dialog("Warning","<b>%s</b> is being executed. Please wait until it finishes."%self.mprocess_app_name )
1185                                        return -1
1186               
1187                        self.execute(cmd,blocked,app,widget)
1188                       
1189                else:
1190                       
1191                        self.open_dialog("Warning","<b>%s</b> dependences have not been configured."%self.get_name(app) +"\n[ %s ]"%app["Depends"])
1192               
1193        #def app_clicked
1194       
1195       
1196        def check_output(self,process,app,button):
1197               
1198                if not process.is_alive():
1199                       
1200                        print "[ZeroCenter] %s has ended"%app["ID"]
1201                       
1202                        if "Service" in app:
1203                                if app["Service"].lower()=="true":
1204                                       
1205                                        try:
1206                                                self.get_states()
1207                       
1208                                                for cat in self.app_parser.apps:
1209                                                        for item in self.app_parser.apps[cat]:
1210                                                                item["gtk_button"].get_child().queue_draw()
1211                                               
1212                                                darea=button.get_child()
1213                                                darea.queue_draw()
1214                                               
1215                                        except Exception as e:
1216                                                pass
1217                                       
1218                return process.is_alive()
1219               
1220        #def check_output
1221       
1222       
1223        def pulse_progress(self):
1224               
1225                self.progress_bar.pulse()
1226                if not self.mprocess.is_alive():
1227                        self.progress_bar.hide()
1228                        self.progress_label.hide()
1229                return self.mprocess.is_alive()
1230
1231        #def pulse_progress
1232
1233       
1234        def execute(self,cmd,blocked=False,app=None,widget=None):
1235               
1236                if not blocked:
1237                        p=multiprocessing.Process(target=self._execute,args=(cmd,))
1238                        #p.daemon=True
1239                        GLib.timeout_add(1000,self.check_output,p,app,widget)
1240                        p.start()
1241                       
1242                if blocked:
1243                       
1244                        if not self.mprocess.is_alive():
1245                                self.mprocess=multiprocessing.Process(target=self._execute,args=(cmd,))
1246                                #self.mprocess.daemon=True
1247                                self.mprocess.start()
1248                                GLib.timeout_add(1000,self.check_output,self.mprocess,app,widget)
1249                        else:
1250                                self.open_dialog("Warning",_("<b>%s</b> is being executed. Please wait until it finishes.")%self.mprocess_app_name )
1251               
1252        #def execute
1253
1254
1255        def _execute(self,cmd):
1256               
1257               
1258                subprocess.call(cmd,shell=True,preexec_fn=lambda: signal.signal(signal.SIGPIPE,signal.SIG_DFL))
1259               
1260                #os.system(cmd)
1261               
1262        #def _execute
1263
1264       
1265        def close_window(self,widget,data):
1266               
1267                if self.mprocess.is_alive():
1268                        ret=self.open_dialog("Warning",_("<b>%s</b> is being executed. Are you sure you want to exit?")%self.mprocess_app_name ,True)
1269               
1270                        if ret==Gtk.ResponseType.CANCEL:
1271                                return -1
1272                               
1273                        self.mprocess.terminate()
1274                        self.mprocess=multiprocessing.Process()
1275               
1276                Gtk.main_quit()
1277                print("")
1278               
1279        #def close_window
1280
1281               
1282        def open_dialog(self,title,text,show_cancel=False):
1283
1284                label = Gtk.Label()
1285                label.set_markup(text)
1286                if show_cancel:
1287                        dialog = Gtk.Dialog(title, None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, (Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT,Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL))
1288                else:
1289                        dialog = Gtk.Dialog(title, None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, (Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
1290                hbox = Gtk.HBox()
1291                img=Gtk.Image.new_from_icon_name("emblem-important",Gtk.IconSize.DIALOG)
1292                hbox.pack_start(img,True,True,5)
1293                hbox.pack_start(label,True,True,10)
1294                hbox.show_all()
1295                dialog.vbox.pack_start(hbox,True,True,10)
1296                dialog.set_border_width(6)
1297                response = dialog.run()
1298                dialog.destroy()
1299                return response
1300               
1301        #def open_dialog
1302
1303       
1304        def get_state(self,app):
1305
1306                try:
1307                        configured=self.client.get_state("","ZCenterVariables",app["ID"])
1308                        return configured
1309                except:
1310                        return 0
1311               
1312        #def get_state
1313
1314       
1315        def set_configured(self,app,key):
1316               
1317                if app in self.app_parser.app_list:
1318                       
1319                        try:
1320                                self.client.set_configured(key,"ZCenterVariables",app)
1321                        except Exception as e:
1322                                print e
1323                               
1324                else:
1325                        print("[!] %s is not installed"%app)
1326               
1327                sys.exit(0)
1328                               
1329        #def set_configured
1330
1331       
1332        def set_non_configured(self,app,key):
1333               
1334                if app in self.app_parser.app_list:
1335                       
1336                        try:
1337                                self.client.set_non_configured(key,"ZCenterVariables",app)
1338                        except:
1339                                pass
1340                               
1341                else:
1342                        print("\t[!] %s is not installed"%app)
1343               
1344                sys.exit(0)
1345               
1346        #def set_non_configured
1347       
1348        def set_failed(self,app,key):
1349               
1350                if app in self.app_parser.app_list:
1351                       
1352                        try:
1353                                self.client.set_failed(key,"ZCenterVariables",app)
1354                        except:
1355                                pass
1356                               
1357                else:
1358                        print("\t[!] %s is not installed"%app)
1359               
1360                sys.exit(0)
1361               
1362        #def set_non_configured
1363
1364       
1365        def set_custom_text(self,app,text,key):
1366               
1367                if app in self.app_parser.app_list:
1368                       
1369                        try:
1370                                self.client.set_custom_text(key,"ZCenterVariables",app,text)
1371                        except:
1372                                pass
1373                               
1374                else:
1375                        print("\t[!] %s is not installed"%app)
1376               
1377                sys.exit(0)
1378               
1379        #def set_custom_text
1380
1381       
1382        def add_pulsating_color(self,key,app):
1383               
1384                try:
1385                        self.client.add_pulsating_color(key,"ZCenterVariables",app)
1386                except:
1387                        pass
1388                       
1389                sys.exit(0)
1390               
1391        #def add_pulsating_color
1392
1393       
1394        def remove_pulsating_color(self,key,app):
1395               
1396                try:
1397                        self.client.remove_pulsating_color(key,"ZCenterVariables",app)
1398                except:
1399                        pass
1400               
1401                sys.exit(0)
1402               
1403        #def add_pulsating_color
1404
1405       
1406        def add_zc_notification(self,key,app,text,text_es="",text_qcv=""):
1407               
1408                try:
1409                        self.client.set_zc_message(key,"ZCenterVariables",app,text,text_es,text_qcv)
1410                except Exception as e:
1411                        print e
1412                       
1413                sys.exit(0)
1414               
1415        #def add_zc_notification
1416
1417       
1418        def remove_zc_notification(self,key,app):
1419               
1420                try:
1421                        self.client.remove_zc_message(key,"ZCenterVariables",app)
1422                except Exception as e:
1423                        print e
1424                       
1425                sys.exit(0)
1426               
1427        #def remove_zc_notification
1428
1429
1430        def usage(self):
1431               
1432                print("USAGE:")
1433                print("\tzero-center [ OPTION [ APP ] ]")
1434                print("Options:")
1435                print("\tset-configured APP") 
1436                print("\tset-non-configured APP") 
1437                print("\tset-custom-text APP TEXT") 
1438                print("\tadd-zero-center-notification APP TEXT_EN [TEXT_ES TEXT_QCV]") 
1439                print("\tremove-zero-center-notification APP") 
1440                print("\tadd-pulsating-color APP") 
1441                print("\tremove-pulsating-color APP") 
1442                print("\tnon-animated")
1443                print("\tanimated")
1444                print("\thelp")
1445                print("")
1446                sys.exit(0)
1447               
1448        #def usage
1449       
1450
1451def check_root():
1452        try:
1453                f=open("/etc/n4d/key","r")
1454                key=f.readline().strip("\n")
1455                f.close()
1456                return key
1457        except:
1458                print("[!] You need root privileges to execute this option [!]")
1459                sys.exit(1)
1460
1461if __name__=="__main__":
1462       
1463
1464        zc=ZeroCenter()
1465        zc.drawing_mode=True
1466
1467        if len(sys.argv)>=2:
1468               
1469                if sys.argv[1] not in zc.commands:
1470                        zc.usage()
1471                        sys.exit(1)
1472                       
1473                if sys.argv[1] == "help":
1474                        zc.usage()
1475                       
1476                if sys.argv[1] == "set-configured":
1477                        key=check_root()
1478                        zc.set_configured(sys.argv[2],key)
1479                       
1480                if sys.argv[1] == "set-non-configured":
1481                        key=check_root()
1482                        zc.set_non_configured(sys.argv[2],key)
1483                       
1484                if sys.argv[1] == "set-failed":
1485                        key=check_root()
1486                        zc.set_failed(sys.argv[2],key)
1487                       
1488                if sys.argv[1] == "set-custom-text":
1489                        key=check_root()
1490                        zc.set_custom_text(sys.argv[2],sys.argv[3],key)
1491                       
1492                if sys.argv[1] == "add-zero-center-notification":
1493                        key=check_root()
1494                       
1495                        try:
1496                                app=sys.argv[2]
1497                        except:
1498                                zc.usage()
1499                        try:
1500                                text=sys.argv[3]
1501                        except:
1502                                zc.usage()
1503                        try:
1504                                text_es=sys.argv[4]
1505                        except Exception as e:
1506                                print e
1507                                text_es=""
1508                        try:
1509                                text_qcv=sys.argv[5]
1510                        except Exception as e:
1511                                print e
1512                                text_qcv=""
1513                       
1514                        zc.add_zc_notification(key,app,text,text_es,text_qcv)
1515                       
1516                if sys.argv[1] == "remove-zero-center-notification":
1517                       
1518                        key=check_root()
1519                       
1520                        try:
1521                                app=sys.argv[2]
1522                        except:
1523                                zc.usage()
1524                               
1525                        zc.remove_zc_notification(key,app)
1526                       
1527                if sys.argv[1] == "add-pulsating-color":
1528                        key=check_root()
1529                        try:
1530                                app=sys.argv[2]
1531                        except:
1532                                zc.usage()
1533                               
1534                        zc.add_pulsating_color(key,app)
1535                               
1536                if sys.argv[1] == "remove-pulsating-color":
1537                        key=check_root()
1538                       
1539                        try:
1540                                app=sys.argv[2]
1541                        except:
1542                                zc.usage()
1543                               
1544                        zc.remove_pulsating_color(key,app)
1545                       
1546
1547                if sys.argv[1]=="animated":
1548                        zc.drawing_mode=True
1549                       
1550                if sys.argv[1]=="non-animated":
1551                        zc.drawing_mode=False
1552               
1553       
1554       
1555        zc.start_gui()
1556
Note: See TracBrowser for help on using the repository browser.