Changeset View
Changeset View
Standalone View
Standalone View
wallace/module_resources.py
Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
from pykolab.xml import event_from_message | from pykolab.xml import event_from_message | ||||
from pykolab.xml import participant_status_label | from pykolab.xml import participant_status_label | ||||
# define some contstants used in the code below | # define some contstants used in the code below | ||||
COND_NOTIFY = 256 | COND_NOTIFY = 256 | ||||
ACT_MANUAL = 1 | ACT_MANUAL = 1 | ||||
ACT_ACCEPT = 2 | ACT_ACCEPT = 2 | ||||
ACT_REJECT = 8 | ACT_REJECT = 8 | ||||
ACT_TENTATIVE = 16 | |||||
ACT_ACCEPT_AND_NOTIFY = ACT_ACCEPT + COND_NOTIFY | ACT_ACCEPT_AND_NOTIFY = ACT_ACCEPT + COND_NOTIFY | ||||
ACT_TENTATIVE_AND_NOTIFY = ACT_TENTATIVE + COND_NOTIFY | |||||
# noqa: E241 | # noqa: E241 | ||||
policy_name_map = { | policy_name_map = { | ||||
'ACT_MANUAL': ACT_MANUAL, # noqa: E241 | 'ACT_MANUAL': ACT_MANUAL, # noqa: E241 | ||||
'ACT_ACCEPT': ACT_ACCEPT, # noqa: E241 | 'ACT_ACCEPT': ACT_ACCEPT, # noqa: E241 | ||||
'ACT_REJECT': ACT_REJECT, # noqa: E241 | 'ACT_REJECT': ACT_REJECT, # noqa: E241 | ||||
'ACT_ACCEPT_AND_NOTIFY': ACT_ACCEPT_AND_NOTIFY | 'ACT_ACCEPT_AND_NOTIFY': ACT_ACCEPT_AND_NOTIFY, | ||||
'ACT_TENTATIVE_AND_NOTIFY': ACT_TENTATIVE_AND_NOTIFY | |||||
} | } | ||||
# pylint: disable=invalid-name | # pylint: disable=invalid-name | ||||
log = pykolab.getLogger('pykolab.wallace/resources') | log = pykolab.getLogger('pykolab.wallace/resources') | ||||
extra_log_params = {'qid': '-'} | extra_log_params = {'qid': '-'} | ||||
log = LoggerAdapter(log, extra_log_params) | log = LoggerAdapter(log, extra_log_params) | ||||
conf = pykolab.getConf() | conf = pykolab.getConf() | ||||
▲ Show 20 Lines • Show All 950 Lines • ▼ Show 20 Lines | def accept_reservation_request( | ||||
resource, | resource, | ||||
delegator=None, | delegator=None, | ||||
confirmed=False, | confirmed=False, | ||||
invitationpolicy=None | invitationpolicy=None | ||||
): | ): | ||||
""" | """ | ||||
Accepts the given iTip event by booking it into the resource's | Accepts the given iTip event by booking it into the resource's | ||||
calendar. Then set the attendee status of the given resource to | calendar. Then set the attendee status of the given resource to | ||||
ACCEPTED and sends an iTip reply message to the organizer. | ACCEPTED/TENTATIVE and sends an iTip reply message to the organizer. | ||||
""" | """ | ||||
owner = get_resource_owner(resource) | owner = get_resource_owner(resource) | ||||
confirmation_required = False | confirmation_required = False | ||||
partstat = 'ACCEPTED' | |||||
if not confirmed and owner: | if not confirmed and owner: | ||||
if invitationpolicy is None: | if invitationpolicy is None: | ||||
invitationpolicy = get_resource_invitationpolicy(resource) | invitationpolicy = get_resource_invitationpolicy(resource) | ||||
log.debug(_("Apply invitation policies %r") % (invitationpolicy), level=8) | log.debug(_("Apply invitation policies %r") % (invitationpolicy), level=8) | ||||
if invitationpolicy is not None: | if invitationpolicy is not None: | ||||
for policy in invitationpolicy: | for policy in invitationpolicy: | ||||
if policy & ACT_MANUAL and owner['mail']: | if policy & ACT_MANUAL and owner['mail']: | ||||
confirmation_required = True | confirmation_required = True | ||||
partstat = 'TENTATIVE' | |||||
break | break | ||||
if policy & ACT_TENTATIVE: | |||||
partstat = 'TENTATIVE' if confirmation_required else 'ACCEPTED' | partstat = 'TENTATIVE' | ||||
itip_event['xml'].set_transparency(False) | itip_event['xml'].set_transparency(False) | ||||
itip_event['xml'].set_attendee_participant_status( | itip_event['xml'].set_attendee_participant_status( | ||||
itip_event['xml'].get_attendee_by_email(resource['mail']), | itip_event['xml'].get_attendee_by_email(resource['mail']), | ||||
partstat | partstat | ||||
) | ) | ||||
saved = save_resource_event(itip_event, resource) | saved = save_resource_event(itip_event, resource) | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
def save_resource_event(itip_event, resource): | def save_resource_event(itip_event, resource): | ||||
""" | """ | ||||
Append the given event object to the resource's calendar | Append the given event object to the resource's calendar | ||||
""" | """ | ||||
try: | try: | ||||
save_event = itip_event['xml'] | save_event = itip_event['xml'] | ||||
targetfolder = imap.folder_quote(resource['kolabtargetfolder']) | |||||
# add exception to existing recurring main event | # add exception to existing recurring main event | ||||
if resource.get('existing_master') is not None: | if resource.get('existing_master') is not None: | ||||
save_event = resource['existing_master'] | save_event = resource['existing_master'] | ||||
save_event.add_exception(itip_event['xml']) | save_event.add_exception(itip_event['xml']) | ||||
elif itip_event.get('_master') is not None: | elif itip_event.get('_master') is not None: | ||||
save_event = itip_event['_master'] | save_event = itip_event['_master'] | ||||
save_event.add_exception(itip_event['xml']) | save_event.add_exception(itip_event['xml']) | ||||
# remove old copy of the reservation (also sets ACLs) | # remove old copy of the reservation (also sets ACLs) | ||||
if 'existing_events' in resource and len(resource['existing_events']) > 0: | if 'existing_events' in resource and len(resource['existing_events']) > 0: | ||||
for existing in resource['existing_events']: | for existing in resource['existing_events']: | ||||
delete_resource_event(existing.uid, resource, existing._msguid) | delete_resource_event(existing.uid, resource, existing._msguid) | ||||
# delete old version referenced save_event | # delete old version referenced save_event | ||||
elif hasattr(save_event, '_msguid'): | elif hasattr(save_event, '_msguid'): | ||||
delete_resource_event(save_event.uid, resource, save_event._msguid) | delete_resource_event(save_event.uid, resource, save_event._msguid) | ||||
else: | else: | ||||
imap.set_acl( | imap.set_acl( | ||||
targetfolder, | resource['kolabtargetfolder'], | ||||
conf.get(conf.get('kolab', 'imap_backend'), 'admin_login'), | conf.get(conf.get('kolab', 'imap_backend'), 'admin_login'), | ||||
"lrswipkxtecda" | "lrswipkxtecda" | ||||
) | ) | ||||
# append new version | # append new version | ||||
result = imap.imap.m.append( | result = imap.append( | ||||
targetfolder, | resource['kolabtargetfolder'], | ||||
None, | |||||
None, | |||||
save_event.to_message(creator="Kolab Server <wallace@localhost>").as_string() | save_event.to_message(creator="Kolab Server <wallace@localhost>").as_string() | ||||
) | ) | ||||
return result | return result | ||||
# pylint: disable=broad-except | # pylint: disable=broad-except | ||||
except Exception as e: | except Exception as e: | ||||
log.error(_("Failed to save event to resource calendar at %r: %r") % ( | log.error(_("Failed to save event to resource calendar at %r: %r") % ( | ||||
resource['kolabtargetfolder'], e | resource['kolabtargetfolder'], e | ||||
)) | )) | ||||
▲ Show 20 Lines • Show All 506 Lines • ▼ Show 20 Lines | if notify or not success: | ||||
result = modules._sendmail(resource['mail'], owner['mail'], msg.as_string()) | result = modules._sendmail(resource['mail'], owner['mail'], msg.as_string()) | ||||
log.debug(_("Owner notification was sent successfully: %r") % result, level=8) | log.debug(_("Owner notification was sent successfully: %r") % result, level=8) | ||||
signal.alarm(0) | signal.alarm(0) | ||||
def owner_notification_text(resource, owner, event, success): | def owner_notification_text(resource, owner, event, success): | ||||
organizer = event.get_organizer() | organizer = event.get_organizer() | ||||
status = event.get_attendee_by_email(resource['mail']).get_participant_status(True) | status = event.get_attendee_by_email(resource['mail']).get_participant_status(True) | ||||
domain = resource['mail'].split('@')[1] | |||||
url = conf.get('wallace', 'webmail_url') | |||||
if success: | if success: | ||||
message_text = _( | message_text = _( | ||||
""" | """ | ||||
The resource booking for %(resource)s by %(orgname)s <%(orgemail)s> has been | The resource booking for %(resource)s by %(orgname)s <%(orgemail)s> has been | ||||
%(status)s for %(date)s. | %(status)s for %(date)s. | ||||
*** This is an automated message, sent to you as the resource owner. *** | *** This is an automated message, sent to you as the resource owner. *** | ||||
""" | """ | ||||
) | ) | ||||
if url: | |||||
message_text += ( | |||||
"\n " | |||||
+ _("You can change the status via %(url)s") % { 'url': url } + '?_task=calendar' | |||||
Lint: PEP8 W503: line break before binary operator | |||||
) | |||||
else: | else: | ||||
message_text = _( | message_text = _( | ||||
""" | """ | ||||
A reservation request for %(resource)s could not be processed automatically. | A reservation request for %(resource)s could not be processed automatically. | ||||
Please contact %(orgname)s <%(orgemail)s> who requested this resource for %(date)s. | Please contact %(orgname)s <%(orgemail)s> who requested this resource for %(date)s. | ||||
Subject for the event: %(summary)s. | Subject for the event: %(summary)s. | ||||
*** This is an automated message, sent to you as the resource owner. *** | *** This is an automated message, sent to you as the resource owner. *** | ||||
""" | """ | ||||
) | ) | ||||
return message_text % { | return message_text % { | ||||
'resource': resource['cn'], | 'resource': resource['cn'], | ||||
'summary': event.get_summary(), | 'summary': event.get_summary(), | ||||
'date': event.get_date_text(), | 'date': event.get_date_text(), | ||||
'status': participant_status_label(status), | 'status': participant_status_label(status), | ||||
'orgname': organizer.name(), | 'orgname': organizer.name(), | ||||
'orgemail': organizer.email() | 'orgemail': organizer.email(), | ||||
'domain': domain | |||||
} | } | ||||
def send_owner_confirmation(resource, owner, itip_event): | def send_owner_confirmation(resource, owner, itip_event): | ||||
""" | """ | ||||
Send a reservation request to the resource owner for manual confirmation (ACCEPT or | Send a reservation request to the resource owner for manual confirmation (ACCEPT or | ||||
DECLINE). | DECLINE). | ||||
▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines |
line break before binary operator