summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pykolab/xml/event.py50
-rw-r--r--tests/test-005-timezone.py50
-rw-r--r--wallace/module_resources.py44
3 files changed, 128 insertions, 16 deletions
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py
index d2973aa..b92339a 100644
--- a/pykolab/xml/event.py
+++ b/pykolab/xml/event.py
@@ -225,19 +225,36 @@ class Event(object):
year,
month,
day,
- hour,
- minute,
- second
) = (
_datetime.year(),
_datetime.month(),
_datetime.day(),
- _datetime.hour(),
- _datetime.minute(),
- _datetime.second()
)
- return datetime.datetime(year, month, day, hour, minute, second)
+ if not _datetime.hour() == None and not _datetime.hour() < 0:
+ (
+ hour,
+ minute,
+ second
+ ) = (
+ _datetime.hour(),
+ _datetime.minute(),
+ _datetime.second()
+ )
+
+ _timezone = _datetime.timezone()
+
+ if _timezone == '':
+ _timezone = pytz.utc
+ elif _timezone == None:
+ _timezone = pytz.utc
+ else:
+ _timezone = pytz.timezone(_timezone)
+
+ if _datetime.hour() == None or _datetime.hour() < 0:
+ return datetime.date(year, month, day)
+ else:
+ return datetime.datetime(year, month, day, hour, minute, second, tzinfo=_timezone)
def get_ical_attendee(self):
# TODO: Formatting, aye? See also the example snippet:
@@ -253,6 +270,8 @@ class Event(object):
role = attendee.get_role()
partstat = attendee.get_participant_status()
cutype = attendee.get_cutype()
+ delegators = attendee.get_delegated_from()
+ delegatees = attendee.get_delegated_to()
if rsvp in attendee.rsvp_map.keys():
_rsvp = rsvp
@@ -298,6 +317,12 @@ class Event(object):
if not _cutype == None:
_attendee.params['CUTYPE'] = icalendar.vText(_cutype)
+ if not delegators == None and len(delegators) > 0:
+ _attendee.params['DELEGATED-FROM'] = icalendar.vText(delegators[0].email())
+
+ if not delegatees == None and len(delegatees) > 0:
+ _attendee.params['DELEGATED-TO'] = icalendar.vText(delegatees[0].email())
+
attendees.append(_attendee)
return attendees
@@ -816,6 +841,7 @@ class Event(object):
attendees = self.get_attendees()
+ # TODO: There's an exception here for delegation (partstat DELEGATED)
for attendee in attendees:
if attendee.get_email() == from_address:
# Only the attendee is supposed to be listed in a reply
@@ -834,8 +860,8 @@ class Event(object):
if msg_from == None:
organizer = self.get_organizer()
- email = organizer.get_email()
- name = organizer.get_name()
+ email = organizer.email()
+ name = organizer.name()
if email == from_address:
if not name:
msg_from = email
@@ -851,9 +877,11 @@ class Event(object):
else:
msg_from = '"%s" <%s>' % (name, email)
-
if msg_from == None:
- log.error(_("No sender specified"))
+ if from_address == None:
+ log.error(_("No sender specified"))
+ else:
+ msg_from = from_address
msg['From'] = msg_from
diff --git a/tests/test-005-timezone.py b/tests/test-005-timezone.py
new file mode 100644
index 0000000..9b12c66
--- /dev/null
+++ b/tests/test-005-timezone.py
@@ -0,0 +1,50 @@
+import datetime
+import icalendar
+import pytz
+import unittest
+
+from pykolab.xml import Attendee
+from pykolab.xml import Event
+from pykolab.xml import EventIntegrityError
+from pykolab.xml import InvalidAttendeeParticipantStatusError
+from pykolab.xml import InvalidEventDateError
+from pykolab.xml import event_from_ical
+
+class TestTimezone(unittest.TestCase):
+
+ def test_001_timezone_conflict(self):
+ london = Event()
+ london.set_organizer("john.doe@example.org", "Doe, John")
+ london.add_attendee("resource-car-vw@example.org", cutype="RESOURCE")
+ london.set_start(datetime.datetime.now(pytz.timezone("Europe/London")))
+ london.set_end(datetime.datetime.now(pytz.timezone("Europe/London")))
+
+ zurich = Event()
+ zurich.set_organizer("john.doe@example.org", "Doe, John")
+ zurich.add_attendee("resource-car-vw@example.org", cutype="RESOURCE")
+ zurich.set_start(datetime.datetime.now(pytz.timezone("Europe/Zurich")))
+ zurich.set_end(datetime.datetime.now(pytz.timezone("Europe/Zurich")))
+
+ london_xml = london.__str__()
+ zurich_xml = zurich.__str__()
+
+ #print london_xml
+ #print zurich_xml
+
+ london_itip = london.as_string_itip()
+ zurich_itip = zurich.as_string_itip()
+
+ del london, zurich
+
+ #print london_itip
+ #print zurich_itip
+
+ london_cal = icalendar.Calendar.from_ical(london_itip)
+ london = event_from_ical(london_cal.walk('VEVENT')[0].to_ical())
+
+ zurich_cal = icalendar.Calendar.from_ical(zurich_itip)
+ zurich = event_from_ical(zurich_cal.walk('VEVENT')[0].to_ical())
+
+ self.assertEqual(london_xml, london.__str__())
+ self.assertEqual(zurich_xml, zurich.__str__())
+
diff --git a/wallace/module_resources.py b/wallace/module_resources.py
index 525cc3b..a4873f4 100644
--- a/wallace/module_resources.py
+++ b/wallace/module_resources.py
@@ -274,7 +274,6 @@ def execute(*args, **kw):
_ee = to_dt(event.get_end())
_ie = to_dt(itip['end'].dt)
-
if _es < _is:
if _es <= _ie:
if _ee <= _is:
@@ -386,7 +385,7 @@ def execute(*args, **kw):
itip_event['xml'].to_message().as_string()
)
- send_response(resources[resource]['mail'], itip_events)
+ send_response(resources[resource]['mail'], itip_event)
else:
# This must have been a resource collection originally.
@@ -395,15 +394,29 @@ def execute(*args, **kw):
if resources[resource].has_key('memberof'):
original_resource = resources[resources[resource]['memberof']]
+ # Randomly selects a target resource from the resource
+ # collection.
_target_resource = resources[original_resource['uniquemember'][random.randint(0,(len(original_resource['uniquemember'])-1))]]
- # unset all
+ # Remove all resources from the collection.
for _r in original_resource['uniquemember']:
del resources[_r]
if original_resource['mail'] in [a.get_email() for a in itip_event['xml'].get_attendees()]:
+ #
+ # Delegate:
+ #
+ # - delegator: the original resource collection
+ # - delegatee: the target resource
+ #
+
+ itip_event['xml'].delegate(
+ original_resource['mail'],
+ _target_resource['mail']
+ )
+
itip_event['xml'].set_attendee_participant_status(
- [a for a in itip_event['xml'].get_attendees() if a.get_email() == original_resource['mail']][0],
+ [a for a in itip_event['xml'].get_attendees() if a.get_email() == _target_resource['mail']][0],
"ACCEPTED"
)
@@ -414,6 +427,8 @@ def execute(*args, **kw):
level=9
)
+ # TODO: The Cyrus IMAP (or Dovecot) Administrator login
+ # name comes from configuration.
imap.imap.m.setacl(_target_resource['kolabtargetfolder'], "cyrus-admin", "lrswipkxtecda")
imap.imap.m.append(
_target_resource['kolabtargetfolder'],
@@ -422,7 +437,7 @@ def execute(*args, **kw):
itip_event['xml'].to_message().as_string()
)
- send_response(original_resource['mail'], itip_events)
+ send_response(original_resource['mail'], itip_event)
# Disconnect IMAP or we lock the mailbox almost constantly
imap.disconnect()
@@ -478,6 +493,8 @@ def itip_events_from_message(message):
for c in cal.walk():
if c.name == "VEVENT":
+ itip = {}
+
# From the event, take the following properties:
#
# - start
@@ -717,9 +734,26 @@ def send_response(from_address, itip_events):
if conf.debuglevel > 8:
smtp.set_debuglevel(True)
+ if isinstance(itip_events, dict):
+ itip_events = [ itip_events ]
+
for itip_event in itip_events:
attendee = [a for a in itip_event['xml'].get_attendees() if a.get_email() == from_address][0]
participant_status = itip_event['xml'].get_ical_attendee_participant_status(attendee)
+
+ if participant_status == "DELEGATED":
+ # Extra actions to take
+ delegator = [a for a in itip_event['xml'].get_attendees() if a.get_email() == from_address][0]
+ delegatee = [a for a in itip_event['xml'].get_attendees() if from_address in [b.email() for b in a.get_delegated_from()]][0]
+
+ itip_event['xml'].event.setAttendees([ delegator, delegatee ])
+
+ message = itip_event['xml'].to_message_itip(delegatee.get_email(), method="REPLY", participant_status=itip_event['xml'].get_ical_attendee_participant_status(delegatee))
+ smtp.sendmail(message['From'], message['To'], message.as_string())
+
+ itip_event['xml'].event.setAttendees([a for a in itip_event['xml'].get_attendees() if a.get_email() == from_address])
+
message = itip_event['xml'].to_message_itip(from_address, method="REPLY", participant_status=participant_status)
smtp.sendmail(message['From'], message['To'], message.as_string())
+
smtp.quit()