kopia lustrzana https://github.com/jazzband/icalevents
rodzic
d2f5e62061
commit
1f05d58c72
|
@ -4,6 +4,7 @@ Parse iCal data to Events.
|
|||
# for UID generation
|
||||
from random import randint
|
||||
from datetime import datetime, timedelta, date
|
||||
from dateutil import relativedelta
|
||||
|
||||
from icalendar import Calendar
|
||||
from pytz import utc
|
||||
|
@ -297,20 +298,29 @@ def create_recurring_events(start, end, component):
|
|||
unfolded.append(current)
|
||||
else:
|
||||
break
|
||||
if freq == 'MONTHLY':
|
||||
elif freq == 'MONTHLY':
|
||||
by_day = rule.get('BYDAY')
|
||||
|
||||
while True:
|
||||
current = current.copy_to(next_month_at(current.start))
|
||||
if by_day:
|
||||
next_date = next_month_byday_delta(current.start, by_day[0])
|
||||
current = current.copy_to(next_date)
|
||||
else:
|
||||
current = current.copy_to(next_month_at(current.start))
|
||||
if current.start < limit:
|
||||
unfolded.append(current)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
if freq == 'DAILY':
|
||||
delta = timedelta(days=1)
|
||||
elif freq == 'WEEKLY':
|
||||
delta = timedelta(days=7)
|
||||
else:
|
||||
return
|
||||
elif freq == 'DAILY':
|
||||
delta = timedelta(days=1)
|
||||
while True:
|
||||
current = current.copy_to(current.start + delta)
|
||||
if current.start < limit:
|
||||
unfolded.append(current)
|
||||
else:
|
||||
break
|
||||
elif freq == 'WEEKLY':
|
||||
delta = timedelta(days=7)
|
||||
|
||||
by_day = rule.get('BYDAY')
|
||||
if by_day:
|
||||
|
@ -326,6 +336,8 @@ def create_recurring_events(start, end, component):
|
|||
unfolded.append(current)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
return
|
||||
|
||||
return in_range(unfolded, start, end)
|
||||
|
||||
|
@ -361,3 +373,26 @@ def generate_day_deltas_by_weekday(by_day):
|
|||
adjusted_deltas = day_deltas[1:] + [first_hop_count]
|
||||
|
||||
return dict(zip(selected_weekday_numbers, adjusted_deltas))
|
||||
|
||||
|
||||
def next_month_byday_delta(start_date, by_day):
|
||||
"""
|
||||
Get the next event date when a MONTHLY rule contains a BYDAY clause,
|
||||
e.g. 3SA = "Next third Saturday"
|
||||
"""
|
||||
|
||||
weekdays = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
|
||||
|
||||
number = int(by_day[0])
|
||||
weekday = by_day[1:]
|
||||
|
||||
if weekday not in weekdays:
|
||||
raise ValueError('Invalid weekday: {}'.format(weekday))
|
||||
|
||||
weekday = weekdays.index(weekday)
|
||||
weekday_func = relativedelta.weekday(weekday)
|
||||
|
||||
delta = relativedelta.relativedelta(day=1, months=+1,
|
||||
weekday=weekday_func(number))
|
||||
|
||||
return start_date + delta
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
|
||||
from test.test_icaldownload import *
|
||||
|
|
|
@ -114,3 +114,15 @@ class ICalParserTests(unittest.TestCase):
|
|||
result = icalevents.icalparser.generate_day_deltas_by_weekday(by_day)
|
||||
|
||||
self.assertEqual(7, result[0], 'Mon to Mon')
|
||||
|
||||
def test_next_month_byday_delta(self):
|
||||
dt = date(2018, 9, 15)
|
||||
|
||||
result = icalevents.icalparser.next_month_byday_delta(dt, "3SA")
|
||||
self.assertEqual(date(2018, 10, 20), result, '3rd Saturday next month')
|
||||
|
||||
result = icalevents.icalparser.next_month_byday_delta(dt, "2TU")
|
||||
self.assertEqual(date(2018, 10, 9), result, '2nd Tuesday next month')
|
||||
|
||||
with self.assertRaises(ValueError, msg='Invalid weekday'):
|
||||
icalevents.icalparser.next_month_byday_delta(dt, "1ZZ")
|
||||
|
|
Ładowanie…
Reference in New Issue