source: scheduler/trunk/fuentes/scheduler.install-files/usr/sbin/scheduler @ 581

Last change on this file since 581 was 581, checked in by jrpelegrina, 3 years ago

First release to xenial

  • Property svn:executable set to *
File size: 12.3 KB
Line 
1#!/usr/bin/python
2#  This program is free software; you can redistribute it and/or modify
3#  it under the terms of the GNU General Public License as published by
4#  the Free Software Foundation; either version 2 of the License, or
5#  (at your option) any later version.
6
7#  This program is distributed in the hope that it will be useful,
8#  but WITHOUT ANY WARRANTY; without even the implied warranty of
9#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10#  GNU General Public License for more details.
11
12#  You should have received a copy of the GNU General Public License
13#  along with this program; if not, write to the Free Software
14#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15#  MA 02110-1301, USA.
16
17
18from calendar import day_name
19from gi.repository import Gtk
20import random, os,sys
21import gettext
22
23MAX_CHKS = 168
24
25class DialogWindow(Gtk.Dialog):
26
27        def __init__(self, parent, title, message):
28                Gtk.Dialog.__init__(self, title, parent, 0,(Gtk.STOCK_OK, Gtk.ResponseType.OK))
29                lns1= Gtk.Separator(expand=True)
30                lns2= Gtk.Separator(expand=True)
31                self.set_default_size(len(message)*7, 100)
32
33                label = Gtk.Label(message)
34
35                box = self.get_content_area()
36                box.add(lns1)
37                box.add(label)
38                box.add(lns2)
39                self.show_all()
40
41class Scheduler(Gtk.Window):
42
43        def __init__(self, program_to_execute):
44                Gtk.Window.__init__(self, title=_("Scheduler"))
45                self.dayButtons = [Gtk.Button]*7
46                hourButtons = [Gtk.Button]*24
47                self.chkProg = [Gtk.CheckButton]*MAX_CHKS
48                self.checkDay={}
49                self.checkHour={}
50               
51                mainBox = Gtk.VBox(spacing=10)
52                grid = Gtk.Grid()
53                mainBox.add(grid)
54
55                separator= Gtk.Separator(expand=True)
56                mainBox.add(separator)
57
58                optBox = Gtk.HBox(spacing=2)
59                mainBox.add(optBox)
60
61                bottomBox = Gtk.HBox(spacing=2)
62                mainBox.add(bottomBox)
63
64                separator2= Gtk.Separator(expand=True)
65                mainBox.add(separator2)
66
67                self.add(mainBox)
68
69                # day buttons
70                for i in range(7):
71                        self.dayButtons[i]=Gtk.Button(day_name[i].capitalize(),relief="none",image_position="left")
72                        self.dayButtons[i].connect("clicked",self.on_click,i)
73                        self.dayButtons[i].set_name='btD'+`i`
74                        grid.attach(self.dayButtons[i], 0, i+1, 1, 1)
75                # hour buttons
76                for i in range(24):
77                        hourLabel= Gtk.Label(`i`+":00",angle = 90)
78                        hourButtons[i]=Gtk.Button(relief="none")
79                        hourButtons[i].add(hourLabel)
80                        hourButtons[i].set_name='btH'+`i`
81                        hourButtons[i].connect("clicked",self.on_click,i+10)
82                        grid.attach(hourButtons[i], i+1, 0, 1, 1)
83
84                # checkboxes associated to hours and days
85                for i in range(7):
86                        self.checkDay[i]=[[],False]
87                        for j in range(24):
88                                self.chkProg[i*24+j] = Gtk.CheckButton(draw_indicator=True, can_focus = True, use_underline = True)
89                                self.chkProg[i*24+j].set_name='chk'+`i`+'_'+`j`
90                                grid.attach(self.chkProg[i*24+j], j+1, i+1, 1, 1)
91                                self.checkDay[i][0].append(self.chkProg[i*24+j])
92
93                for i in range(24):
94                        self.checkHour[i]=[[],False]
95                        for j in range(7):
96                                self.checkHour[i][0].append(self.chkProg[j*24+i])
97
98               
99                self.entryShell=Gtk.Entry()
100                # set program given as paramerater
101                self.entryShell.set_text(program_to_execute)
102                # update combobox
103                self.entryShell.connect("key-press-event",self.on_text_mod)
104                # check if exist previous selection
105                self.entryShell.connect("focus-out-event",self.check_prg)
106
107                img=Gtk.Image()
108                img.set_from_stock("gtk-open",Gtk.IconSize.BUTTON)
109                openBtn=Gtk.Button()
110                openBtn.add(img)
111                openBtn.connect("clicked",self.on_click_search)
112
113                optBox.pack_start(self.entryShell, True, True, 4)
114                optBox.pack_start(openBtn, False, False, 1)
115               
116                self.optLst = Gtk.ListStore(int, str, str)
117                self.optLst.append([0, "", _("Custom")])
118                self.read_prgs_conffile()
119
120
121                self.dfltOpt = Gtk.ComboBox.new_with_model_and_entry(self.optLst)
122                self.dfltOpt.connect("changed", self.on_dfltOpt_changed)
123                self.dfltOpt.set_entry_text_column(2)
124                self.dfltOpt.set_active(0)
125                optBox.pack_end(self.dfltOpt, False, True, 4)
126
127                adjustment = Gtk.Adjustment(0, 0, 100, 1, 10, 0)
128                self.selQty = Gtk.SpinButton()
129                self.selQty.set_adjustment(adjustment)
130                btRnd=Gtk.Button(_("Random"))
131                btRnd.connect("clicked",self.random_chk)
132                btClean=Gtk.Button(_("Clean"))
133                btClean.connect("clicked",self.clean_chk)
134                btApply=Gtk.Button(_("Apply"))
135                btApply.connect("clicked",self.save_prg_selections)
136                btListApps=Gtk.Button(_("List programmed applications"))
137                btListApps.connect("clicked", self.show_apps)
138                btEnd=Gtk.Button(_("Exit"))
139                btEnd.connect("clicked", Gtk.main_quit)
140
141                bottomBox.pack_start(self.selQty, False, True, 4)
142                bottomBox.pack_start(btRnd, False, True, 4)
143                bottomBox.pack_start(btClean, False, True, 4)
144                bottomBox.pack_start(btApply, False, True, 4)
145                bottomBox.pack_end(btEnd, False, True, 4)
146                bottomBox.pack_end(btListApps, False, True, 4)
147
148        # returns number of inactive checkboxes
149        def active_ops(self):
150                try:
151                        n=0
152                        for i in range(MAX_CHKS):
153                                if self.chkProg[i].get_active():
154                                        n+=1
155                        n = MAX_CHKS - n
156                except Exception as e:
157                        print e
158                       
159                return n
160
161
162        # check if given program has previous configurations
163        #if it has, then function loads them on scheduler
164        def check_prg(self, widget, data):
165                for files in os.listdir('/etc/cron.d/'):
166                        if files.endswith('scheduler'):
167                                if  self.get_prg_name() == files.split('.')[0]:
168                                        messageBox(self.get_prg_name(), _("Restored previous configuration"))
169                                        self.read_config_data()
170
171
172        #deactivate all checkboxes
173        def clean_chk(self,widget):
174                try:
175                        for i in range(MAX_CHKS):
176                                self.chkProg[i].set_active(False)
177                               
178                except Exception as e:
179                        print e
180
181        def generate_cron_file(self, full_path):
182                fileName = "/etc/cron.d/"+self.get_prg_name()+"_scheduler"
183                if not fileName.find('mirror') == -1:
184                        minute = random.randint(0, 60)
185                else:
186                        minute = 0
187
188                exist = False
189                created = False
190
191                if os.path.exists(fileName):
192                        try:
193                                os.remove(fileName)
194                                exist=True
195                        except:
196                                print "Exception: ",str(sys.exc_info())
197
198
199                try:
200                        if (MAX_CHKS - self.active_ops()) > 0:
201                                created = True
202
203                                f=open(fileName,"w")
204                                f.write("SHELL=/bin/bash\n")
205                                f.write("PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n")
206
207                                for day in range(7):
208                                        hours = ""
209                                        count = 0
210                                        for j in range(24):
211                                                if self.chkProg[day*24+j].get_active():
212                                                        hours = hours + `j` +','
213                                                        count+=1
214
215                                        if count > 0 :
216                                                if count == 24 :
217                                                        hours = '*'
218                                                else:
219                                                        hours=hours[0:-1]
220
221                                                day+=1
222                                                f.write(`minute`+" "+hours+" *"+" * "+`day`+" root "+full_path+" > /dev/null\n")
223                                f.close()
224                               
225                except:
226                        print "Exception: ",str(sys.exc_info())
227
228                print "exist: "+`exist` + " created: " + `created`
229               
230                if exist:
231                        if created:
232                                messageBox(_("Updated Cron file"),_("Cron of ") + self.get_prg_name() + _(" updated"))
233                        else:
234                                messageBox(_("Removed Cron file"),_("Cron of ") + self.get_prg_name() + _(" removed"))
235                else:
236                        if created:
237                                messageBox(_("Created Cron file"),_("Cron of ") + self.get_prg_name() + _(" created"))
238                        else:
239                                messageBox(_("Nothing to do"),_("No selections made"))
240
241        def get_data(self,data):
242                name = ''
243                app = ''
244                if len(data.strip())<>0 and not data.startswith('#'):
245                        data=data.rstrip('\n')
246                        data= data.split('\"')
247                        name = data [1]
248                        app= data [3]
249                return(name,app)
250
251
252        def get_data_cron_format(self,data):
253                hour = ''
254                weekday = ''
255                if len(data.strip())<>0 and not data.startswith('#'):
256                        try:
257                                i=int(data[0])
258                                data=data.rstrip('\n')
259                                data= data.split(' ')
260                                hour = data [1]
261                                weekday= data [4]
262                        except:
263                                print _("ommited")
264                return(hour, weekday)
265
266
267        #get program name from textbox
268        def get_prg_name(self):
269                return(self.entryShell.get_text().split('/')[-1]).split(' ')[0]
270
271
272        def on_click(self,widget,data):
273                try:
274                        if data <10:
275                                self.checkDay[data][1]=not self.checkDay[data][1]
276                                for item in self.checkDay[data][0]:
277                                        item.set_active(self.checkDay[data][1])
278                        else:
279                                data=data-10
280                                self.checkHour[data][1]=not self.checkHour[data][1]
281                                for item in self.checkHour[data][0]:
282                                        item.set_active(self.checkHour[data][1])
283                               
284                except Exception as e:
285                        print e
286
287        def on_click_search(self,widget):
288                try:
289                        dialog = Gtk.FileChooserDialog(_("Choose binary file"), self,Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
290                        response = dialog.run()
291                        if response == Gtk.ResponseType.OK:
292                                self.dfltOpt.set_active(0)
293                                self.entryShell.set_text(dialog.get_filename())
294                                self.check_prg(self.entryShell,"")
295                        elif response == Gtk.ResponseType.CANCEL:
296                                print "Cancel clicked"
297                        dialog.destroy()
298
299                        widget.get_toplevel().child_focus(Gtk.DirectionType.TAB_FORWARD)
300                except Exception as e:
301                        print e
302
303
304        def on_dfltOpt_changed(self, combo):
305                tree_iter = combo.get_active_iter()
306                if tree_iter != None:
307                        model = combo.get_model()
308                        row_if, path_binary = model[tree_iter][:2]
309                        self.entryShell.set_text(path_binary)
310                        self.check_prg(self.entryShell,"")
311                else:
312                        combo.set_active_text("")
313
314        # on text modify change combobox to "custom"
315        def on_text_mod(self, widget,data):
316                self.dfltOpt.set_active(0)
317
318        #activate random n-given checkboxes
319        def random_chk(self,widget):
320                i =int(self.selQty.get_value())
321
322                if i > self.active_ops():
323                        messageBox(_("Atention"),_("Not enougth free hours"))
324                else:
325                        while i>0:
326                                n= random.randint(0, MAX_CHKS-1)
327                                if self.chkProg[n].get_active() == False :
328                                        self.chkProg[n].set_active(True)
329                                        i-=1
330
331        def read_config_data(self):
332                fileName = "/etc/cron.d/"+self.get_prg_name()+"_scheduler"
333                try:
334                        if os.path.exists(fileName):
335                                try:
336                                        ins = open(fileName, "r" )
337                                        for line in ins:
338                                                hours, week_day = self.get_data_cron_format(line)
339                                                if not hours == '':
340                                                        if hours == '*':
341                                                                self.dayButtons[int(week_day)-1].clicked()
342                                                        else:
343                                                                hours=hours.split(',')
344                                                                for hour in hours:
345                                                                        value = int(hour)+(int(week_day)-1)*24
346                                                                        self.chkProg[value].set_active(True)
347                                except:
348                                        print "Exception: ",str(sys.exc_info())
349                except Exception as e:
350                        print e
351
352
353        def read_prgs_conffile(self):
354                fileName = "/etc/scheduler.conf"
355                i=0
356                try:
357                        if os.path.exists(fileName):
358                                try:
359                                        ins = open(fileName, "r" )
360                                        for line in ins:
361                                                name, app = self.get_data(line)
362                                                if not name == '':
363                                                        i+=1
364                                                        self.optLst.append([i, app, _(name)])
365                                except:
366                                        print "Exception: ",str(sys.exc_info())
367                        else:
368                                print fileName + " not exist using default values"
369                                self.optLst.append([1, "/usr/sbin/lliurex-mirror-non-gtk update", _("Update mirror")])
370                                self.optLst.append([2, "/sbin/shutdown -h now", _("Shutdown")])
371
372                except Exception as e:
373                        print e
374
375
376        def save_prg_selections(self,widget):
377                binary=self.entryShell.get_text()
378                path_to_bin=binary.split(' ')[0]
379                full_path=''
380               
381                #check if program exist
382                if os.path.exists(path_to_bin) and path_to_bin[-1] != '/':
383                        full_path=self.entryShell.get_text()
384                else:
385                        full_path = self.search_binary() + binary[len(binary.split (' ')[0]):len(binary)]
386
387                if full_path == '':
388                        messageBox(_("Atention"),_("Binary path not exist"))
389                else:
390                        self.generate_cron_file(full_path)
391                print full_path
392
393        def search_binary(self):
394                binary_dirs = ['/bin/','/sbin/','/usr/bin/','/usr/sbin/','/usr/local/bin/','/usr/local/sbin/']
395                full_path=''
396                name=self.get_prg_name()
397
398                for path in binary_dirs:
399                        for files in os.listdir(path):
400                                if files == name:
401                                        full_path = path+files
402                                        break
403                        if not full_path == '':
404                                break
405                return full_path
406
407
408        def show_apps(self, widget):
409                text=''
410                for files in os.listdir('/etc/cron.d/'):
411                        if files.endswith('scheduler'):
412                                        text=text+'\n*  '+files.split('.')[0]+'\n'
413                os.system('echo "APLICACIONES PROGRAMADAS: %s"' % (text))
414
415                if not text == '':
416                        os.system('echo "estoy dentro y no printeo"')
417                        messageBox(_("Programmed Applications"), text)
418
419
420############
421##  main
422############
423
424def messageBox(title, msg):
425        dialog = DialogWindow(None,title,msg)
426        dialog.run()
427        dialog.destroy()
428
429gettext.textdomain('scheduler')
430_ = gettext.gettext
431
432
433if os.geteuid() != 0:
434        messageBox(_("ERROR"),_("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting."))
435        exit(_("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting."))
436
437program_to_execute =""
438if len(sys.argv) > 2:
439        for i in range(1,len(sys.argv)):
440                program_to_execute=program_to_execute+sys.argv[i]+" "
441        win = Scheduler(program_to_execute)
442else:
443        win = Scheduler("")
444
445win.set_property("resizable",False)
446win.set_resizable(False)
447win.set_position(Gtk.WindowPosition.CENTER)
448win.connect("delete-event", Gtk.main_quit)
449win.show_all()
450Gtk.main()
Note: See TracBrowser for help on using the repository browser.