source: taskscheduler/trunk/fuentes/scheduler-gui.install/usr/share/taskscheduler/bin/taskScheduler.py @ 6866

Last change on this file since 6866 was 6866, checked in by Juanma, 19 months ago

refactorized

  • Property svn:executable set to *
File size: 24.5 KB
Line 
1#! /usr/bin/python3
2# -*- coding: utf-8 -*-
3import gi
4gi.require_version('Gtk', '3.0')
5gi.require_version('PangoCairo', '1.0')
6import json
7import cairo
8import os
9import subprocess
10import shutil
11import threading
12import platform
13import subprocess
14import sys
15import time
16#import commands
17from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib, PangoCairo, Pango
18import time
19from taskscheduler.taskscheduler import TaskScheduler as scheduler
20from taskscheduler.cronParser import cronParser
21from detailDateBox import DetailBox as detailDateBox
22from edupals.ui.n4dgtklogin import *
23import signal
24signal.signal(signal.SIGINT, signal.SIG_DFL)
25
26import gettext
27gettext.textdomain('taskscheduler')
28_ = gettext.gettext
29
30BASE_DIR="/usr/share/taskscheduler/"
31#BASE_DIR="../share/taskscheduler/"
32GLADE_FILE=BASE_DIR+"rsrc/taskScheduler.ui"
33REMOVE_ICON=BASE_DIR+"rsrc/trash.svg"
34EDIT_ICON=BASE_DIR+"rsrc/edit.svg"
35NO_EDIT_ICON=BASE_DIR+"rsrc/no_edit.svg"
36LOCK_PATH="/var/run/taskScheduler.lock"
37WIDGET_MARGIN=6
38DBG=0
39
40class TaskScheduler:
41        def __init__(self):
42                self.is_scheduler_running()
43                try:
44                        self.flavour=subprocess.getoutput("lliurex-version -f")
45                except:
46                        self.flavour="client"
47                self.last_task_type='remote'
48                self.ldm_helper='/usr/sbin/sched-ldm.sh'
49                self.i18n={}
50                       
51        #def __init__           
52
53        def _debug(self,msg):
54                if DBG:
55                        print("taskScheduler: %s"%msg)
56        #def _debug
57
58        def is_scheduler_running(self):
59                if os.path.exists(LOCK_PATH):
60                        dialog = Gtk.MessageDialog(None,0,Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Task Scheduler")
61                        dialog.format_secondary_text(_("There's another instance of Task Scheduler running."))
62                        dialog.run()
63                        sys.exit(1)
64        #def is_scheduler_running
65
66        def start_gui(self):
67                self.scheduler=scheduler()
68                builder=Gtk.Builder()
69                builder.set_translation_domain('taskscheduler')
70
71                self.stack = Gtk.Stack()
72                self.stack.set_transition_duration(1000)
73                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
74
75                glade_path=GLADE_FILE
76                builder.add_from_file(glade_path)
77
78                self.window=builder.get_object("main_window")
79                self.window.set_resizable(False)
80                self.main_box=builder.get_object("main_box")
81                btn_exit=builder.get_object("btn_exit")
82                btn_exit.connect('clicked',self.quit)
83                self.login=N4dGtkLogin()
84                self.login.set_allowed_groups(['adm','teachers'])
85                desc=_("Welcome to the Task Scheduler for Lliurex.\nFrom here you can:\n<sub>* Schedule tasks in the local pc\n* Distribute tasks among all the pcs in the network\n*Show scheduled tasks</sub>")
86                self.login.set_info_text("<span foreground='black'>Task Scheduler</span>",_("Task Scheduler"),"<span foreground='black'>"+desc+"</span>\n")
87                self.login.set_info_background(image='taskscheduler',cover=True)
88                self.login.after_validation_goto(self._signin)
89                self.login.hide_server_entry()
90                self.inf_message=Gtk.InfoBar()
91                self.inf_message.set_show_close_button(True)
92                self.lbl_message=Gtk.Label("")
93                self.inf_message.get_action_area().add(self.lbl_message)
94                self.inf_message.set_halign(Gtk.Align.CENTER)
95                self.inf_message.set_valign(Gtk.Align.CENTER)
96                def hide(widget,response):
97                        self.inf_message.hide()
98                self.inf_message.connect('response',hide)
99#               self.inf_message.props.no_show_all=True
100
101                self.inf_question=Gtk.InfoBar() 
102                self.lbl_question=Gtk.Label("")
103                self.inf_question.get_action_area().add(self.lbl_question)
104                self.inf_question.add_button(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL)
105                self.inf_question.add_button(Gtk.STOCK_OK,Gtk.ResponseType.OK)
106                self.inf_question.set_halign(Gtk.Align.CENTER)
107                self.inf_question.set_valign(Gtk.Align.CENTER)
108#               self.inf_question.props.no_show_all=True
109                self.main_box.pack_start(self.inf_question,False,False,0)
110                self.main_box.pack_start(self.inf_message,False,False,0)
111                self.view_tasks_button_box=builder.get_object("view_tasks_button_box")
112                self.view_tasks_eb=builder.get_object("view_tasks_eventbox")
113                self.btn_signal_id=None
114                #Toolbar
115                self.toolbar=builder.get_object("toolbar")
116                self.toolbar.set_visible(False)
117                self.btn_add_task=builder.get_object("btn_add_task")
118                self.btn_add_task.connect("button-release-event", self.add_task_clicked)
119                self.btn_refresh_tasks=builder.get_object("btn_refresh_tasks")
120                self.btn_refresh_tasks.connect("button-release-event", self._reload_grid)
121                self.btn_manage_tasks=builder.get_object("btn_manage_tasks")
122                self.btn_manage_tasks.connect("button-release-event", self._manage_tasks)
123                self.txt_search=builder.get_object("txt_search")
124                self.txt_search.connect('changed',self.match_tasks)
125                #tasks list
126                self._load_task_list_gui(builder)
127                #Manage tasks
128                self._load_manage_tasks(builder)
129                #Icons
130                image=Gtk.Image()
131                image.set_from_file(REMOVE_ICON)               
132                self.remove_icon=image.get_pixbuf()
133                image.set_from_file(EDIT_ICON)         
134                self.edit_icon=image.get_pixbuf()
135                image.set_from_file(NO_EDIT_ICON)               
136                self.no_edit_icon=image.get_pixbuf()
137
138                self.stack.add_titled(self.tasks_box, "tasks", "Tasks")
139                self.stack.add_titled(self.manage_box, "manage", "Manage")
140                self.stack.add_titled(self.add_task_box, "add", "Add Task")
141                self.stack.add_titled(self.login, "login", "Login")
142                #Packing
143                self.main_box.pack_start(self.stack,True,False,5)
144
145                self.toolbar.props.no_show_all=True
146                self.window.connect("destroy",self.quit)
147                self.window.set_resizable(False)
148                self.window.show_all()
149                self.inf_message.hide()
150                self.inf_question.hide()
151                self.set_css_info()
152                #Load stack
153                self.stack.set_transition_type(Gtk.StackTransitionType.NONE)
154                self.stack.set_visible_child_name("login")
155                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
156
157                Gtk.main()
158        #def start_gui
159
160        def _load_task_list_gui(self,builder):
161                self.tasks_box=builder.get_object("tasks_box")
162                self.tasks_label=builder.get_object("tasks_label")
163                self.tasks_tv=builder.get_object("tasks_treeview")
164                self.tasks_store=Gtk.ListStore(str,str,str,GdkPixbuf.Pixbuf,GdkPixbuf.Pixbuf,str,str,str,str)
165                self.tasks_store_filter=self.tasks_store.filter_new()
166                self.tasks_store_filter.set_visible_func(self.filter_tasklist)
167                self.tasks_tv.set_model(self.tasks_store_filter)
168                self.tasks_tv.connect("button-release-event",self.task_clicked)
169                self.tasks_tv.connect("row-activated",self.task_clicked)
170                self.tasks_tv.connect("cursor-changed",self.task_clicked)
171
172                column=Gtk.TreeViewColumn(_("Task"))
173                cell=Gtk.CellRendererText()
174                column.pack_start(cell,True)
175                column.add_attribute(cell,"markup",0)
176                column.add_attribute(cell,"cell_background",7)
177                column.add_attribute(cell,"foreground",8)
178                column.set_expand(True)
179                self.tasks_tv.append_column(column)
180               
181                column=Gtk.TreeViewColumn(_("Serial"))
182                cell=Gtk.CellRendererText()
183                column.pack_start(cell,True)
184                column.add_attribute(cell,"markup",1)
185                column.add_attribute(cell,"cell_background",7)
186                column.add_attribute(cell,"foreground",8)
187                column.set_expand(True)
188                column.set_visible(False)
189                self.tasks_tv.append_column(column)
190               
191                column=Gtk.TreeViewColumn(_("When"))
192                cell=Gtk.CellRendererText()
193                cell.set_property("alignment",Pango.Alignment.CENTER)
194                column.pack_start(cell,False)
195                column.add_attribute(cell,"markup",2)
196                column.add_attribute(cell,"cell_background",7)
197                column.add_attribute(cell,"foreground",8)
198                column.set_expand(True)
199                self.tasks_tv.append_column(column)             
200
201                column=Gtk.TreeViewColumn(_("Edit"))
202
203                cell=Gtk.CellRendererPixbuf()
204                column.pack_start(cell,True)
205                column.add_attribute(cell,"pixbuf",3)
206                column.add_attribute(cell,"cell_background",7)
207                self.col_edit=column
208                self.tasks_tv.append_column(column)
209               
210                column=Gtk.TreeViewColumn(_("Remove"))
211                cell=Gtk.CellRendererPixbuf()
212                column.pack_start(cell,True)
213                column.add_attribute(cell,"pixbuf",4)
214                column.add_attribute(cell,"cell_background",7)
215                self.col_remove=column
216                self.tasks_tv.append_column(column)
217
218                column=Gtk.TreeViewColumn(_("Command"))
219                cell=Gtk.CellRendererText()
220                column.pack_start(cell,True)
221                column.add_attribute(cell,"markup",5)
222                column.set_expand(True)
223                column.set_visible(False)
224                self.tasks_tv.append_column(column)
225               
226                column=Gtk.TreeViewColumn(_("Type"))
227                cell=Gtk.CellRendererText()
228                column.pack_start(cell,True)
229                column.add_attribute(cell,"markup",6)
230                column.set_expand(True)
231                column.set_visible(False)
232                self.tasks_tv.append_column(column)
233
234                self.tasks_tv.set_search_column(2)
235                self.tasks_tv.set_search_entry(self.txt_search)
236
237                #Add tasks
238                self.add_task_box=builder.get_object("add_task_box")
239                self.add_task_grid=detailDateBox(self.scheduler)
240                at_grid=self.add_task_grid.render_form(builder.get_object("add_task_grid"))
241                at_grid=builder.get_object("add_task_grid")
242                at_grid.set_hexpand(False)
243                self.cmb_task_names=builder.get_object("cmb_task_names")
244                self.cmb_task_cmds=builder.get_object("cmb_task_cmds")
245                builder.get_object("btn_back_add").connect("clicked", self.cancel_add_clicked)
246                builder.get_object("btn_cancel_add").connect("clicked", self.cancel_add_clicked)
247                self.btn_confirm_add=builder.get_object("btn_confirm_add")
248                self.btn_confirm_add.connect("clicked", self.save_task_details)
249        #def _load_task_list_gui
250
251        def _load_manage_tasks(self,builder):
252                self.manage_box=builder.get_object("manage_box")
253                custom_grid=builder.get_object("custom_grid")
254                custom_grid.set_margin_left(WIDGET_MARGIN*2)
255                custom_grid.set_margin_top(WIDGET_MARGIN*2)
256                txt_taskname=Gtk.Entry()
257                txt_taskname.set_tooltip_text(_("A descriptive name for the command"))
258                txt_taskname.set_placeholder_text(_("Task name"))
259                lbl_name=Gtk.Label(_("Task name"))
260                lbl_name.set_halign(Gtk.Align.END)
261                btn_add_cmd=Gtk.Button.new_from_stock(Gtk.STOCK_ADD)
262                custom_grid.attach(lbl_name,0,0,1,1)
263                custom_grid.attach(txt_taskname,1,0,1,1)
264                cmb_cmds=Gtk.ComboBoxText()
265                i18n_cmd=self.load_cmb_cmds(cmb_cmds)
266                lbl_cmd=Gtk.Label(_("Command"))
267                lbl_cmd.set_halign(Gtk.Align.END)
268                custom_grid.attach(lbl_cmd,0,1,1,1)
269                custom_grid.attach(cmb_cmds,1,1,1,1)
270                custom_grid.attach(btn_add_cmd,2,1,1,1)
271                chk_parm_is_file=Gtk.CheckButton(_("Needs a file"))
272                chk_parm_is_file.set_tooltip_text(_("Mark if the command will launch a file"))
273                btn_file=Gtk.FileChooserButton()
274                chk_parm_is_file.set_tooltip_text(_("Select the file that will be launched"))
275                chk_parm_is_file.connect('toggled',self._enable_filechooser,btn_file)
276                txt_params=Gtk.Entry()
277                txt_params.set_placeholder_text(_("Needed arguments"))
278                txt_params.set_tooltip_text(_("Put here the arguments for the command (if any)"))
279                lbl_arg=Gtk.Label(_("Arguments"))
280                lbl_arg.set_halign(Gtk.Align.END)
281                custom_grid.attach(lbl_arg,3,1,1,1)
282                custom_grid.attach(txt_params,4,1,1,1)
283                custom_grid.attach(chk_parm_is_file,3,0,1,1)
284                custom_grid.attach(btn_file,4,0,1,1)
285                btn_file.set_sensitive(False)
286                self.btn_apply_manage=builder.get_object("btn_apply_manage")
287                self.btn_apply_manage.connect("clicked",self._add_custom_task,txt_taskname,cmb_cmds,txt_params,chk_parm_is_file,btn_file,i18n_cmd)
288                self.btn_back_manage=builder.get_object("btn_back_manage")
289                self.btn_back_manage.connect("clicked",self._cancel_manage_clicked)
290                self.btn_cancel_manage=builder.get_object("btn_cancel_manage")
291                self.btn_cancel_manage.connect("clicked",self._cancel_manage_clicked)
292                btn_add_cmd.connect("clicked",self._add_cmd_clicked,cmb_cmds)
293        #def _load_manage_tasks
294
295        def load_cmb_cmds(self,cmb_cmds):
296                cmb_cmds.remove_all()
297                cmds=self.scheduler.get_commands()
298                i18n_cmd={}
299                for cmd in cmds.keys():
300                        i18n_cmd[_(cmd)]=cmd
301                        cmb_cmds.append_text(_(cmd))
302                return(i18n_cmd)
303
304        def _add_cmd_clicked(self,*args):
305                cmb_cmds=args[-1]
306                def show_file_dialog(*args):
307                        file_response=dlg_file.run()
308                        if file_response == Gtk.ResponseType.OK:
309                                txt_file.set_text(dlg_file.get_filename())
310#                       dlg_file.destroy()
311                dialog=Gtk.Dialog()
312                dialog.add_buttons(Gtk.STOCK_APPLY,42,"Close",Gtk.ResponseType.CLOSE)
313                box=dialog.get_content_area()
314                hbox=Gtk.Grid()
315                hbox.set_column_spacing(WIDGET_MARGIN)
316                hbox.set_row_spacing(WIDGET_MARGIN)
317                lbl_name=Gtk.Label(_("Action name"))
318                txt_name=Gtk.Entry()
319                txt_name.set_tooltip_text("Enter the name for the action")
320                lbl_file=Gtk.Label(_("Command"))
321                txt_file=Gtk.Entry()
322                txt_file.set_tooltip_text("Enter the command or choose one from the file selector")
323                dlg_file=Gtk.FileChooserDialog(_("Choose a command"),dialog,Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
324                btn_file=Gtk.Button.new_from_stock(Gtk.STOCK_FILE)
325                btn_file.connect("clicked",show_file_dialog)
326                hbox.attach(lbl_name,0,0,1,1)
327                hbox.attach(txt_name,1,0,1,1)
328                hbox.attach(lbl_file,0,1,1,1)
329                hbox.attach(txt_file,1,1,1,1)
330                hbox.attach(btn_file,2,1,1,1)
331                hbox.attach(Gtk.Separator(),0,2,2,1)
332                box.add(hbox)
333                box.show_all()
334                response=dialog.run()
335                if response==Gtk.ResponseType.CLOSE:
336                        dialog.destroy()
337                if response==42:
338                        self._add_custom_cmd(txt_name.get_text(),txt_file.get_text())
339                        self.load_cmb_cmds(cmb_cmds)
340        #def _add_cmd_clicked
341
342        def _add_custom_cmd(self,name,cmd):
343                self.scheduler.add_command(name,cmd)
344       
345        def _enable_filechooser(self,widget,filechooser):
346                if widget.get_active():
347                        filechooser.set_sensitive(True)
348                else:
349                        filechooser.set_sensitive(False)
350        #def _enable_filechooser
351
352        def _add_custom_task(self,widget,w_name,w_cmd,w_parms,w_chk,w_file,i18n_cmd=None):
353                name=w_name.get_text()
354                cmd=w_cmd.get_active_text()
355                if i18n_cmd:
356                        cmd_desc=i18n_cmd[cmd]
357                else:
358                        cmd_desc=cmd
359                parms=w_parms.get_text()
360                cmd=self.scheduler.get_command_cmd(cmd_desc)
361                if w_chk.get_active():
362                        parms=parms+' '+w_file.get_uri().replace('file://','')
363                if self.scheduler.write_custom_task(name,cmd,parms):
364                        self._show_info(_("Task saved"))
365                else:
366                        self._show_info(_("Permission denied"))
367        #def _add_custom_task
368
369        def _signin(self,user=None,pwd=None,server=None,data=None):
370                self.scheduler.set_credentials(user,pwd,server)
371                self.stack.set_visible_child_name("tasks")
372                self.populate_tasks_tv()
373                self.toolbar.show()
374        #def _signin
375
376        def populate_tasks_tv(self,sw_remote=False):
377                self._debug("Populating task list")
378                self.scheduled_tasks={}
379                tasks=[]
380                sw_tasks=False
381                tasks=self.scheduler.get_scheduled_tasks(sw_remote)
382                self.tasks_store.clear()
383                if type(tasks)==type({}):       
384                        parser=cronParser()
385                        self.i18n['cmd']={}
386                        self.i18n['name']={}
387                        for task_name in tasks.keys():
388                                for serial in tasks[task_name].keys():
389                                        task=tasks[task_name][serial]
390                                        task['sw_remote']=''
391                                        color_palette=['goldenrod','DarkSlateGrey','Burlywood','DarkSlateGrey','DarkSlateBlue','bisque','LightSteelBlue','DarkSlateGrey']
392                                        bg_color=color_palette[0]
393                                        fg_color=color_palette[1]
394                                        if 'kind' in task.keys():
395                                                if 'fixed' in task['kind']:
396                                                        bg_color=color_palette[2]
397                                                        fg_color=color_palette[3]
398                                                elif 'repeat' in task['kind']:
399                                                        bg_color=color_palette[4]
400                                                        fg_color=color_palette[5]
401                                                elif 'daily' in task['kind']:
402                                                        bg_color=color_palette[6]
403                                                        fg_color=color_palette[7]
404                                        else:
405                                                task['kind']=''
406                                        remote='Local task'
407                                        if 'spread' in task.keys():
408                                                if task['spread']==True:
409                                                        remote="Client task"
410                                        else:
411                                                task['spread']=False
412                                        self.scheduled_tasks[task_name]=tasks[task_name]
413                                        sw_tasks=True
414                                        parsed_calendar=''
415                                        parsed_calendar=parser.parse_taskData(task)
416                                        task['cmd']=task['cmd'].replace(self.ldm_helper+' ','')
417                                        task['action']=self.scheduler.get_task_description(task['cmd'])
418                                        if 'name' in task.keys():
419                                                name=task['name']
420                                        else:
421                                                name=_(task['action'])
422                                        self.i18n['cmd'].update({name:task['action']})
423                                        self.i18n['name'].update({_(task_name):task_name})
424                                        img=self.edit_icon
425                                        if 'protected' in task.keys():
426                                                if task['protected']==True:
427                                                        img=self.no_edit_icon
428                                        row=self.tasks_store.append(("<span font='Roboto'><b>"+name+"</b></span>\n"+\
429                                                                "<span font='Roboto' size='small'><i>"+\
430                                                                _(task_name)+"</i></span>",serial,"<span font='Roboto' size='small'>"+\
431                                                                parsed_calendar+"</span>\n"+"<span font='Roboto' size='small'><i>"+remote+"</i></span>",img,self.remove_icon,str(task['spread']),','.join(task['kind']),bg_color,fg_color))
432        #def populate_tasks_tv
433       
434        def filter_tasklist(self,model,iterr,data):
435                sw_match=True
436                match=self.txt_search.get_text().lower()
437                task_data=model.get_value(iterr,0).split('\n')
438                task_sched_data=model.get_value(iterr,2).split('\n')
439                task_cmd=task_data[0][task_data[0].find("<b>")+3:task_data[0].find("</b>")]
440                task_name=task_data[1][task_data[1].find("<i>")+3:task_data[1].find("</i>")]
441                task_sched=task_sched_data[0][task_sched_data[0].find("ll'>")+4:task_sched_data[0].find("</span>")]
442
443                task_text=task_cmd+' '+task_name+' '+task_sched
444                if match and match not in task_text.lower():
445                        sw_match=False
446                return sw_match
447        #def filter_tasklist
448
449        def match_tasks(self,widget):
450                self.tasks_store_filter.refilter()
451                GObject.timeout_add(100,self.tasks_tv.set_cursor,0)
452        #def match_tasks
453
454        def _process_model(self,model,data):
455                task={}
456                task['data']=model[data][0].split('\n')
457                if _("client task") in model[data][2]:
458                        task['spread']=True
459                else:
460                        task['spread']=False
461                task['serial']=model[data][1].split('\n')[0]
462                cmd=task['data'][0][task['data'][0].find("<b>")+3:task['data'][0].find("</b>")]
463                if cmd in self.i18n['cmd'].keys():
464                        task['cmd']=self.i18n['cmd'][cmd]
465                else:
466                        task['cmd']=cmd
467
468                name=task['data'][1][task['data'][1].find("<i>")+3:task['data'][1].find("</i>")]
469                if name in self.i18n['name'].keys():
470                        task['name']=self.i18n['name'][name]
471                else:
472                        task['name']=name
473
474                task['serial']=model[data][1]
475                return(task)
476
477        def _click_on_list(self,event):
478                action=''
479                row=None
480
481                if type(event)==type(Gtk.TreePath()):
482                        action='edit'
483                else:
484                        try:
485                                row=self.tasks_tv.get_path_at_pos(int(event.x),int(event.y))
486                        except Exception as e:
487                                self._debug(e)
488                        if row:
489                                if row[1]==self.col_remove:
490                                        action='remove'
491                                elif row[1]==self.col_edit:
492                                        action='edit'
493                self._debug(action)
494                return action
495
496        def task_clicked(self,treeview,event=None,*args):
497                self._debug("task clicked %s"%event)
498                selection=self.tasks_tv.get_selection()
499                model,data=selection.get_selected()
500                if not data:
501                        return
502                task={}
503                action=''
504                if event!=None:
505                        action=self._click_on_list(event)
506                task=self._process_model(model,data)
507                if action=='remove':
508                        self.lbl_question.set_text(_("Are you sure to delete this task?"))
509                        for widget in self.main_box.get_children():
510                                widget.set_sensitive(False)
511                        self.inf_question.set_sensitive(True)
512                        self.inf_question.show_all()
513                        try:
514                                self.inf_question.disconnect_by_func(self.manage_remove_responses)
515                        except:
516                                pass
517                        self.inf_question.connect('response',self.manage_remove_responses,model,task)
518                elif action=='edit':
519                        if task['name'] in self.scheduled_tasks.keys():
520                                if task['serial'] in self.scheduled_tasks[task['name']].keys():
521                                        task['data']=self.scheduled_tasks[task['name']][task['serial']]
522                                        self._debug("Loading details of task %s of group %s"% (task['serial'],task['name']))
523                                        self.add_task_grid.set_task_data(task)
524                                        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
525                                        self.cmb_task_names.remove_all()
526                                        self.cmb_task_cmds.remove_all()
527                                        self.cmb_task_names.append_text(_(task['name']))
528                                        self.cmb_task_cmds.append_text(_(task['cmd']))
529                                        self.cmb_task_names.set_active(0)
530                                        self.cmb_task_cmds.set_active(0)
531                                        self.add_task_grid.load_task_details()
532                                        if 'protected' in task['data'].keys():
533                                                if task['data']['protected']:
534                                                        self.btn_confirm_add.set_sensitive(False)
535                                        else:
536                                                self.btn_confirm_add.set_sensitive(True)
537                                        self.stack.set_visible_child_name("add")
538        #def task_clicked                       
539
540        def save_task_details(self,widget):
541                task={}
542                name=self.cmb_task_names.get_active_text()
543                task['name']=self.i18n['name'][name]
544                action=self.cmb_task_cmds.get_active_text()
545                i18n_action=self.i18n['cmd'][action]
546                tasks=self.scheduler.get_available_tasks()
547                task['cmd']=tasks[task['name']][i18n_action]
548                self.add_task_grid.update_task_data(task)
549                task=self.add_task_grid.get_task_details()
550
551                self._debug("Writing task info...%s"%task)
552                for key in task.keys():
553                        for data in task[key].keys():
554                                if task[key][data]['spread']==False:
555                                        status=self.scheduler.write_tasks(task,'local')
556                                else:
557                                        status=self.scheduler.write_tasks(task,'remote')
558                        break
559                if status:
560                        self._show_info(_("Task saved"))
561                else:
562                        self._show_info(_("Permission denied"))
563                return()
564        #def save_task_details
565
566        def view_tasks_clicked(self,widget,sw_remote):
567                if widget:
568                        if not widget.get_active():
569                                return True
570                self._debug("loading tasks (remote: %s)" % sw_remote)
571                if sw_remote:
572                        self.last_task_type='remote'
573                else:
574                        self.last_task_type='local'
575                self._debug("Task clicked")
576                self.populate_tasks_tv()
577                self.tasks_tv.set_model(self.tasks_store_filter)
578                self.tasks_tv.set_cursor(0)
579                if self.stack.get_visible_child_name!='tasks':
580                        self.stack.set_visible_child_name("tasks")
581        #def view_tasks_clicked
582
583        def load_add_task_details(self):
584                tasks=[]
585                names=[]
586                self.cmb_task_names.remove_all()
587                tasks=self.scheduler.get_available_tasks()
588                for name in tasks.keys():
589                        if name not in names:
590                                names.append(name)
591                                self.i18n['name'].update({_(name):name})
592                                self.cmb_task_names.append_text(_(name))
593               
594                self.cmb_task_names.connect('changed',self.load_add_task_details_cmds,tasks)
595                self.cmb_task_names.set_active(0)
596        #def load_add_task_details
597
598        def load_add_task_details_cmds(self,widget,tasks):
599                actions=[]
600                self.i18n['cmd']={}
601                self.cmb_task_cmds.remove_all()
602                task_name=self.cmb_task_names.get_active_text()
603                if task_name:
604                        orig_name=self.i18n['name'][task_name]
605                        for action in tasks[orig_name].keys():
606                                if action not in actions:
607                                        self.i18n['cmd'].update({_(action):action})
608                                        actions.append(action)
609                                        self.cmb_task_cmds.append_text(_(action))
610                self.cmb_task_cmds.set_active(0)
611        #def load_add_task_details_cmds
612       
613        def update_task(self,widget,data=None):
614                self._debug("Updating task")
615                if self.task_details_grid.update_task_details():
616                        self._show_info(_('Task updated'))
617                        self._reload_grid()
618                else:
619                        self._show_info(_('Permission denied'))
620               
621        #def update_task
622
623        def add_task_clicked(self,widget,event):
624                self._debug("Loading new task form")
625                self.add_task_grid.clear_screen()
626                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
627                self.stack.set_visible_child_name("add")
628                self.load_add_task_details()
629        #def add_task_clicked   
630
631        def cancel_add_clicked(self,widget,event=None):
632                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
633                self.stack.set_visible_child_name("tasks")     
634                self._debug("Cancel add clicked")
635                self._reload_grid()
636        #def cancel_add_clicked
637
638        def _reload_grid(self,widget=None,data=None):
639                cursor=self.tasks_tv.get_cursor()[0]
640                self._debug("CURSOR %s"%widget)
641                self._debug("Reload grid")
642                self.populate_tasks_tv()
643                if cursor:
644                        self._debug("Restoring cursor")
645                        self.tasks_tv.set_cursor(cursor)
646
647                if type(widget)==type(Gtk.CheckButton()):
648                        self.task_details_grid.chk_node.connect("toggled",self._reload_grid)
649        #def _reload_grid
650
651        def manage_remove_responses(self,widget,response,model,task):
652                self.inf_question.hide()
653                if response==Gtk.ResponseType.OK:
654                        self._debug("Removing task %s"%(task))
655                        if task['name'] in self.i18n['name'].keys():
656                                task['name']=self.i18n['name'][task['name']]
657                        if task['cmd'] in self.i18n['cmd'].keys():
658                                task['cmd']=self.i18n['cmd'][task['cmd']]
659                        if self.scheduler.remove_task(task):
660                                self.populate_tasks_tv()
661                                self.tasks_tv.set_cursor(0)
662                        else:
663                                self._show_info(_("Permission denied"))
664                for widget in self.main_box.get_children():
665                        widget.set_sensitive(True)
666        #def manage_remove_responses
667
668        def _show_info(self,msg):
669                self.lbl_message.set_text(_(msg))
670                self.inf_message.show_all()
671                GObject.timeout_add(5000,self.inf_message.hide)
672        #def _show_info
673       
674        def _manage_tasks(self,widget,event):
675                self._debug("Loading manage tasks form")
676                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
677                self.stack.set_visible_child_name("manage")
678        #def _manage_tasks     
679
680        def _cancel_manage_clicked(self,widget):
681                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
682                self.stack.set_visible_child_name("tasks")     
683       
684        def set_css_info(self):
685       
686                css = b"""
687                #WHITE_BACKGROUND {
688                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff),  to (#ffffff));;
689               
690                }
691
692                #BLUE_FONT {
693                        color: #3366cc;
694                        font: Roboto Bold 11;
695                       
696                }       
697               
698
699                #TASKGRID_FONT {
700                        color: #3366cc;
701                        font: Roboto 11;
702                       
703                }
704
705                #LABEL_OPTION{
706               
707                        color: #808080;
708                        font: Roboto 11;
709                }
710
711                #ERROR_FONT {
712                        color: #CC0000;
713                        font: Roboto Bold 11;
714                }
715                """
716                self.style_provider=Gtk.CssProvider()
717                self.style_provider.load_from_data(css)
718                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
719               
720                self.window.set_name("WHITE_BACKGROUND")
721                self.tasks_box.set_name("WHITE_BACKGROUND")
722        #def set_css_info       
723
724        def quit(self,*args):
725                Gtk.main_quit() 
726        #def quit       
727
728#class TaskScheduler
729
730GObject.threads_init()
731t=TaskScheduler()
732t.start_gui()           
Note: See TracBrowser for help on using the repository browser.