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

Last change on this file was 8295, checked in by Juanma, 12 months ago

sync with git

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