source: repoman/trunk/fuentes/src/repoman.py @ 7918

Last change on this file since 7918 was 7918, checked in by Juanma, 16 months ago

Add missing images

  • Property svn:executable set to *
File size: 21.7 KB
Line 
1#! /usr/bin/python3
2# -*- coding: utf-8 -*-
3
4import os
5import gi
6gi.require_version('Gtk', '3.0')
7from gi.repository import Gtk,Gdk,GdkPixbuf,GObject,GLib
8gi.require_version('PangoCairo', '1.0')
9import json
10from edupals.ui.n4dgtklogin import *
11#import repomanager.RepoManager as RepoManager
12import xmlrpc.client as n4d
13import threading
14import time
15import subprocess
16from collections import OrderedDict
17
18import gettext
19gettext.textdomain('repoman')
20_ = gettext.gettext
21
22RSRC_DIR='/usr/share/repoman/rsrc'
23#RSRC_DIR='/home/lliurex/trabajo/repoman/rsrc'
24JSON_SRC_DIR='/usr/share/repoman/sources.d'
25APT_SRC_DIR='/etc/apt/sources.list.d'
26LOGIN_IMG=RSRC_DIR+'/repoman_login.png'
27LOGIN_BACKGROUND=RSRC_DIR+'/repoman_background.png'
28
29SPACING=6
30MARGIN=6
31
32class main:
33
34        def __init__(self):
35                self.dbg=True
36                self.default_editor=''
37                self.err_msg={1:_("Invalid Url"),
38                                                2:_("Can't add repository information.\nCheck your permissions"),
39                                                3:_("Can't write sources file.\nCheck your permissions"),
40                                                4:_("Repository not found at given Url"),
41                                                5:_("Repositories failed to update"),
42                                                6:_("Mirror not availabe"),
43                                                7:("This repository could'nt be overwrited")
44                                                }
45                self.result={}         
46                self._set_css_info()
47                self.stack_dir=Gtk.StackTransitionType.SLIDE_LEFT
48                self.n4d=None
49                self.credentials=[]
50                self.server=None
51                self.repos={}
52                self._render_gui()
53        #def __init__
54
55        def _debug(self,msg):
56                if self.dbg:
57                        print("repoman: %s"%msg)
58
59        def _render_gui(self):
60                self.mw=Gtk.Window()
61                self.mw.set_title("RepoMan")
62                self.mw.set_hexpand(True)
63                self.mw.connect("destroy",self._on_destroy)
64                self.mw.set_resizable(False)
65                self.overlay=Gtk.Stack()
66                self.mw.add(self.overlay)
67                vbox=Gtk.VBox(False,True)
68                self.overlay.set_name("WHITE_BACKGROUND")
69                self.overlay.add_titled(vbox,"vbox","vbox")
70                self.overlay.add_titled(self._render_login(),"login","login")
71                self.overlay.set_visible_child_name("login")
72                pb=GdkPixbuf.Pixbuf.new_from_file("%s/repoman.png"%RSRC_DIR)
73                img_banner=Gtk.Image.new_from_pixbuf(pb)
74                img_banner.props.halign=Gtk.Align.CENTER
75                img_banner.set_margin_left(MARGIN*2)
76                vbox.add(img_banner)
77                toolbarbox=self._render_toolbar()
78                vbox.add(toolbarbox)
79                self.rev_question=Gtk.InfoBar()
80                lbl_question=Gtk.Label()
81                lbl_question.set_name("NOTIF_LABEL")
82                lbl_question.set_halign(Gtk.Align.START)
83                self.rev_question.props.no_show_all=True
84                self.rev_question.get_content_area().add(lbl_question)
85                img_cancel=Gtk.Image()
86                img_cancel.set_from_icon_name(Gtk.STOCK_CANCEL,Gtk.IconSize.BUTTON)
87                btn_cancel=Gtk.Button()
88                btn_cancel.add(img_cancel)
89                btn_cancel.set_halign(Gtk.Align.END)
90                btn_cancel.props.no_show_all=False
91                self.rev_question.add_action_widget(btn_cancel,Gtk.ResponseType.CANCEL)
92                img_ok=Gtk.Image()
93                img_ok.set_from_icon_name(Gtk.STOCK_OK,Gtk.IconSize.BUTTON)
94                btn_ok=Gtk.Button()
95                btn_ok.props.no_show_all=False
96                btn_ok.set_halign(Gtk.Align.START)
97                btn_ok.add(img_ok)
98                self.rev_question.add_action_widget(btn_ok,Gtk.ResponseType.OK)
99                self.rev_question.connect('response',self._manage_response)
100                vbox.add(self.rev_question)
101                self.stack = Gtk.Stack()
102                self.stack.set_hexpand(True)
103                self.stack.set_transition_duration(1000)
104                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
105#               self.stack.set_visible_child_name("login")
106                vbox.add(self.stack)
107                self.rev_info=Gtk.Revealer()
108                vbox.add(self.rev_info)
109                lbl_update=Gtk.Label()
110                lbl_update.set_name("NOTIF_LABEL")
111                self.rev_info.add(lbl_update)
112                self.rev_info.set_transition_duration(1000)
113                self.mw.show_all()
114                self.rev_info.set_reveal_child(False)
115#               toolbarbox.hide()
116#               img_banner.hide()
117                self.box_info=Gtk.Grid()
118                self.box_info.set_margin_bottom(MARGIN)
119                self.box_info.set_margin_left(MARGIN)
120                self.box_info.set_column_spacing(MARGIN)
121                lbl_info=Gtk.Label()
122                info=_("Repositories must be updated. Update now?")
123                lbl_info.set_markup('<span color="grey">%s</span>'%info)
124#               img_info=Gtk.Image().new_from_icon_name(Gtk.STOCK_REFRESH,Gtk.IconSize.BUTTON)
125                pb_info=GdkPixbuf.Pixbuf.new_from_file_at_scale("%s/stock_refresh.png"%RSRC_DIR,16,16,True)
126                img_info=Gtk.Image().new_from_pixbuf(pb_info)
127                btn_info=Gtk.Button()
128                btn_info.set_name("BLUEBUTTON")
129                btn_info.set_tooltip_text(_("Update repositories"))
130                btn_info.add(img_info)
131                spn_info=Gtk.Spinner()
132                self.box_info.attach(lbl_info,0,0,1,1)
133                self.box_info.attach(btn_info,1,0,1,1)
134                self.box_info.attach(spn_info,0,0,2,1)
135                self.box_info.set_no_show_all(True)
136                btn_info.connect("clicked",self._begin_update_repos,spn_info)
137                vbox.add(self.box_info)
138                Gtk.main()
139        #def _render_gui
140
141        def _render_toolbar(self):
142                self.toolbar=Gtk.Box()
143                self.toolbar=Gtk.Box(spacing=SPACING)
144                self.toolbar.set_margin_top(MARGIN)
145                self.toolbar.set_margin_bottom(MARGIN)
146                self.toolbar.set_margin_left(MARGIN)
147               
148                btn_return=Gtk.Button()#.new_from_stock(Gtk.STOCK_GO_BACK)
149                btn_return.add(Gtk.Image().new_from_icon_name(Gtk.STOCK_HOME,Gtk.IconSize.BUTTON))
150                btn_return.connect("clicked",self._load_screen,"sources")
151                btn_return.props.halign=Gtk.Align.START
152                btn_return.set_tooltip_text(_("Default repositories"))
153                self.toolbar.add(btn_return)
154
155                btn_manage=Gtk.Button()
156                btn_manage.props.halign=Gtk.Align.START
157                btn_manage.add(Gtk.Image().new_from_icon_name(Gtk.STOCK_PROPERTIES,Gtk.IconSize.BUTTON))
158                btn_manage.connect("clicked",self._load_screen,"repolist")
159                btn_manage.set_tooltip_text(_("External repositories"))
160                self.toolbar.add(btn_manage)
161               
162                btn_add=Gtk.Button()#.new_from_stock(Gtk.STOCK_ADD)
163                btn_add.props.halign=Gtk.Align.START
164                btn_add.add(Gtk.Image().new_from_icon_name(Gtk.STOCK_ADD,Gtk.IconSize.BUTTON))
165                btn_add.connect("clicked",self._load_screen,"newrepo")
166                btn_add.set_tooltip_text(_("Add external repository"))
167                self.toolbar.add(btn_add)
168               
169                return(self.toolbar)
170        #def _render_toolbar
171
172        def _render_login(self):
173                login=N4dGtkLogin(orientation=Gtk.Orientation.VERTICAL)
174#               login=N4dGtkLogin()
175                login.set_mw_proportion_ratio(1,1)
176                login.set_allowed_groups(['adm','teachers'])
177                login.set_login_banner(image=LOGIN_IMG)
178                login.set_label_background(255,255,255,0.3)
179                login.set_mw_background(image=LOGIN_BACKGROUND,cover=True)
180                desc=_("From here you can invoke RepoMan's mighty powers to manage your repositories.")
181                login.set_info_text("<span foreground='black'>RepoMan</span>",_("Repositories Manager"),"<span foreground='black'>"+desc+"</span>\n")
182                login.after_validation_goto(self._signin)
183                login.hide_server_entry()
184                login.show_all()
185                return (login)
186
187        def _signin(self,user=None,pwd=None,server=None,data=None):
188#               self.scheduler.set_credentials(user,pwd,server)
189#               self.stack.set_visible_child_name("sources")
190                self.credentials=[user,pwd]
191                self.server=server
192                context=ssl._create_unverified_context()
193                self.n4d=n4d.ServerProxy("https://%s:9779"%server,context=context,allow_none=True)
194                self.stack.add_titled(self._render_sources(), "sources", "Sources")
195                self.stack.add_titled(self._render_newrepo(), "newrepo", "Newrepo")
196                self.stack.add_titled(self._render_repolist(), "repolist", "Repolist")
197                self.overlay.set_transition_duration(1000)
198                self.overlay.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
199                self.overlay.set_visible_child_name("vbox")
200                self.mw.show_all()
201        #def _signin
202
203        def _render_sources(self):
204                gridbox=Gtk.Grid()
205                gridbox.set_column_homogeneous(False)
206                gridbox.set_column_spacing(MARGIN)
207                gridbox.set_name("WHITE_BACKGROUND")
208                gridbox.set_margin_top(MARGIN)
209                gridbox.set_margin_left(MARGIN)
210                gridbox.set_margin_right(MARGIN)
211                gridbox.set_margin_bottom(MARGIN)
212                self.repos=self.n4d.list_default_repos(self.credentials,"RepoManager")['data']
213                        #Sort by relevancy (Lliurex, Local, Ubuntu-*)
214                sort_repos=OrderedDict()
215                for repo in sorted(self.repos.keys()):
216                        sort_repos.update({repo:self.repos[repo]})
217                self.repos=sort_repos.copy()
218                row=0
219                for source,sourcedata in self.repos.items():
220                        desc=''
221                        if sourcedata['desc']:
222                                desc=_(sourcedata['desc'])
223                        self._insert_sourceslist_item(gridbox,source,desc,'',sourcedata['enabled'],row)
224                        row+=1
225                gridbox.set_margin_top(MARGIN)
226                gridbox.set_margin_bottom(MARGIN*2)
227                return(gridbox)
228        #def _render_sources
229
230        def _repo_state_changed(self,*args):
231                self.stack.set_sensitive(False)
232                self.box_info.set_no_show_all(False)
233                reponame=args[-1]
234                state=args[-2]
235                widget=args[0]
236                err=0
237                if reponame.lower()=="lliurex mirror":
238                        ret=subprocess.run(["lliurex-version","-m"],universal_newlines=True,stdout=subprocess.PIPE)
239                        if ret.stdout.strip()=="False":
240                                err=6
241                if err==0:
242                        self.repos[reponame].update({'enabled':str(state)})
243                        repo={}
244                        repo={reponame:self.repos[reponame]}
245                        self._debug("New state: %s"%repo)
246                        self._debug("Saving repo json: %s"%repo)
247                        if self.n4d.write_repo_json(self.credentials,"RepoManager",repo)['status']:
248                                if self.n4d.write_repo(self.credentials,"RepoManager",repo)['status']!=True:
249                                        err=3
250                        else:
251                                err=2
252                if err:
253                        self.toolbar.set_sensitive(False)
254                        GLib.timeout_add(3000,self.show_info,(self.err_msg[err]),"ERROR_LABEL")
255                        widget.set_state(not(state))
256                        return True
257                else:
258                        self.stack.set_sensitive(True)
259                        self.box_info.show_all()
260        #def _repo_state_changed
261
262        def _render_repolist(self):
263                scrollbox=Gtk.ScrolledWindow()
264                scrollbox.set_min_content_height(280)
265                scrollbox.set_min_content_width(280)
266                self.repobox=Gtk.Grid()
267                self.repobox.set_hexpand(True)
268                self.repobox.set_row_spacing(MARGIN)
269                self.repobox.set_margin_left(MARGIN)
270                self.repobox.set_margin_right(MARGIN)
271                self.repobox.set_margin_top(MARGIN)
272                self.repobox.set_row_spacing(0)
273                self.repobox.set_name("WHITE_BACKGROUND")
274                sourcefiles=self.n4d.list_sources(self.credentials,"RepoManager")['data']
275                sort_repos=OrderedDict()
276                for repo in sorted(sourcefiles.keys()):
277                        sort_repos.update({repo:sourcefiles[repo]})
278                sourcefiles=sort_repos.copy()
279                self.repos.update(sourcefiles)
280                row=0
281                for sourcefile,sourcedata in sourcefiles.items():
282                        desc=''
283                        if sourcedata['desc']:
284                                desc=_(sourcedata['desc'])
285                        edit=True
286                        if 'protected' in sourcedata.keys():
287                                if sourcedata['protected'].lower()=='true':
288                                        edit=False
289                        self._insert_sourceslist_item(self.repobox,sourcefile,desc,'',sourcedata['enabled'],row,edit)
290                        row+=1
291                scrollbox.add(self.repobox)
292                return scrollbox
293        #def _render_repolist
294
295        def _render_newrepo(self):
296                def del_icon(*args):
297                        args[-1].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,None)
298                        args[-1].set_placeholder_text("")
299
300                gridbox=Gtk.Grid()
301                gridbox.set_hexpand(True)
302                gridbox.set_row_spacing(MARGIN)
303                gridbox.set_margin_left(MARGIN)
304                gridbox.set_margin_right(MARGIN)
305                gridbox.set_margin_top(MARGIN)
306                boxname=Gtk.VBox(True,True)
307                boxname.set_name("WHITE_BACKGROUND")
308                boxname.set_hexpand(True)
309                lbl_name=Gtk.Label()
310                lbl_name.set_name("ENTRY_LABEL")
311                lbl_name.set_halign(Gtk.Align.START)
312                lbl_name.set_markup("<sup>%s</sup>"%_("Name for the repo"))
313                boxname.add(lbl_name)
314                inp_name=Gtk.Entry()
315                inp_name.connect("focus-in-event",del_icon,inp_name)
316                boxname.add(inp_name)
317                gridbox.add(boxname)
318                boxdesc=Gtk.VBox(True,True)
319                boxdesc.set_name("WHITE_BACKGROUND")
320                lbl_desc=Gtk.Label()
321                lbl_desc.set_name("ENTRY_LABEL")
322                lbl_desc.set_halign(Gtk.Align.START)
323                lbl_desc.set_markup("<sup>%s</sup>"%_("Description"))
324                boxdesc.add(lbl_desc)
325                inp_desc=Gtk.Entry()
326                boxdesc.add(inp_desc)
327                gridbox.attach_next_to(boxdesc,boxname,Gtk.PositionType.BOTTOM,1,1)
328                boxurl=Gtk.VBox(True,True)
329                boxurl.set_name("WHITE_BACKGROUND")
330                lbl_url=Gtk.Label()
331                lbl_url.set_name("ENTRY_LABEL")
332                lbl_url.set_halign(Gtk.Align.START)
333                lbl_url.set_markup("<sup>%s</sup>"%_("Url"))
334                boxurl.add(lbl_url)
335                inp_url=Gtk.Entry()
336                inp_url.connect("focus-in-event",del_icon,inp_url)
337                inp_url.connect("activate",self._begin_add_repo,inp_name,inp_desc,inp_url)
338                boxurl.add(inp_url)
339                gridbox.attach_next_to(boxurl,boxdesc,Gtk.PositionType.BOTTOM,1,1)
340                boxbtn=Gtk.Box()
341                btn_add=Gtk.Button.new_from_stock(Gtk.STOCK_APPLY)
342                btn_add.connect("clicked",self._begin_add_repo,inp_name,inp_desc,inp_url)
343#               btn_add.connect("clicked",self._add_repo,inp_name,inp_desc,inp_url)
344                boxbtn.set_halign(Gtk.Align.END)
345                boxbtn.add(btn_add)
346               
347                gridbox.attach_next_to(boxbtn,boxurl,Gtk.PositionType.BOTTOM,1,1)
348                return(gridbox)
349        #def _render_newrepo
350
351        def _begin_add_repo(self,*args):
352                name=args[-3].get_text()
353                desc=args[-2].get_text()
354                url=args[-1].get_text()
355                sw_err=False
356                if not name:
357                        args[-3].set_placeholder_text(_("Name is mandatory"))
358                        args[-3].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
359                        sw_err=True
360                elif len(name)>40:
361                        args[-3].set_placeholder_text(_("Name is too long"))
362                        args[-3].set_text("")
363                        args[-3].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
364                        sw_err=True
365
366                desc_array=desc.split(' ')
367                for element in desc_array:
368                        if len(element)>40:
369                                args[-2].set_placeholder_text(_("Description is too long"))
370                                args[-2].set_text("")
371                                args[-2].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
372                                sw_err=True
373
374                if not url:
375                        args[-1].set_placeholder_text(_("Url is mandatory"))
376                        args[-1].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
377                        sw_err=True
378                if not sw_err:
379                        listfiles=os.listdir(JSON_SRC_DIR)
380                        lowfiles=[]
381                        for jsonfile in listfiles:
382                                lowfile=jsonfile.lower()
383                                lowfiles.append(lowfile)
384                        if name.replace(' ','_').lower()+'.json' in lowfiles:
385                                #see if the repo is protected
386                                for repo in self.repos.keys():
387                                        if name.lower().replace('_',' ')==repo.lower():
388                                                if 'protected' in self.repos[repo]:
389                                                        if self.repos[repo]['protected'].lower()=='true':
390                                                                self.stack.set_sensitive(False)
391                                                                self.toolbar.set_sensitive(False)
392                                                                err=7
393                                                                GLib.timeout_add(3000,self.show_info,(self.err_msg[err]),"ERROR_LABEL")
394                                                                return
395
396                                self.result.pop('response',None)
397                                try:
398                                        self.rev_question.disconnect_by_func(self._manage_response)
399                                except:
400                                        pass
401                                self.rev_question.grab_add()
402                                self.rev_question.connect('response',self._manage_response,self._add_repo,*args)
403                                self.show_question(_("%s already exists. Overwrite it?"%name))
404                        else:
405                                self._add_repo(*args)
406
407        def _add_repo(self,*args):
408                name=args[-3].get_text()
409                desc=args[-2].get_text()
410                url=args[-1].get_text()
411                self.stack.set_sensitive(False)
412                self.toolbar.set_sensitive(False)
413                listfiles=os.listdir(JSON_SRC_DIR)
414                lowfiles={}
415                for jsonfile in listfiles:
416                        lowfile=jsonfile.lower()
417                        lowfiles[lowfile]=jsonfile
418                lowname=name.replace(' ','_').lower()+'.json'
419                if lowname in lowfiles.keys():
420                        name=lowfiles[lowname].replace('.json','').replace('_',' ')
421                err=self.n4d.add_repo(self.credentials,"RepoManager",name,desc,url)['status']
422                if err==0:
423                        row=(len(self.repos.keys())*2)
424                        if name in self.repos.keys():
425                                row=-1
426                        sourcefiles=self.n4d.list_sources(self.credentials,"RepoManager")['data']
427                        self.repos.update(sourcefiles)
428                        if row>=0:
429                                self._insert_sourceslist_item(self.repobox,name,desc,url,'true',row,True)
430                        GLib.timeout_add(2000,self.show_info,(_("Added repository %s"%name)),"NOTIF_LABEL",True)
431                else:
432                        #err=1 -> Bad url
433                        #err=2 -> Can't write json
434                        #err=3 -> Can't write sources
435                        #err=4 -> Repository not found at given url
436                        GLib.timeout_add(3000,self.show_info,(self.err_msg[err]),"ERROR_LABEL")
437        #def _add_repo
438
439        def _insert_sourceslist_item(self,sourcebox,name,desc,url,enabled='false',index=0,edit=False):
440                index*=2
441                repobox=Gtk.VBox(True,True)
442                repobox.set_margin_left(MARGIN)
443                repobox.set_margin_right(MARGIN)
444                repobox.set_margin_bottom(MARGIN)
445                repobox.set_margin_top(MARGIN)
446                lbl_source=Gtk.Label()
447                lbl_source.set_markup('<span size="larger">%s</span>'%name)
448                lbl_source.set_halign(Gtk.Align.START)
449                lbl_source.set_hexpand(True)
450                lbl_source.set_margin_left(MARGIN)
451                lbl_source.set_margin_bottom(MARGIN)
452                lbl_source.set_margin_top(MARGIN)
453                lbl_source.props.halign=Gtk.Align.START
454                repobox.add(lbl_source)
455                lbl_desc=Gtk.Label()
456                lbl_desc.set_ellipsize(3)
457                lbl_desc.set_markup('<span size="medium">%s</span>'%desc)
458                lbl_desc.set_tooltip_text('%s'%desc)
459                lbl_desc.set_halign(Gtk.Align.START)
460                repobox.add(lbl_desc)
461                if edit:
462                        img_edit=Gtk.Image.new_from_icon_name(Gtk.STOCK_EDIT,Gtk.IconSize.BUTTON)
463                        btn_edit=Gtk.Button()
464                        btn_edit.add(img_edit)
465                        btn_edit.set_tooltip_text(_("Edit sources file"))
466                        btn_edit.set_valign(Gtk.Align.CENTER)
467                        btn_edit.connect("clicked",self._edit_source_file,name)
468                        sourcebox.attach(btn_edit,1,index,1,1)
469                swt_repo=Gtk.Switch()
470                swt_repo.set_halign(Gtk.Align.END)
471                if enabled.lower()=="true":
472                        swt_repo.set_active(True)
473                else:
474                        swt_repo.set_active(False)
475                swt_repo.connect("state_set",self._repo_state_changed,name)
476                sourcebox.attach(repobox,0,index,1,1)
477                sourcebox.attach(swt_repo,2,index,1,1)
478                sourcebox.attach(Gtk.Separator(),0,index+1,1,1)
479                sourcebox.show_all()
480        #def _insert_sourceslist_item
481
482        def _load_screen(self,*args):
483                self.stack.set_transition_type(self.stack_dir)
484                if self.stack_dir==Gtk.StackTransitionType.SLIDE_RIGHT:
485                        self.stack_dir=Gtk.StackTransitionType.SLIDE_LEFT
486                else:
487                        self.stack_dir=Gtk.StackTransitionType.SLIDE_RIGHT
488                screen=args[-1]
489                self.stack.set_visible_child_name(screen)
490        #def _load_screen
491
492        def _begin_update_repos(self,*args):
493                spinner=args[-1]
494                spinner.show()
495                spinner.start()
496                self.stack.set_sensitive(False)
497                self.toolbar.set_sensitive(False)
498                th=threading.Thread(target=self._update_repos,args=[spinner])
499                th.start()
500                GLib.timeout_add(1500,self._check_update,th,spinner)
501        #def _begin_update_repos
502
503        def _update_repos(self,spinner):
504                self.result['update']=self.n4d.update_repos(self.credentials,"RepoManager")['status']
505        #def _update_repos
506
507        def _check_update(self,th,spinner):
508                if th.is_alive():
509                        return True
510                spinner.stop()
511                self.stack.set_sensitive(True)
512                self.toolbar.set_sensitive(True)
513                self.box_info.hide()
514                if self.result['update']:
515                        return(self.show_info(_("Repositories updated")))
516                else:
517                        return(self.show_info(self.err_msg[5],"ERROR_LABEL"))
518        #def _check_update
519
520        def _edit_source_file(self,*args):
521                sfile=args[-1].replace(' ','_')
522                self._debug("Editing %s.list"%sfile)
523                if os.path.isfile("%s/%s.list"%(APT_SRC_DIR,sfile)):
524                        edit=True
525                        try:
526                                if self.default_editor=='':
527                                        self.default_editor=subprocess.check_output(["xdg-mime","query","default","text/plain"],universal_newlines=True).strip().rstrip('.desktop;')
528                                if 'DISPLAY' in os.environ.keys():
529                                        display=os.environ['DISPLAY']
530                                        subprocess.run(["pkexec","%s"%self.default_editor,"%s/%s.list"%(APT_SRC_DIR,sfile),"--display=%s"%display],check=True)
531                        except Exception as e:
532                                self._debug("_edit_source_file error: %s"%e)
533                                edit=False
534                        if edit:
535                                newrepos=[]
536                                try:
537                                        with open("%s/%s.list"%(APT_SRC_DIR,sfile),'r') as f:
538                                                for line in f:
539                                                        newrepos.append(line.strip())
540                                except Exception as e:
541                                        self._debug("_edit_source_file failed: %s"%e)
542                                if sorted(self.repos[args[-1]]['repos'])!=sorted(newrepos):
543                                        self.repos[args[-1]]['repos']=newrepos
544                                        self.n4d.write_repo_json(self.credentials,"RepoManager",{args[-1]:self.repos[args[-1]]})
545                                        self.box_info.show_all()
546                else:
547                        self._debug("File %s/%s not found"%(APT_SRC_DIR,sfile))
548        #def _edit_source_file
549
550        def show_info(self,msg='',style="NOTIF_LABEL",show_info=False):
551                if self.rev_info.get_reveal_child():
552                        self.rev_info.set_reveal_child(False)
553                        self.stack.set_sensitive(True)
554                        self.toolbar.set_sensitive(True)
555                        if show_info:
556                                self.box_info.show_all()
557                        return False
558                lbl=None
559                for child in self.rev_info.get_children():
560                        if type(child)==type(Gtk.Label()):
561                                lbl=child
562                if lbl:
563                        lbl.set_name(style)
564                        lbl.set_markup(msg)
565                        self.rev_info.set_reveal_child(True)
566                return True
567        #def show_info
568       
569        def show_question(self,msg='',style="NOTIF_LABEL"):
570                self.rev_question.grab_add()
571                for child in self.rev_question.get_content_area():
572                        if type(child)==type(Gtk.Label()):
573                                lbl=child
574                for child in self.rev_question.get_action_area():
575                        if type(child)==type(Gtk.Button()):
576                                child.show_all()
577
578                lbl.set_markup(msg)
579                lbl.set_line_wrap(True)
580                lbl.set_lines(-1)
581                lbl.set_max_width_chars(20)
582                lbl.show()
583                self.rev_question.show()
584        #def show_question
585
586        def _manage_response(self,*args):
587                self.rev_question.grab_remove()
588                response=args[1]
589                self.rev_question.hide()
590                if response==Gtk.ResponseType.OK:
591                        args[2](args[-3],args[-2],args[-1])
592                else:
593                        return False
594
595        def _on_destroy(self,*args):
596                Gtk.main_quit()
597
598        def _set_css_info(self):
599       
600                css = b"""
601
602                GtkEntry{
603                        font-family: Roboto;
604                        border:0px;
605                        border-bottom:1px grey solid;
606                        margin-top:0px;
607                        padding-top:0px;
608                }
609
610                GtkLabel {
611                        font-family: Roboto;
612                }
613
614                #NOTIF_LABEL{
615                        background-color: #3366cc;
616                        font: 11px Roboto;
617                        color:white;
618                        border: dashed 1px silver;
619                        padding:6px;
620                }
621
622                #ERROR_LABEL{
623                        background-color: red;
624                        font: 11px Roboto;
625                        color:white;
626                        border: dashed 1px silver;
627                        padding:6px;
628                }
629
630                #ENTRY_LABEL{
631                        color:grey;
632                        padding:6px;
633                        padding-bottom:0px;
634                }
635
636                #PLAIN_BTN,#PLAIN_BTN:active{
637                        border:0px;
638                        padding:0px;
639                        background:white;
640                }
641               
642                #PLAIN_BTN_DISABLED,#PLAIN_BTN_DISABLED:active{
643                        border:0px;
644                        padding:0px;
645                        background:white;
646                        font:grey;
647                }
648
649                #COMPONENT{
650                        padding:3px;
651                        border: dashed 1px silver;
652
653                }
654
655                #WHITE_BACKGROUND {
656                        background-color:rgba(255,255,255,1);
657               
658                }
659
660                #BLUE_FONT {
661                        color: #3366cc;
662                        font: Roboto Bold 11;
663                       
664                }       
665               
666
667                #TASKGRID_FONT {
668                        color: #3366cc;
669                        font: Roboto 11;
670                       
671                }
672
673                #LABEL #LABEL_INSTALL{
674                        padding: 6px;
675                        margin:6px;
676                        font: 12px Roboto;
677                }
678
679                #LABEL_OPTION{
680               
681                        font: 48px Roboto;
682                        padding: 6px;
683                        margin:6px;
684                        font-weight:bold;
685                }
686
687                #ERROR_FONT {
688                        color: #CC0000;
689                        font: Roboto Bold 11;
690                }
691
692                #MENUITEM {
693                        padding: 12px;
694                        margin:6px;
695                        font: 24px Roboto;
696                        background:white;
697                }
698
699                #BLUEBUTTON {
700                        background-color: #3366cc;
701                        color:white;
702                        font: 11px Roboto Bold;
703                }
704
705                """
706                self.style_provider=Gtk.CssProvider()
707                self.style_provider.load_from_data(css)
708                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
709        #def set_css_info       
710
711GObject.threads_init()
712main()
Note: See TracBrowser for help on using the repository browser.