My favorites
▼
|
Sign in
fullcalendar
ISSUE TRACKER HAS MOVED. DO NOT USE THIS (more info)
Project Home
Issues
Export to GitHub
New issue
Search
Search within:
All issues
Open issues
New issues
Issues to verify
for
Advanced search
Search tips
Subscriptions
Issue
116
attachment: recurring.py
(3.5 KB)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def fetchRecurring(start, end, events):
''' returns list of recurring entries that have instances in the specified time range (between start and end) '''
def recursDuring(entry):
''' returns whether the recurring entry has an instance during the date range from start to end '''
# ignore if the first instance of the event is after our range
origin = entry.start
recurring = []
# TODO: should use date class instead of datetime class
if origin > end:
# ignore event - all instances occur in future
return recurring
def recurWeek(incr):
''' calculate either weekly or biweekly repeats. 'incr' will be either 7 or 14 '''
leadup = start - origin
rm = leadup.seconds
# account for partial days since start/end ranges usually have midnight as a time
days = leadup.days + 1 if rm > 0 else leadup.days
if origin > start:
# first instance is within the current range
begin = origin
else:
# set the first date we check BEFORE the specified range, so we don't jump over any relevant instances
diff = days % incr
begin = start - timedelta(days=diff)
# start comparisons
candidate = begin.replace(hour=origin.hour, minute=origin.minute, second=origin.second)
duration = entry.end - entry.start
while candidate < end:
if candidate > start:
instance = candidate
recurring.append(construct(entry, instance, instance + duration))
# increment by event frequency (e.g. 7 days for weekly)
candidate = candidate + timedelta(days=incr)
if entry.frequency == "D":
# get the first date of relevance
if origin > start:
candidate = begin = origin
else:
begin = start
candidate = begin.replace(hour=origin.hour, minute=origin.minute, second=origin.second)
duration = entry.end - entry.start
while candidate < end:
if candidate > start:
instance = candidate
recurring.append(construct(entry, instance, instance + duration))
# get the next day
candidate = candidate + timedelta(days=1)
elif entry.frequency == "W":
recurWeek(7)
elif entry.frequency == "B":
recurWeek(14)
elif entry.frequency == "M":
candidate = begin = origin
duration = entry.end - entry.start
while candidate < end:
# checking month
if candidate > start:
instance = candidate
recurring.append(construct(entry, instance, instance + duration))
# increment by event frequency
nextmonth = candidate.month + 1
nextmonth = 1 if nextmonth > 12 else nextmonth
candidate = candidate.replace(month=nextmonth)
return recurring
# call the recursDuring method on each member in the list of event objects (from database)
output = map(recursDuring, events)
# map function returns a nested list (array) so we flatten it
return [item for sublist in output for item in sublist] if output else []
Powered by
Google Project Hosting