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

Last change on this file since 6718 was 6718, checked in by Juanma, 3 years ago

WIP on basic mode

File size: 18.0 KB
Line 
1#!/usr/bin/env python3
2
3# -*- coding: utf-8 -*-
4import gi
5gi.require_version('Gtk', '3.0')
6gi.require_version('PangoCairo', '1.0')
7import json
8import cairo
9import os
10import subprocess
11import shutil
12import threading
13import platform
14import subprocess
15import sys
16import time
17#import commands
18from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib, PangoCairo, Pango
19import time
20from taskscheduler.cronParser import cronParser
21
22import gettext
23gettext.textdomain('taskscheduler')
24_ = gettext.gettext
25
26
27WIDGET_MARGIN=6
28DBG=1
29
30class DetailBox:
31       
32        def __init__(self,scheduler,expert_mode=False):
33                self.expert_mode=expert_mode
34                self.scheduler_client=scheduler
35                self.parser=cronParser()
36                self.task_serial="0"
37                self.task_type="remote"
38                self.btn_apply=Gtk.Button(stock=Gtk.STOCK_APPLY)
39                try:
40                        self.flavour=subprocess.getoutput("lliurex-version -f")
41                except:
42                        self.flavour="client"
43                self.ldm_helper='/usr/sbin/sched-ldm.sh'
44
45        def _debug(self,msg):
46                if DBG:
47                        print("taskDetails: %s"%msg)
48        #def _debug
49
50        def _format_widget_for_grid(self,widget):
51                #common
52                widget.set_hexpand(False)
53                widget.set_halign(Gtk.Align.CENTER)
54                widget.set_valign(Gtk.Align.CENTER)
55                if 'Gtk.Button' in str(type(widget)):
56                        pass
57                elif 'Gtk.Entry' in str(type(widget)):
58                        widget.set_alignment(xalign=0.5)
59                        widget.set_max_length(2)
60                        widget.set_width_chars(2)
61                        widget.set_max_width_chars(3)
62        #def _format_widget_for_grid
63
64        def _load_interval_data(self,widget=None,handler=None):
65                if handler:
66                        self.cmb_interval.handler_block(handler)
67                position=self.cmb_interval.get_active()
68                self.cmb_interval.remove_all()
69                date=self.cmb_dates.get_active_text()
70                total=24
71                if date==_("day(s)"):
72                        total=7
73                elif date==_("hour(s)"):
74                        total=24
75                elif date==_("week(s)"):
76                        total=4
77                elif date==_("month(s)"):
78                        total=12
79                for i in range(total):
80                        self.cmb_interval.append_text(str(i+1))
81
82                #Set sensitive status
83                self._changed_interval()
84                #If user changes selection try to activate same value on new interval data or max
85                if position>=total:
86                        position=total-1
87                elif position<0:
88                        position=0
89                self.cmb_interval.set_active(position)
90                if handler:
91                        self.cmb_interval.handler_unblock(handler)
92                        self._parse_scheduled(True)
93        #def _load_interval_data
94       
95        def _load_date_data(self):
96                date=[_("hour(s)"),_("day(s)"),_("week(s)"),_("month(s)")]
97                for i in date:
98                        self.cmb_dates.append_text(i)
99                self.cmb_dates.set_active(0)
100        #def _load_date_data
101       
102        def _load_special_date_data(self):
103                date=[_("Last month day"),_("First month day")]
104                for i in date:
105                        self.cmb_special_dates.append_text(i)
106                self.cmb_special_dates.set_active(0)
107        #def _load_special_date_data
108
109        def _load_date_time_data(self,date_type):
110                inc=0
111                jump=0
112                time_units=0
113                if date_type=='hour':
114                        time_units=24
115                        widget=self.cmb_hours
116                elif date_type=='minute':
117                        time_units=60
118                        jump=5
119                        widget=self.cmb_minutes
120                elif date_type=='month':
121                        widget=self.cmb_months
122                        widget.append_text(_("Every month"))
123                        inc=1
124                        time_units=12
125                elif date_type=='day':
126                        widget=self.cmb_days
127                        widget.append_text(_("Every day"))
128                        inc=1
129                        time_units=31
130
131                for i in range(time_units):
132                        if jump:
133                                if (not i%jump):
134                                        widget.append_text(str(i+inc))
135                        else:
136                                widget.append_text(str(i+inc))
137                widget.set_active(0)
138        #def _load_date_time_data
139
140        def render_form(self,gtkGrid,btn_apply=True):
141                self.chk_monday=Gtk.ToggleButton(_("Monday"))
142                self.chk_thursday=Gtk.ToggleButton(_("Tuesday"))
143                self.chk_wednesday=Gtk.ToggleButton(_("Wednesday"))
144                self.chk_tuesday=Gtk.ToggleButton(_("Thursday"))
145                self.chk_friday=Gtk.ToggleButton(_("Friday"))
146                self.chk_saturday=Gtk.ToggleButton(_("Saturday"))
147                self.chk_sunday=Gtk.ToggleButton(_("Sunday"))
148                self.chk_daily=Gtk.CheckButton(_("Daily"))
149                self.chk_hourly=Gtk.CheckButton(_("Hourly"))
150                self.chk_weekly=Gtk.CheckButton(_("Weekly"))
151                self.chk_interval=Gtk.CheckButton(_("Interval"))
152                self.cmb_interval=Gtk.ComboBoxText()
153                self.cmb_dates=Gtk.ComboBoxText()
154                self.chk_special_dates=Gtk.CheckButton(_("Last month day"))
155                self.day_box=Gtk.Box()
156                self.day_box.set_homogeneous(True)
157                self.cmb_days=Gtk.ComboBoxText()
158                self.day_box.add(Gtk.Label(_("Day")))
159                self.day_box.add(self.cmb_days)
160                self.month_box=Gtk.Box()
161                self.month_box.set_homogeneous(True)
162                self.cmb_months=Gtk.ComboBoxText()
163                self.month_box.add(Gtk.Label(_("Month")))
164                self.month_box.add(self.cmb_months)
165                self.hour_box=Gtk.Box()
166                self.hour_box.set_homogeneous(True)
167                self.cmb_hours=Gtk.ComboBoxText()
168                self.hour_box.add(Gtk.Label(_("Hour")))
169                self.hour_box.add(self.cmb_hours)
170                self.minute_box=Gtk.Box()
171                self.minute_box.set_homogeneous(True)
172                self.cmb_minutes=Gtk.ComboBoxText()
173                self.minute_box.add(Gtk.Label(_("Minutes")))
174                self.minute_box.add(self.cmb_minutes)
175
176                self._load_interval_data()
177                self._load_date_data()
178
179                self.lbl_info=Gtk.Label("")
180                self.lbl_info.set_line_wrap(True)
181                self.lbl_info.set_max_width_chars(20)
182                self.lbl_info.set_width_chars(20)
183                self.lbl_info.set_opacity(0.6)
184                gtkGrid.attach(self.lbl_info,0,0,4,1)
185                self.lbl_info.set_margin_bottom(24)
186                dow_frame=Gtk.Frame()
187                dow_frame.set_shadow_type(Gtk.ShadowType.OUT)
188                frame_box=Gtk.Box(orientation=Gtk.Orientation.VERTICAL,spacing=6)
189                dow_frame.add(frame_box)
190                label=Gtk.Label(_("Days of week"))
191                frame_box.add(label)
192                frame_box.set_margin_bottom(6)
193                frame_box.set_margin_top(6)
194                frame_box.set_margin_left(6)
195                frame_box.set_margin_right(6)
196                dow_box=Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
197                work_days_box=Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
198                work_days_box.add(self.chk_monday)
199                work_days_box.add(self.chk_tuesday)
200                work_days_box.add(self.chk_wednesday)
201                work_days_box.add(self.chk_thursday)
202                work_days_box.add(self.chk_friday)
203                work_days_box.set_focus_chain([self.chk_monday,self.chk_tuesday,self.chk_wednesday,self.chk_thursday,self.chk_friday])
204                dow_box.add(work_days_box)
205                weekend_days_box=Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
206                dow_box.add(weekend_days_box)
207                weekend_days_box.add(self.chk_saturday)
208                weekend_days_box.add(self.chk_sunday)
209                weekend_days_box.set_focus_chain([self.chk_saturday,self.chk_sunday])
210                dow_box.set_focus_chain([work_days_box,weekend_days_box])
211                frame_box.add(dow_box)
212                label=Gtk.Label()
213                label.set_margin_bottom(WIDGET_MARGIN)
214                self.interval_box=Gtk.Box()
215                if self.expert_mode:
216                        label.set_text(_("Time & date"))
217                        minBoxPos=Gtk.PositionType.BOTTOM
218                        labelCol=1
219                        dowCol=0
220                        gtkGrid.attach(dow_frame,0,1,1,6)
221                        gtkGrid.attach(label,1,1,1,1)
222                        gtkGrid.attach_next_to(self.hour_box,label,Gtk.PositionType.BOTTOM,1,1)
223                        gtkGrid.attach_next_to(self.minute_box,self.hour_box,Gtk.PositionType.BOTTOM,1,1)
224                        gtkGrid.attach_next_to(self.month_box,self.minute_box,Gtk.PositionType.BOTTOM,1,1)
225                        gtkGrid.attach_next_to(self.day_box,self.month_box,Gtk.PositionType.BOTTOM,1,1)
226                        label=Gtk.Label(_("Time intervals"))
227                        label.set_margin_bottom(WIDGET_MARGIN)
228                        gtkGrid.attach(label,2,1,2,1)
229                        gtkGrid.attach_next_to(self.chk_interval,label,Gtk.PositionType.BOTTOM,1,1)
230                        self.interval_box.add(Gtk.Label(_("Each")))
231                        self.interval_box.add(self.cmb_interval)
232                        self.interval_box.add(self.cmb_dates)
233                        gtkGrid.attach_next_to(self.interval_box,self.chk_interval,Gtk.PositionType.BOTTOM,1,1)
234                        gtkGrid.attach_next_to(self.chk_special_dates,self.interval_box,Gtk.PositionType.BOTTOM,1,1)
235                else:
236                        label.set_text(_("Time"))
237                        gtkGrid.attach(dow_frame,1,1,1,6)
238                        gtkGrid.attach(label,2,1,1,1)
239                        gtkGrid.attach_next_to(self.hour_box,label,Gtk.PositionType.BOTTOM,1,1)
240                        gtkGrid.attach_next_to(self.minute_box,self.hour_box,Gtk.PositionType.RIGHT,1,1)
241
242                if btn_apply:
243                        self.btn_apply.set_halign(Gtk.Align.END)
244                        self.btn_apply.set_valign(Gtk.Align.END)
245                        gtkGrid.attach(self.btn_apply,4,7,2,1)
246                self.btn_mode=Gtk.CheckButton()
247                self.btn_mode.set_margin_top(12)
248                self.btn_mode.set_halign(Gtk.Align.START)
249                self.btn_mode.set_valign(Gtk.Align.START)
250                gtkGrid.attach(self.btn_mode,0,7,1,1)
251                self.btn_mode.set_label("Advanced")
252                self.btn_mode.set_active(self.expert_mode)
253
254                #Tab order chain
255                widget_array=[dow_frame,self.hour_box,self.minute_box,self.month_box,self.day_box,self.chk_interval,\
256                                                self.interval_box,self.chk_special_dates]
257                if btn_apply:
258                        widget_array.append(self.btn_apply)
259
260                gtkGrid.set_focus_chain(widget_array)
261                #Add data to combos
262                self._load_date_time_data('minute')
263                self._load_date_time_data('hour')
264                self._load_date_time_data('day')
265                self._load_date_time_data('month')
266                #handled signals
267                interval_handler=self.cmb_interval.connect("changed",self._parse_scheduled)
268                #Signals
269                self.chk_monday.connect("toggled",self._enable_fixed_dates,interval_handler)
270                self.chk_thursday.connect("toggled",self._enable_fixed_dates,interval_handler)
271                self.chk_wednesday.connect("toggled",self._enable_fixed_dates,interval_handler)
272                self.chk_tuesday.connect("toggled",self._enable_fixed_dates,interval_handler)
273                self.chk_friday.connect("toggled",self._enable_fixed_dates,interval_handler)
274                self.chk_saturday.connect("toggled",self._enable_fixed_dates,interval_handler)
275                self.chk_sunday.connect("toggled",self._enable_fixed_dates,interval_handler)
276                self.chk_interval.connect("toggled",self._chk_interval_status)
277                self.chk_special_dates.connect("toggled",self._chk_special_dates_status)
278                self.cmb_dates.connect("changed",self._load_interval_data,interval_handler)
279                self.cmb_handler={}
280                self.cmb_handler[self.cmb_months]=self.cmb_months.connect("changed",self._parse_scheduled)
281                self.cmb_handler[self.cmb_days]=self.cmb_days.connect("changed",self._parse_scheduled)
282                self.cmb_handler[self.cmb_hours]=self.cmb_hours.connect("changed",self._parse_scheduled)
283                self.cmb_handler[self.cmb_minutes]=self.cmb_minutes.connect("changed",self._parse_scheduled)
284                gtkGrid.connect("event",self._parse_scheduled)
285                self.btn_mode.connect("toggled",self._enable_expert_mode,gtkGrid,btn_apply)
286
287                #Initial control status
288                self.interval_box.set_sensitive(False)
289                #signals
290                return (gtkGrid)
291        #def render_form
292
293        def _enable_expert_mode(self,widget,gtkgrid,btn_apply):
294                self.expert_mode=self.btn_mode.get_active()
295                for grid_widget in gtkgrid.get_children():
296                        gtkgrid.remove(grid_widget)
297                parent=gtkgrid.get_parent()
298                parent.remove(gtkgrid)
299                gtkgrid=self.render_form(gtkgrid,btn_apply)
300                parent.add(gtkgrid)
301                parent.show_all()
302
303
304        def load_task_details(self,task_name,task_serial,task_data,task_type):
305                self.clear_screen()
306                for widget,handler in self.cmb_handler.items():
307                        widget.handler_block(handler)
308                self.task_name=task_name
309                self.task_serial=task_serial
310                self.task_cmd=task_data['cmd']
311                self.task_type=task_type
312                self.lbl_info.set_text('')
313                if task_data['m'].isdigit():
314                        cursor=0
315                        for minute in range(0,60,5):
316                                if minute>int(task_data['m']):
317                                        break
318                                cursor+=1
319                        self.cmb_minutes.set_active(cursor-1)
320                else:
321                        self.cmb_minutes.set_active(0)
322
323                self._parse_date_details(task_data['h'],self.cmb_hours,'hour')
324                self._parse_date_details(task_data['dom'],self.cmb_days,'dom')
325                self._parse_date_details(task_data['mon'],self.cmb_months,'mon')
326                widget_dict={'0':self.chk_sunday,'1':self.chk_monday,'2':self.chk_tuesday,\
327                                        '3':self.chk_wednesday,'4':self.chk_thursday,'5':self.chk_friday,\
328                                        '6':self.chk_saturday,'7':self.chk_sunday}
329                self._parse_date_details(task_data['dow'],None,'dow',widget_dict)
330                if 'lmd' in task_data.keys():
331                        self.chk_special_dates.set_active(True)
332                for widget,handler in self.cmb_handler.items():
333                        widget.handler_unblock(handler)
334        #def load_task_details
335
336        def _parse_date_details(self,date,widget=None,date_type=None,widget_dict=None):
337                if date.isdigit() and widget:
338                        widget.set_active(int(date))
339                elif '/' in date:
340                        pos=date.split('/')
341                        self.chk_interval.set_active(True)
342                        self.cmb_interval.set_active(int(pos[1])-1)
343                        if date_type=='hour':
344                                self.cmb_dates.set_active(0)
345                                self.hour_box.set_sensitive(False)
346                        elif date_type=='dom':
347                                self.cmb_dates.set_active(1)
348                                self.day_box.set_sensitive(False)
349                                self.hour_box.set_sensitive(True)
350                        elif date_type=='mon':
351                                self.cmb_interval.set_active(int(pos[1])-1)
352                                self.cmb_dates.set_active(3)
353                                self.month_box.set_sensitive(False)
354                                self.hour_box.set_sensitive(True)
355                elif widget_dict:
356                        array_date=[]
357                        if ',' in date:
358                                array_date=date.split(',')
359                        else:
360                                array_date.append(date)
361
362                        for selected_date in array_date:
363                                if selected_date.isdigit():
364                                        widget_dict[selected_date].set_active(True)
365        #def _parse_date_details
366
367        def clear_screen(self):
368                widgets=[self.chk_monday,self.chk_thursday,self.chk_wednesday,self.chk_tuesday,\
369                                self.chk_friday,self.chk_saturday,self.chk_sunday]
370                for widget in widgets:
371                        widget.set_active(False)
372                self.cmb_hours.set_active(0)
373                self.cmb_minutes.set_active(0)
374                self.cmb_days.set_active(0)
375                self.cmb_months.set_active(0)
376                self.cmb_interval.set_active(0)
377                self.cmb_dates.set_active(0)
378                self.chk_special_dates.set_active(False)
379                self.chk_interval.set_active(False)
380        #def clear_screen
381       
382        def _set_sensitive_widget(self,widget_dic):
383                for widget,status in widget_dic.items():
384                        widget.set_sensitive(status)
385        #def _set_sensitive_widget
386       
387        def _changed_interval(self):
388                if self.chk_interval.get_active():
389                        interval=self.cmb_dates.get_active_text()
390                        if interval==_('hour(s)'):
391                                self._set_sensitive_widget({self.day_box:not self._get_days_active(),\
392                                                self.month_box:True,self.hour_box:False})
393                                self._set_days_sensitive(True)
394                        elif interval==_('day(s)') or interval==_('week(s)'):
395                                self._set_sensitive_widget({self.day_box:False,self.month_box:True,self.hour_box:True})
396                                self._set_days_sensitive(False)
397                        elif interval==_('month(s)'):
398                                self._set_sensitive_widget({self.day_box:not self._get_days_active(),\
399                                                self.month_box:False,self.hour_box:True})
400                                self._set_days_sensitive(True)
401                self._chk_special_dates_status()
402        #def _changed_interval
403
404
405        def _chk_interval_status(self,widget):
406                if self.chk_interval.get_active():
407                        self._set_sensitive_widget({self.interval_box:True,\
408                                self.hour_box:False,self.month_box:True,self.day_box:not self._get_days_active()})
409                        self._changed_interval()
410                else:
411                        self._set_sensitive_widget({self.interval_box:False,\
412                                self.hour_box:True,self.month_box:True,self.day_box:not self._get_days_active()})
413                self._chk_special_dates_status()
414        #def _chk_interval_status
415                       
416        def _chk_special_dates_status(self,widget=None):
417                if self.chk_special_dates.get_active():
418                        self._set_sensitive_widget({self.hour_box:True,self.month_box:True,self.day_box:False})
419                        self._set_days_sensitive(False)
420                else:
421                        self._set_sensitive_widget({self.day_box:not self._get_days_active()})
422                        self._set_days_sensitive(True)
423        #def _chk_special_dates_status
424
425        def _get_days_active(self):
426                sw_active=False
427                widgets=[self.chk_monday,
428                                self.chk_thursday,
429                                self.chk_wednesday,
430                                self.chk_tuesday,
431                                self.chk_friday,
432                                self.chk_saturday,
433                                self.chk_sunday]
434                for widget in widgets:
435                        if widget.get_active():
436                                sw_active=True
437                                break
438                return sw_active
439        #def _get_days_active
440
441        def _enable_fixed_dates(self,widget,handler=None):
442                sw_enable=True
443                sw_enable=self._get_days_active()
444                if sw_enable:
445                        if self.chk_interval.get_active():
446                                self._load_interval_data(True,handler)
447                                self.day_box.set_sensitive(False)
448                        else:
449                                self.month_box.set_sensitive(True)
450                                self.day_box.set_sensitive(False)
451                else:
452                        if self.chk_interval.get_active():
453                                self._load_interval_data(True,handler)
454                        else:
455                                self.day_box.set_sensitive(True)
456                                self.month_box.set_sensitive(True)
457        #def _enable_fixed_dates
458
459        def _set_days_sensitive(self,state):
460                if self.chk_special_dates.get_active():
461                        state=False
462                widgets=[self.chk_monday,
463                                self.chk_thursday,
464                                self.chk_wednesday,
465                                self.chk_tuesday,
466                                self.chk_friday,
467                                self.chk_saturday,
468                                self.chk_sunday]
469                for widget in widgets:
470                        widget.set_sensitive(state)
471        #def _set_days_sensitive
472
473        def _parse_screen(self):
474                details={}
475                dow=''
476                widgets=[self.chk_monday,self.chk_thursday,     self.chk_wednesday,     self.chk_tuesday,\
477                                self.chk_friday,self.chk_saturday,self.chk_sunday]
478                cont=1
479                for widget in widgets:
480                        if widget.get_active() and widget.get_sensitive():
481                                dow+=str(cont)+','
482                        cont+=1
483                if dow!='':
484                        dow=dow.rstrip(',')
485                else:
486                        dow='*'
487                details['dow']=dow
488                #Init date data
489                for i in ["h","m","mon","dom"]:
490                        details[i]="*"
491                #load data
492                if self.cmb_hours.is_sensitive():
493                        details["h"]=self.cmb_hours.get_active_text()
494                if self.cmb_minutes.is_sensitive():
495                        details["m"]=self.cmb_minutes.get_active_text()
496                if self.cmb_months.is_sensitive():
497                        if self.cmb_months.get_active_text().isdigit():
498                                details["mon"]=self.cmb_months.get_active_text()
499                if self.cmb_days.is_sensitive():
500                        if self.cmb_days.get_active_text().isdigit():
501                                details["dom"]=self.cmb_days.get_active_text()
502
503                if self.cmb_dates.is_sensitive():
504                        if self.cmb_dates.get_active_text()==_('hour(s)'):
505                                details['h']="0/"+self.cmb_interval.get_active_text()
506                        if self.cmb_dates.get_active_text()==_('day(s)'):
507                                details['dom']="1/"+self.cmb_interval.get_active_text()
508                        if self.cmb_dates.get_active_text()==_('week(s)'):
509                                week=int(self.cmb_interval.get_active_text())*7
510                                details['dom']="1/"+str(week)
511                        if self.cmb_dates.get_active_text()==_('month(s)'):
512                                details['mon']="1/"+self.cmb_interval.get_active_text()
513                details['hidden']=0
514                if self.chk_special_dates.get_active():
515                        details['lmd']=1
516                        details['dom']='*'
517                        details['dow']='*'
518                return details
519        #def _parse_screen
520
521        def _parse_scheduled(self,container=None,widget=None):
522                details=self._parse_screen()
523                self.lbl_info.set_text(self.parser.parse_taskData(details))
524        #def _parse_scheduled
525
526        def update_task_details(self,widget=None):
527                if self.task_name and self.task_serial:
528                        task_data=self.get_task_details()
529                        return self.scheduler_client.write_tasks(task_data,self.task_type)
530        #def update_task_details
531
532        def get_task_details(self,widget=None,task_name=None,task_serial=None,task_cmd=None,task_type=None):
533                if task_name:
534                        self.task_name=task_name
535                if task_serial:
536                        self.task_serial=task_serial
537                if task_cmd:
538                        self.task_cmd=task_cmd
539                if task_type:
540                        self.task_type=task_type
541                details=self._parse_screen()
542                details['cmd']=self.scheduler_client.get_task_command(self.task_cmd)
543                if 'lmd' in details.keys():
544                        details['cmd']=self.ldm_helper+' '+details['cmd']
545                task={}
546                task[self.task_name]={self.task_serial:details}
547                self._debug("Saving %s"%task)
548                return task
549        #def get_task_details
Note: See TracBrowser for help on using the repository browser.