source: bell-scheduler/trunk/fuentes/n4d-bellscheduler.install/usr/share/n4d/python-plugins/BellSchedulerManager.py @ 7252

Last change on this file since 7252 was 7252, checked in by jrpelegrina, 19 months ago

WIP in integration of holiday-manager module

File size: 12.7 KB
Line 
1 
2import os
3import json
4import codecs
5import shutil
6import xmlrpclib as n4dclient
7import ssl
8import zipfile
9
10
11class BellSchedulerManager(object):
12
13        def __init__(self):
14
15                self.config_dir=os.path.expanduser("/etc/bellScheduler/")
16                self.config_file=self.config_dir+"bell_list"
17                self.holiday_token=self.config_dir+"enabled_holiday_token"
18                self.cron_dir="/etc/scheduler/tasks.d/"
19                self.cron_file=os.path.join(self.cron_dir,"BellScheduler")
20
21                self.images_folder="/usr/local/share/bellScheduler/images"
22                self.sounds_folder="/usr/local/share/bellScheduler/sounds"
23                self.media_files_folder="/usr/local/share/bellScheduler/"
24       
25
26                server='localhost'
27                context=ssl._create_unverified_context()
28                self.n4d = n4dclient.ServerProxy("https://"+server+":9779",context=context,allow_none=True)
29               
30                self._get_n4d_key()
31
32
33        #def __init__   
34
35
36        def _get_n4d_key(self):
37
38                self.n4dkey=''
39                with open('/etc/n4d/key') as file_data:
40                        self.n4dkey = file_data.readlines()[0].strip()
41
42        #def _get_n4d_key
43
44        def _create_conf(self):
45
46                if not os.path.exists(self.config_dir):
47                        os.makedirs(self.config_dir)
48
49                if not os.path.exists(self.images_folder):
50                        os.makedirs(self.images_folder)
51
52                if not os.path.exists(self.sounds_folder):
53                        os.makedirs(self.sounds_folder)         
54               
55                var={}
56                with codecs.open(self.config_file,'w',encoding="utf-8") as f:
57                        json.dump(var,f,ensure_ascii=False)
58                        f.close()
59
60                return {"status":True,"msg":"Configuration file created successfuly"}
61
62        #def create_conf               
63       
64
65        def read_conf(self):
66               
67                if not os.path.exists(self.config_file):
68                        self._create_conf()
69               
70                f=open(self.config_file)
71               
72                try:
73                        self.bells_config=json.load(f)
74                except Exception as e:
75
76                        self.bells_config={}
77                        return {"status":False,"msg":"Unabled to read configuration file :" +str(e),"code":25,"data":self.bells_config}
78
79
80                f.close()       
81
82                return {"status":True,"msg":"Configuration file readed successfuly","code":26,"data":self.bells_config}
83
84        #def read_conf 
85
86        def _get_tasks_from_cron(self):
87
88                cron_tasks={}
89                tmp_tasks={}
90                tasks=self.n4d.get_local_tasks(self.n4dkey,'SchedulerServer')
91               
92                if tasks["status"]:
93
94                        for item in tasks["data"]:
95                                if item=="BellScheduler":
96                                        tmp_tasks=tasks["data"][item]
97
98                        if len(tmp_tasks)>0:
99                                for     item in tmp_tasks:
100                                        key=str(tmp_tasks[item]["BellId"])
101                                        cron_tasks[key]={}
102                                        cron_tasks[key]["CronId"]=item
103               
104                return cron_tasks
105
106        #def _get_tasks_from_cron       
107               
108       
109        def sync_with_cron(self):
110       
111                bell_tasks=self.read_conf()["data"]
112                keys_bells=bell_tasks.keys()
113
114                bells_incron=self._get_tasks_from_cron()
115                keys_cron=bells_incron.keys()
116                changes=0
117
118                if len(keys_cron)>0:
119                        for item in bell_tasks:
120                                if item in keys_cron:
121                                        if bell_tasks[item]["active"]:
122                                                pass
123                                        else:
124                                                changes+=1
125                                                bell_tasks[item]["active"]=True
126                                else:
127                                        if bell_tasks[item]["active"]:
128                                                changes+=1
129                                                bell_tasks[item]["active"]=False
130                                        else:
131                                                pass
132
133                        for item in keys_cron:
134                                if item not in keys_bells:
135                                        result=self._delete_from_cron(item)
136                                        if not result["status"]:
137                                                return {"status":False,"msg":"Unable to clear alarm from cron file","code":37}
138                else:
139                        for item in bell_tasks:
140                                if bell_tasks[item]["active"]:
141                                        changes+=1
142                                        bell_tasks[item]["active"]=False
143                                       
144
145                if changes>0:
146                        self._write_conf(bell_tasks,"BellList")
147
148                return {"status":True,"msg":"Sync with cron sucessfully","data":bell_tasks}     
149                                       
150
151        #def sync_with_cron     
152
153        def _write_conf(self,info,type_list):
154               
155                if type_list=="BellList":
156                        self.bells_config=info
157                        file_to_write=self.config_file
158                        msg="Bell list saved successfuly"
159                else:
160                        file_to_write=self.cron_file
161                        msg="Cron list saved successfuly"
162
163               
164                with codecs.open(file_to_write,'w',encoding="utf-8") as f:
165                        json.dump(info,f,ensure_ascii=False)
166                        f.close()       
167
168                return {"status":True,"msg":msg}       
169
170
171        #def _write_conf       
172
173        def save_changes(self,info,last_change,action):
174               
175                turn_on=False
176                if action !="remove":
177                        if info[last_change]["active"]:
178                                turn_on=True
179                                tasks_for_cron=self._format_to_cron(info,last_change,action)
180                                result=self.n4d.write_tasks(self.n4dkey,'SchedulerServer','local',tasks_for_cron)
181
182                        else:
183                                result=self._delete_from_cron(last_change)
184                else:
185                        result=self._delete_from_cron(last_change)
186
187
188                if result['status']:   
189                        return self._write_conf(info,"BellList")
190                else:
191                        if action=="edit":
192                                return {"status":False,"action":action,"msg":result['data'],"code":19} 
193                        elif action=="add":
194                                return {"status":False,"action":action,"msg":result['data'],"code":20}
195                        elif action=="remove":
196                                return {"status":False,"action":action,"msg":result['data'],"code":21} 
197                        elif action=="active": 
198                                if turn_on:
199                                        return {"status":False,"action":action,"msg":result['data'],"code":22}
200                                else:
201                                        return {"status":False,"action":action,"msg":result['data'],"code":23}
202               
203        #def save_changes                               
204
205        def _get_cron_id(self,last_change):
206
207                cron_tasks=self._get_tasks_from_cron()
208                if len(cron_tasks)>0:
209                        if last_change in cron_tasks.keys():
210                                return {"status":True, "id":cron_tasks[last_change]}
211               
212                return {"status":False,"id":{"CronId":0}}
213
214        # def _get_cron_id     
215       
216        def _delete_from_cron(self,last_change):
217
218                id_to_remove=self._get_cron_id(last_change)
219                cron_id=id_to_remove["id"]["CronId"]
220                delete={"status":True,"data":"0"}
221
222                if id_to_remove["status"]:
223                        delete=self.n4d.remove_task(self.n4dkey,'SchedulerServer','local','BellScheduler',cron_id,'cmd')
224                       
225                return delete
226
227        #def _delete_from_cron 
228       
229        def _format_to_cron(self,info,item,action):
230
231                info_to_cron={}
232               
233       
234                if action=="edit" or action=="active":
235                        cron_tasks=self._get_tasks_from_cron()
236                        try:
237                                key=cron_tasks[item]["CronId"]
238                        except:
239                                key="0" 
240                else:
241                        key="0"
242                       
243                info_to_cron["BellScheduler"]={}
244                info_to_cron["BellScheduler"][key]={}
245                info_to_cron["BellScheduler"][key]["name"]=info[item]["name"]
246                info_to_cron["BellScheduler"][key]["dom"]="*"
247                info_to_cron["BellScheduler"][key]["mon"]="*" 
248                info_to_cron["BellScheduler"][key]["h"]=str(info[item]["hour"])
249                info_to_cron["BellScheduler"][key]["m"]=str(info[item]["minute"])
250                info_to_cron["BellScheduler"][key]["protected"]=True
251
252                weekdays=info[item]["weekdays"]
253                days=""
254                if weekdays["0"]:
255                        days=days+"1,"
256                if weekdays["1"]:
257                        days=days+"2,"
258                if weekdays["2"]:
259                        days=days+"3,"
260                if weekdays["3"]:
261                        days=days+"4,"
262                if weekdays["4"]:
263                        days=days+"5,"
264
265                if days!="":
266                        days=days[:-1]
267
268                else:
269                        days='*'
270
271                info_to_cron["BellScheduler"][key]["dow"]=days
272                info_to_cron["BellScheduler"][key]["BellId"]=item                               
273
274               
275                sound_option=info[item]["sound"]["option"]
276                sound_path=info[item]["sound"]["path"]
277                duration=info[item]["play"]["duration"]
278
279
280                if duration>0:
281                        fade_out=int(duration)-2
282                        fade_effects='-af aformat=channel_layouts=mono -af afade=in:st=0:d=6,afade=out:st='+str(fade_out)+":d=2"
283                        cmd="ffplay -nodisp -autoexit -t "+str(duration)
284                else:
285                        fade_effects='-af aformat=channel_layouts=mono '
286                        cmd="ffplay -nodisp -autoexit "
287
288                if sound_option !="url":
289                        if sound_option =="file":
290                                cmd=cmd+' "'+ sound_path +'" '+fade_effects
291                        else:
292                                #random_file="$(find"+ " '"+sound_path+"' -type f -print0 | xargs -0 file -i | awk -F ':' '{ if ($2 ~ /audio/ || $2 ~ /video/ ) print $1 }'| shuf -n 1)"
293                                random_file="$(randomaudiofile" + " '"+sound_path+"')"
294                                cmd=cmd+' "'+ random_file + '" '+fade_effects
295                                #cmd=cmd+" $(find"+ " '"+sound_path+"' -type f | shuf -n 1) "+fade_effects             
296                else:
297                        cmd=cmd+ " $(youtube-dl -g "+sound_path+ " | sed -n 2p) "+fade_effects
298                       
299                info_to_cron["BellScheduler"][key]["cmd"]=cmd
300
301                if os.path.exists(self.holiday_token):
302                        info_to_cron["BellScheduler"][key]["holidays"]=True
303                else:
304                        info_to_cron["BellScheduler"][key]["holidays"]=False
305       
306                       
307                return info_to_cron
308
309        #def _format_to_cron   
310
311        def copy_media_files(self,image,sound):
312
313
314                if image!="":
315                        image_file=os.path.basename(image)
316                        image_dest=os.path.join(self.images_folder,image_file)
317
318                if sound!="":
319                        sound_file=os.path.basename(sound)
320                        sound_dest=os.path.join(self.sounds_folder,sound_file)
321
322                try:
323                        if image!="":
324                                if not os.path.exists(image_dest):
325                                        shutil.copy2(image,image_dest)
326
327                        if sound!="":
328                                if not os.path.exists(sound_dest):
329                                        shutil.copy2(sound,sound_dest)
330
331                        result={"status":True,"msg":"Files copied successfully"}
332                except Exception as e:
333                                result={"status":False,"msg":str(e),"code":24}         
334
335                return result
336       
337        #def copy_media_files
338
339        def export_bells_conf(self,dest_file,user,arg=None):
340
341                tmp_export=tempfile.mkdtemp("_bell_export")
342               
343                try:
344                        shutil.copy2(self.config_file,os.path.join(tmp_export,os.path.basename(self.config_file)))
345                        if os.path.exists(self.cron_file):
346                                shutil.copy2(self.cron_file,os.path.join(tmp_export,os.path.basename(self.cron_file)))
347                        if os.path.exists(self.holiday_token):
348                                shutil.copy2(self.holiday_token,os.path.join(tmp_export,os.path.basename(self.holiday_token)))
349
350                        if os.path.exists(self.media_files_folder):
351                                shutil.copytree(self.media_files_folder,os.path.join(tmp_export,"media"))
352                       
353                        shutil.make_archive(dest_file, 'zip', tmp_export)
354                        if arg!=True:
355                                shutil.rmtree(tmp_export)
356
357                        cmd='chown -R '+user+':'+user +" " + dest_file+'.zip'
358                        os.system(cmd) 
359                        result={"status":True,"msg":"Bells exported successfullly","code":11}
360                                               
361                except Exception as e:
362                        result={"status":False,"msg":str(e),"code":12}         
363
364                return result   
365
366        #def export_bells_conf 
367
368        def import_bells_conf(self,orig_file,user,backup):
369
370                backup_file=["",""]
371                unzip_tmp=tempfile.mkdtemp("_import_bells")
372                result={"status":True}
373                action="disable"
374
375                if backup:
376                        backup_file=tempfile.mkstemp("_bells_backup")
377                        result=self.export_bells_conf(backup_file[1],user,True)
378
379                try:   
380                        if result['status']:   
381                                tmp_zip=zipfile.ZipFile(orig_file)
382                                tmp_zip.extractall(unzip_tmp)
383                                tmp_zip.close   
384
385                                config_file=os.path.join(unzip_tmp,os.path.basename(self.config_file)) 
386                                if os.path.exists(config_file):
387                                        try:
388                                                f=open(config_file)
389                                                read=json.load(f)
390                                                shutil.copy2(config_file,self.config_dir)
391                                                f.close()
392                                        except Exception as e:
393                                                result={"status":False,"msg":str(e),"code":9,"data":backup_file[1]}     
394                                                return result           
395                                                       
396                                cron_file=os.path.join(unzip_tmp,os.path.basename(self.cron_file))
397                                if os.path.exists(cron_file):
398                                        try:
399                                                f=open(cron_file)
400                                                read=json.load(f)
401                                                shutil.copy2(cron_file,self.cron_dir)
402                                                f.close()
403                                                #self.n4d.process_tasks(self.n4dkey,'SchedulerClient')
404                                        except Exception as e:
405                                                result={"status":False,"msg":str(e),"code":9,"data":backup_file[1]}     
406                                                return result   
407
408                                holiday_token=os.path.join(unzip_tmp,os.path.basename(self.holiday_token))     
409                                if os.path.exists(holiday_token):
410                                        action="enable"
411                                        shutil.copyfile(holiday_token,self.holiday_token)       
412                                else:
413                                        if os.path.exists(self.holiday_token):
414                                                os.remove(self.holiday_token)
415
416                                if os.path.exists(self.images_folder):
417                                        shutil.rmtree(self.images_folder)
418                                        shutil.copytree(os.path.join(unzip_tmp,"media/images"),self.images_folder)
419
420                                if os.path.exists(self.sounds_folder):
421                                        shutil.rmtree(self.sounds_folder)
422                                        shutil.copytree(os.path.join(unzip_tmp,"media/sounds"),self.sounds_folder)
423               
424                                update_holiday=self.enable_holiday_control(action)     
425                               
426                                if update_holiday["status"]:   
427                                        result={"status":True,"msg":"Bells imported successfullly","code":10,"data":backup_file[1]}
428                                else:
429                                        result={"status":False,"msg":update_holiday["msg"],"code":9}                           
430                except Exception as e:
431                        result={"status":False,"msg":str(e),"code":9,"data":backup_file[1]}     
432
433               
434                return result           
435
436        #def import_bells_conf
437
438        def enable_holiday_control(self,action):
439
440                result=self._update_holiday_control(action)
441                if result['status']:
442                        if action=="disable":
443                                if os.path.exists(self.holiday_token):
444                                        os.remove(self.holiday_token)   
445                                        result={"status":True,"msg":"Holiday token removed","code":34}
446                        else:
447                                if not os.path.exists(self.holiday_token):
448                                        if not os.path.exists(self.config_dir):
449                                                os.makedirs(self.config_dir)
450                                        f=open(self.holiday_token,'w')
451                                        f.close()
452                                        result={"status":True,"msg":"Holiday token created","code":35}         
453               
454                return result           
455
456        #def enable_holiday
457
458        def _update_holiday_control(self,action):
459
460               
461                if os.path.exists(self.cron_file):
462                        f=open(self.cron_file)
463                        try:
464                                tasks_cron=json.load(f)
465                        except Exception as e:
466                                result={"status":False,"msg":str(e),"code":36}
467                                return result
468
469                       
470                        for item in     tasks_cron["BellScheduler"]:
471                                if action=="enable":
472                                        tasks_cron["BellScheduler"][item]["holidays"]=True
473                               
474                                else:
475                                        tasks_cron["BellScheduler"][item]["holidays"]=False
476
477                       
478                        self._write_conf(tasks_cron,"CronList")
479                        self.n4d.process_tasks(self.n4dkey,'SchedulerClient')
480                        result={"status":True,"msg":"Cron file updated","code":37}
481                else:
482                        result={"status":True,"msg":"Cron file dosn't exists","code":37}                       
483
484                return result
485
486        #def _update_holiday_control           
487               
488                       
489
Note: See TracBrowser for help on using the repository browser.