1 """
2 Schedule actions or events
3
4 @copyright: (c) 2011 hackmeeting U{http://sindominio.net/hackmeeting}
5 @author: Ruben Pollan
6 @organization: hackmeeting U{http://sindominio.net/hackmeeting}
7 @contact: meskio@sindominio.net
8 @license:
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the Do What The Fuck You Want To
11 Public License, Version 2, as published by Sam Hocevar. See
12 U{http://sam.zoy.org/projects/COPYING.WTFPL} for more details.
13 """
14
15 import thread
16 import random
17 from time import sleep, time
18 from cPickle import dumps
19 from time import strptime, mktime
20
21 from events import trigger
22 from database import DB
23
24
26 """
27 Convert an string of date to a epoch date
28
29 @type date: string
30 @param date: string date of the date
31 @returns: epoch date
32 """
33 date_fmt = [_("%d/%m/%Y %H:%M"), _("%d/%m/%Y")]
34
35 for fmt in date_fmt:
36 try:
37 return mktime(strptime(date, fmt))
38 except ValueError:
39 pass
40 return -1
41
42
44 """
45 Program a periodic action
46
47 Execute I{handler} each I{seconds} in parallel.
48
49 @type handler: fun()
50 @param handler: function to call each I{seconds}
51 @type seconds: integer
52 @param seconds: waiting seconds between the end of a handler call and the
53 next
54 """
55 thread.start_new_thread(_periodic, (handler, seconds))
56
57
59 while 1:
60 handler()
61 sleep(float(seconds))
62
63
64 -def at(event, data, date, doc_id=None):
65 """
66 Program an event to be trigger on a date
67
68 @type event: Event
69 @param event: event to be scheduled
70 @param data: data for the event
71 @type date: int or string
72 @param date: epoch date or string date for the event
73 @type doc_id: ObjectId
74 @param doc_id: optional database document id where is stored the scheduled
75 event. Meant to be use on recovering sched from the database, like after
76 a shutdown
77 """
78 epoch = -1
79 if isinstance(date, int):
80 epoch = date
81 elif isinstance(date, str):
82 epoch = str2date(date)
83
84 if epoch != -1:
85 args = (event, data, epoch - time(), epoch, doc_id)
86 thread.start_new_thread(_delay, args)
87 return epoch
88
89
90 -def delay(event, data, seconds, doc_id=None):
91 """
92 Program an event to be trigger after some seconds
93
94 @type event: Event
95 @param event: event to be scheduled
96 @param data: data for the event
97 @type seconds: int
98 @param seconds: seconds of delay for the event
99 @type doc_id: ObjectId
100 @param doc_id: optional database document id where is stored the scheduled
101 event. Meant to be use on recovering sched from the database, like after
102 a shutdown
103 @warning: it is not properly tested might have bugs
104 """
105 thread.start_new_thread(_delay, (event, data, seconds, seconds + time()))
106
107
108 -def _delay(event, data, seconds, date, doc_id=None):
109 db = DB()
110 core = db.core()
111 if not doc_id:
112 doc = {'element': 'sched',
113 'type': 'at',
114 'event': dumps(event.elements()),
115 'data': dumps(data),
116 'date': date}
117 doc_id = core.insert(doc)
118
119 if seconds > 0:
120 sleep(float(seconds))
121 trigger(event, data)
122 core.remove(doc_id)
123