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

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

refactorized

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