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

Last change on this file since 6849 was 6849, 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                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("cursor-changed",self.task_clicked)
170
171                column=Gtk.TreeViewColumn(_("Task"))
172                cell=Gtk.CellRendererText()
173                column.pack_start(cell,True)
174                column.add_attribute(cell,"markup",0)
175                column.add_attribute(cell,"cell_background",7)
176                column.add_attribute(cell,"foreground",8)
177                column.set_expand(True)
178                self.tasks_tv.append_column(column)
179               
180                column=Gtk.TreeViewColumn(_("Serial"))
181                cell=Gtk.CellRendererText()
182                column.pack_start(cell,True)
183                column.add_attribute(cell,"markup",1)
184                column.add_attribute(cell,"cell_background",7)
185                column.add_attribute(cell,"foreground",8)
186                column.set_expand(True)
187                column.set_visible(False)
188                self.tasks_tv.append_column(column)
189               
190                column=Gtk.TreeViewColumn(_("When"))
191                cell=Gtk.CellRendererText()
192                cell.set_property("alignment",Pango.Alignment.CENTER)
193                column.pack_start(cell,False)
194                column.add_attribute(cell,"markup",2)
195                column.add_attribute(cell,"cell_background",7)
196                column.add_attribute(cell,"foreground",8)
197                column.set_expand(True)
198                self.tasks_tv.append_column(column)             
199
200                column=Gtk.TreeViewColumn(_("Edit"))
201
202                cell=Gtk.CellRendererPixbuf()
203                column.pack_start(cell,True)
204                column.add_attribute(cell,"pixbuf",3)
205                column.add_attribute(cell,"cell_background",7)
206                self.col_edit=column
207                self.tasks_tv.append_column(column)
208               
209                column=Gtk.TreeViewColumn(_("Remove"))
210                cell=Gtk.CellRendererPixbuf()
211                column.pack_start(cell,True)
212                column.add_attribute(cell,"pixbuf",4)
213                column.add_attribute(cell,"cell_background",7)
214                self.col_remove=column
215                self.tasks_tv.append_column(column)
216
217                column=Gtk.TreeViewColumn(_("Command"))
218                cell=Gtk.CellRendererText()
219                column.pack_start(cell,True)
220                column.add_attribute(cell,"markup",5)
221                column.set_expand(True)
222                column.set_visible(False)
223                self.tasks_tv.append_column(column)
224               
225                column=Gtk.TreeViewColumn(_("Type"))
226                cell=Gtk.CellRendererText()
227                column.pack_start(cell,True)
228                column.add_attribute(cell,"markup",6)
229                column.set_expand(True)
230                column.set_visible(False)
231                self.tasks_tv.append_column(column)
232
233                self.tasks_tv.set_search_column(2)
234                self.tasks_tv.set_search_entry(self.txt_search)
235
236                #Add tasks
237                self.add_task_box=builder.get_object("add_task_box")
238                self.add_task_grid=detailDateBox(self.scheduler)
239                at_grid=self.add_task_grid.render_form(builder.get_object("add_task_grid"))
240                at_grid=builder.get_object("add_task_grid")
241                at_grid.set_hexpand(False)
242                self.cmb_task_names=builder.get_object("cmb_task_names")
243                self.cmb_task_cmds=builder.get_object("cmb_task_cmds")
244                builder.get_object("btn_back_add").connect("clicked", self.cancel_add_clicked)
245                builder.get_object("btn_cancel_add").connect("clicked", self.cancel_add_clicked)
246                self.btn_confirm_add=builder.get_object("btn_confirm_add")
247                self.btn_confirm_add.connect("clicked", self.save_task_details)
248        #def _load_task_list_gui
249
250        def _load_manage_tasks(self,builder):
251                self.manage_box=builder.get_object("manage_box")
252                custom_grid=builder.get_object("custom_grid")
253                custom_grid.set_margin_left(WIDGET_MARGIN*2)
254                custom_grid.set_margin_top(WIDGET_MARGIN*2)
255                txt_taskname=Gtk.Entry()
256                txt_taskname.set_tooltip_text(_("A descriptive name for the command"))
257                txt_taskname.set_placeholder_text(_("Task name"))
258                lbl_name=Gtk.Label(_("Task name"))
259                lbl_name.set_halign(Gtk.Align.END)
260                btn_add_cmd=Gtk.Button.new_from_stock(Gtk.STOCK_ADD)
261                custom_grid.attach(lbl_name,0,0,1,1)
262                custom_grid.attach(txt_taskname,1,0,1,1)
263                cmb_cmds=Gtk.ComboBoxText()
264                i18n_cmd=self.load_cmb_cmds(cmb_cmds)
265                lbl_cmd=Gtk.Label(_("Command"))
266                lbl_cmd.set_halign(Gtk.Align.END)
267                custom_grid.attach(lbl_cmd,0,1,1,1)
268                custom_grid.attach(cmb_cmds,1,1,1,1)
269                custom_grid.attach(btn_add_cmd,2,1,1,1)
270                chk_parm_is_file=Gtk.CheckButton(_("Needs a file"))
271                chk_parm_is_file.set_tooltip_text(_("Mark if the command will launch a file"))
272                btn_file=Gtk.FileChooserButton()
273                chk_parm_is_file.set_tooltip_text(_("Select the file that will be launched"))
274                chk_parm_is_file.connect('toggled',self._enable_filechooser,btn_file)
275                txt_params=Gtk.Entry()
276                txt_params.set_placeholder_text(_("Needed arguments"))
277                txt_params.set_tooltip_text(_("Put here the arguments for the command (if any)"))
278                lbl_arg=Gtk.Label(_("Arguments"))
279                lbl_arg.set_halign(Gtk.Align.END)
280                custom_grid.attach(lbl_arg,3,1,1,1)
281                custom_grid.attach(txt_params,4,1,1,1)
282                custom_grid.attach(chk_parm_is_file,3,0,1,1)
283                custom_grid.attach(btn_file,4,0,1,1)
284                btn_file.set_sensitive(False)
285                self.btn_apply_manage=builder.get_object("btn_apply_manage")
286                self.btn_apply_manage.connect("clicked",self._add_custom_task,txt_taskname,cmb_cmds,txt_params,chk_parm_is_file,btn_file,i18n_cmd)
287                self.btn_back_manage=builder.get_object("btn_back_manage")
288                self.btn_back_manage.connect("clicked",self._cancel_manage_clicked)
289                self.btn_cancel_manage=builder.get_object("btn_cancel_manage")
290                self.btn_cancel_manage.connect("clicked",self._cancel_manage_clicked)
291                btn_add_cmd.connect("clicked",self._add_cmd_clicked,cmb_cmds)
292        #def _load_manage_tasks
293
294        def load_cmb_cmds(self,cmb_cmds):
295                cmb_cmds.remove_all()
296                cmds=self.scheduler.get_commands()
297                i18n_cmd={}
298                for cmd in cmds.keys():
299                        i18n_cmd[_(cmd)]=cmd
300                        cmb_cmds.append_text(_(cmd))
301                return(i18n_cmd)
302
303        def _add_cmd_clicked(self,*args):
304                cmb_cmds=args[-1]
305                def show_file_dialog(*args):
306                        file_response=dlg_file.run()
307                        if file_response == Gtk.ResponseType.OK:
308                                txt_file.set_text(dlg_file.get_filename())
309#                       dlg_file.destroy()
310                dialog=Gtk.Dialog()
311                dialog.add_buttons(Gtk.STOCK_APPLY,42,"Close",Gtk.ResponseType.CLOSE)
312                box=dialog.get_content_area()
313                hbox=Gtk.Grid()
314                hbox.set_column_spacing(WIDGET_MARGIN)
315                hbox.set_row_spacing(WIDGET_MARGIN)
316                lbl_name=Gtk.Label(_("Action name"))
317                txt_name=Gtk.Entry()
318                txt_name.set_tooltip_text("Enter the name for the action")
319                lbl_file=Gtk.Label(_("Command"))
320                txt_file=Gtk.Entry()
321                txt_file.set_tooltip_text("Enter the command or choose one from the file selector")
322                dlg_file=Gtk.FileChooserDialog(_("Choose a command"),dialog,Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
323                btn_file=Gtk.Button.new_from_stock(Gtk.STOCK_FILE)
324                btn_file.connect("clicked",show_file_dialog)
325                hbox.attach(lbl_name,0,0,1,1)
326                hbox.attach(txt_name,1,0,1,1)
327                hbox.attach(lbl_file,0,1,1,1)
328                hbox.attach(txt_file,1,1,1,1)
329                hbox.attach(btn_file,2,1,1,1)
330                hbox.attach(Gtk.Separator(),0,2,2,1)
331                box.add(hbox)
332                box.show_all()
333                response=dialog.run()
334                if response==Gtk.ResponseType.CLOSE:
335                        dialog.destroy()
336                if response==42:
337                        self._add_custom_cmd(txt_name.get_text(),txt_file.get_text())
338                        self.load_cmb_cmds(cmb_cmds)
339        #def _add_cmd_clicked
340
341        def _add_custom_cmd(self,name,cmd):
342                self.scheduler.add_command(name,cmd)
343       
344        def _enable_filechooser(self,widget,filechooser):
345                if widget.get_active():
346                        filechooser.set_sensitive(True)
347                else:
348                        filechooser.set_sensitive(False)
349        #def _enable_filechooser
350
351        def _add_custom_task(self,widget,w_name,w_cmd,w_parms,w_chk,w_file,i18n_cmd=None):
352                name=w_name.get_text()
353                cmd=w_cmd.get_active_text()
354                if i18n_cmd:
355                        cmd_desc=i18n_cmd[cmd]
356                else:
357                        cmd_desc=cmd
358                parms=w_parms.get_text()
359                cmd=self.scheduler.get_command_cmd(cmd_desc)
360                if w_chk.get_active():
361                        parms=parms+' '+w_file.get_uri().replace('file://','')
362                if self.scheduler.write_custom_task(name,cmd,parms):
363                        self._show_info(_("Task saved"))
364                else:
365                        self._show_info(_("Permission denied"))
366        #def _add_custom_task
367
368        def _signin(self,user=None,pwd=None,server=None,data=None):
369                self.scheduler.set_credentials(user,pwd,server)
370                self.stack.set_visible_child_name("tasks")
371                self.populate_tasks_tv()
372                self.toolbar.show()
373        #def _signin
374
375        def populate_tasks_tv(self,sw_remote=False):
376                self._debug("Populating task list")
377                self.scheduled_tasks={}
378                tasks=[]
379                sw_tasks=False
380                tasks=self.scheduler.get_scheduled_tasks(sw_remote)
381                self.tasks_store.clear()
382                if type(tasks)==type({}):       
383                        parser=cronParser()
384                        self.i18n['cmd']={}
385                        self.i18n['name']={}
386                        for task_name in tasks.keys():
387                                for serial in tasks[task_name].keys():
388                                        task=tasks[task_name][serial]
389                                        task['sw_remote']=''
390                                        color_palette=['goldenrod','DarkSlateGrey','Burlywood','DarkSlateGrey','DarkSlateBlue','bisque','LightSteelBlue','DarkSlateGrey']
391                                        bg_color=color_palette[0]
392                                        fg_color=color_palette[1]
393                                        if 'kind' in task.keys():
394                                                if 'fixed' in task['kind']:
395                                                        bg_color=color_palette[2]
396                                                        fg_color=color_palette[3]
397                                                elif 'repeat' in task['kind']:
398                                                        bg_color=color_palette[4]
399                                                        fg_color=color_palette[5]
400                                                elif 'daily' in task['kind']:
401                                                        bg_color=color_palette[6]
402                                                        fg_color=color_palette[7]
403                                        else:
404                                                task['kind']=''
405                                        remote='Local task'
406                                        if 'spread' in task.keys():
407                                                if task['spread']==True:
408                                                        remote="Client task"
409                                        else:
410                                                task['spread']=False
411                                        self.scheduled_tasks[task_name]=tasks[task_name]
412                                        sw_tasks=True
413                                        parsed_calendar=''
414                                        parsed_calendar=parser.parse_taskData(task)
415                                        task['cmd']=task['cmd'].replace(self.ldm_helper+' ','')
416                                        task['action']=self.scheduler.get_task_description(task['cmd'])
417                                        if 'name' in task.keys():
418                                                name=task['name']
419                                        else:
420                                                name=_(task['action'])
421                                        self.i18n['cmd'].update({name:task['action']})
422                                        self.i18n['name'].update({_(task_name):task_name})
423                                        img=self.edit_icon
424                                        if 'protected' in task.keys():
425                                                if task['protected']==True:
426                                                        img=self.no_edit_icon
427                                        row=self.tasks_store.append(("<span font='Roboto'><b>"+name+"</b></span>\n"+\
428                                                                "<span font='Roboto' size='small'><i>"+\
429                                                                _(task_name)+"</i></span>",serial,"<span font='Roboto' size='small'>"+\
430                                                                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))
431        #def populate_tasks_tv
432       
433        def filter_tasklist(self,model,iterr,data):
434                sw_match=True
435                match=self.txt_search.get_text().lower()
436                task_data=model.get_value(iterr,0).split('\n')
437                task_sched_data=model.get_value(iterr,2).split('\n')
438                task_cmd=task_data[0][task_data[0].find("<b>")+3:task_data[0].find("</b>")]
439                task_name=task_data[1][task_data[1].find("<i>")+3:task_data[1].find("</i>")]
440                task_sched=task_sched_data[0][task_sched_data[0].find("ll'>")+4:task_sched_data[0].find("</span>")]
441
442                task_text=task_cmd+' '+task_name+' '+task_sched
443                if match and match not in task_text.lower():
444                        sw_match=False
445                return sw_match
446        #def filter_tasklist
447
448        def match_tasks(self,widget):
449                self.tasks_store_filter.refilter()
450                GObject.timeout_add(100,self.tasks_tv.set_cursor,0)
451        #def match_tasks
452
453        def _process_model(self,model,data):
454                task={}
455                task['data']=model[data][0].split('\n')
456                if _("client task") in model[data][2]:
457                        task['spread']=True
458                else:
459                        task['spread']=False
460                task['serial']=model[data][1].split('\n')[0]
461                cmd=task['data'][0][task['data'][0].find("<b>")+3:task['data'][0].find("</b>")]
462                if cmd in self.i18n['cmd'].keys():
463                        task['cmd']=self.i18n['cmd'][cmd]
464                else:
465                        task['cmd']=cmd
466
467                name=task['data'][1][task['data'][1].find("<i>")+3:task['data'][1].find("</i>")]
468                if name in self.i18n['name'].keys():
469                        task['name']=self.i18n['name'][name]
470                else:
471                        task['name']=name
472
473                task['serial']=model[data][1]
474                return(task)
475
476        def _click_on_list(self,event):
477                action=''
478                try:
479                        row=self.tasks_tv.get_path_at_pos(int(event.x),int(event.y))
480                except Exception as e:
481                        self._debug(e)
482                if row:
483                        if row[1]==self.col_remove:
484                                action='remove'
485                        elif row[1]==self.col_edit:
486                                action='edit'
487                self._debug(action)
488                return action
489
490        def task_clicked(self,treeview,event=None):
491                self._debug("task clicked %s"%event)
492                selection=self.tasks_tv.get_selection()
493                model,data=selection.get_selected()
494                if not data:
495                        return
496                task={}
497                action=''
498                if event!=None:
499                        action=self._click_on_list(event)
500                task=self._process_model(model,data)
501                if action=='remove':
502                        self.lbl_question.set_text(_("Are you sure to delete this task?"))
503                        for widget in self.main_box.get_children():
504                                widget.set_sensitive(False)
505                        self.inf_question.set_sensitive(True)
506                        self.inf_question.show_all()
507                        try:
508                                self.inf_question.disconnect_by_func(self.manage_remove_responses)
509                        except:
510                                pass
511                        self.inf_question.connect('response',self.manage_remove_responses,model,task)
512                elif action=='edit':
513                        if task['name'] in self.scheduled_tasks.keys():
514                                if task['serial'] in self.scheduled_tasks[task['name']].keys():
515                                        task['data']=self.scheduled_tasks[task['name']][task['serial']]
516                                        self._debug("Loading details of task %s of group %s"% (task['serial'],task['name']))
517                                        self.add_task_grid.set_task_data(task)
518                                        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
519                                        self.cmb_task_names.remove_all()
520                                        self.cmb_task_cmds.remove_all()
521                                        self.cmb_task_names.append_text(_(task['name']))
522                                        self.cmb_task_cmds.append_text(_(task['cmd']))
523                                        self.cmb_task_names.set_active(0)
524                                        self.cmb_task_cmds.set_active(0)
525                                        self.add_task_grid.load_task_details()
526                                        if 'protected' in task['data'].keys():
527                                                if task['data']['protected']:
528                                                        self.btn_confirm_add.set_sensitive(False)
529                                        else:
530                                                self.btn_confirm_add.set_sensitive(True)
531                                        self.stack.set_visible_child_name("add")
532        #def task_clicked                       
533
534        def save_task_details(self,widget):
535                task={}
536                name=self.cmb_task_names.get_active_text()
537                task['name']=self.i18n['name'][name]
538                action=self.cmb_task_cmds.get_active_text()
539                i18n_action=self.i18n['cmd'][action]
540                tasks=self.scheduler.get_available_tasks()
541                task['cmd']=tasks[task['name']][i18n_action]
542                self.add_task_grid.update_task_data(task)
543                task=self.add_task_grid.get_task_details()
544
545                self._debug("Writing task info...%s"%task)
546                for key in task.keys():
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,*args):
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.