Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117952826
D629.1775492189.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None
D629.1775492189.diff
View Options
diff --git a/wallace/module_resources.py b/wallace/module_resources.py
--- a/wallace/module_resources.py
+++ b/wallace/module_resources.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+# pylint: disable=too-many-lines
# Copyright 2010-2015 Kolab Systems AG (http://www.kolabsys.com)
#
# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
@@ -17,40 +18,39 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+import base64
import datetime
-import icalendar
+
+from email import message_from_string
+from email.parser import Parser
+from email.utils import formataddr
+from email.utils import getaddresses
+
import os
-import pytz
import random
+import re
import signal
-import tempfile
import time
-from urlparse import urlparse
-from dateutil.tz import tzlocal
-import base64
import uuid
-import re
-from email import message_from_string
-from email.parser import Parser
-from email.utils import formataddr
-from email.utils import getaddresses
+from dateutil.tz import tzlocal
import modules
-import pykolab
import kolabformat
+import pykolab
from pykolab.auth import Auth
from pykolab.conf import Conf
from pykolab.imap import IMAP
+from pykolab.logger import LoggerAdapter
+from pykolab.itip import events_from_message
+from pykolab.itip import check_event_conflict
+from pykolab.translate import _
from pykolab.xml import to_dt
from pykolab.xml import utils as xmlutils
from pykolab.xml import event_from_message
from pykolab.xml import participant_status_label
-from pykolab.itip import events_from_message
-from pykolab.itip import check_event_conflict
-from pykolab.translate import _
# define some contstants used in the code below
COND_NOTIFY = 256
@@ -59,16 +59,18 @@
ACT_REJECT = 8
ACT_ACCEPT_AND_NOTIFY = ACT_ACCEPT + COND_NOTIFY
+# noqa: E241
policy_name_map = {
- 'ACT_MANUAL': ACT_MANUAL,
- 'ACT_ACCEPT': ACT_ACCEPT,
- 'ACT_REJECT': ACT_REJECT,
+ 'ACT_MANUAL': ACT_MANUAL, # noqa: E241
+ 'ACT_ACCEPT': ACT_ACCEPT, # noqa: E241
+ 'ACT_REJECT': ACT_REJECT, # noqa: E241
'ACT_ACCEPT_AND_NOTIFY': ACT_ACCEPT_AND_NOTIFY
}
+# pylint: disable=invalid-name
log = pykolab.getLogger('pykolab.wallace/resources')
extra_log_params = {'qid': '-'}
-log = pykolab.logger.LoggerAdapter(log, extra_log_params)
+log = LoggerAdapter(log, extra_log_params)
conf = pykolab.getConf()
@@ -77,24 +79,28 @@
auth = None
imap = None
+
def __init__():
modules.register('resources', execute, description=description(), heartbeat=heartbeat)
+
def accept(filepath):
new_filepath = os.path.join(
- mybasepath,
- 'ACCEPT',
- os.path.basename(filepath)
- )
+ mybasepath,
+ 'ACCEPT',
+ os.path.basename(filepath)
+ )
cleanup()
os.rename(filepath, new_filepath)
filepath = new_filepath
- exec('modules.cb_action_ACCEPT(%r, %r)' % ('resources',filepath))
+ exec('modules.cb_action_ACCEPT(%r, %r)' % ('resources', filepath))
+
def description():
return """Resource management module."""
+
def cleanup():
global auth, imap, extra_log_params
@@ -109,7 +115,13 @@
imap.disconnect()
del imap
-def execute(*args, **kw):
+
+# pylint: disable=inconsistent-return-statements
+# pylint: disable=too-many-branches
+# pylint: disable=too-many-locals
+# pylint: disable=too-many-return-statements
+# pylint: disable=too-many-statements
+def execute(*args, **kw): # noqa: C901
global auth, imap, extra_log_params
# TODO: Test for correct call.
@@ -118,12 +130,12 @@
extra_log_params['qid'] = os.path.basename(filepath)
# (re)set language to default
- pykolab.translate.setUserLanguage(conf.get('kolab','default_locale'))
+ pykolab.translate.setUserLanguage(conf.get('kolab', 'default_locale'))
if not os.path.isdir(mybasepath):
os.makedirs(mybasepath)
- for stage in ['incoming', 'ACCEPT', 'REJECT', 'HOLD', 'DEFER' ]:
+ for stage in ['incoming', 'ACCEPT', 'REJECT', 'HOLD', 'DEFER']:
if not os.path.isdir(os.path.join(mybasepath, stage)):
os.makedirs(os.path.join(mybasepath, stage))
@@ -132,37 +144,37 @@
auth = Auth()
imap = IMAP()
- if kw.has_key('stage'):
+ if 'stage' in kw:
log.debug(
- _("Issuing callback after processing to stage %s") % (
- kw['stage']
- ),
- level=8
- )
+ _("Issuing callback after processing to stage %s") % (
+ kw['stage']
+ ),
+ level=8
+ )
log.debug(_("Testing cb_action_%s()") % (kw['stage']), level=8)
if hasattr(modules, 'cb_action_%s' % (kw['stage'])):
log.debug(
- _("Attempting to execute cb_action_%s()") % (kw['stage']),
- level=8
- )
+ _("Attempting to execute cb_action_%s()") % (kw['stage']),
+ level=8
+ )
exec(
- 'modules.cb_action_%s(%r, %r)' % (
- kw['stage'],
- 'resources',
- filepath
- )
+ 'modules.cb_action_%s(%r, %r)' % (
+ kw['stage'],
+ 'resources',
+ filepath
)
+ )
return filepath
else:
# Move to incoming
new_filepath = os.path.join(
- mybasepath,
- 'incoming',
- os.path.basename(filepath)
- )
+ mybasepath,
+ 'incoming',
+ os.path.basename(filepath)
+ )
if not filepath == new_filepath:
log.debug("Renaming %r to %r" % (filepath, new_filepath))
@@ -176,8 +188,11 @@
if not message.get('X-Kolab-To'):
return filepath
- recipients = [address for displayname,address in getaddresses(message.get_all('X-Kolab-To'))]
- sender_email = [address for displayname,address in getaddresses(message.get_all('X-Kolab-From'))][0]
+ recipients = [address for displayname, address in getaddresses(message.get_all('X-Kolab-To'))]
+
+ sender_email = [
+ address for displayname, address in getaddresses(message.get_all('X-Kolab-From'))
+ ][0]
any_itips = False
any_resources = False
@@ -188,43 +203,46 @@
# is an iTip message by checking the length of this list.
try:
itip_events = events_from_message(message, ['REQUEST', 'REPLY', 'CANCEL'])
- except Exception, e:
- log.error(_("Failed to parse iTip events from message: %r" % (e)))
+
+ # pylint: disable=broad-except
+ except Exception as errmsg:
+ log.error(_("Failed to parse iTip events from message: %r" % (errmsg)))
itip_events = []
if not len(itip_events) > 0:
- log.info(
- _("Message is not an iTip message or does not contain any " + \
- "(valid) iTip.")
- )
+ log.info("Message is not an iTip message or does not contain any (valid) iTip.")
else:
any_itips = True
log.debug(
- _("iTip events attached to this message contain the " + \
- "following information: %r") % (itip_events),
- level=8
- )
+ "iTip events attached to this message contain the following information: %r" % (
+ itip_events
+ ),
+ level=8
+ )
if any_itips:
# See if any iTip actually allocates a resource.
- if len([x['resources'] for x in itip_events if x.has_key('resources')]) > 0 \
- or len([x['attendees'] for x in itip_events if x.has_key('attendees')]) > 0:
- possibly_any_resources = True
+ if (len([x['resources'] for x in itip_events if 'resources' in x]) > 0
+ or len([x['attendees'] for x in itip_events if 'attendees' in x]) > 0):
+
+ possibly_any_resources = True
if possibly_any_resources:
auth.connect()
for recipient in recipients:
# extract reference UID from recipients like resource+UID@domain.org
- if re.match('.+\+[A-Za-z0-9=/-]+@', recipient):
+ if re.match(r'.+\+[A-Za-z0-9=/-]+@', recipient):
try:
(prefix, host) = recipient.split('@')
(local, uid) = prefix.split('+')
reference_uid = base64.b64decode(uid, '-/')
recipient = local + '@' + host
- except:
+
+ # pylint: disable=broad-except
+ except Exception:
continue
if not len(resource_record_from_email_address(recipient)) == 0:
@@ -233,9 +251,14 @@
if any_resources:
if not any_itips:
- log.debug(_("Not an iTip message, but sent to resource nonetheless. Reject message"), level=5)
+ log.debug(
+ _("Not an iTip message, but sent to resource nonetheless. Reject message"),
+ level=5
+ )
+
reject(filepath)
return False
+
else:
# Continue. Resources and iTips. We like.
pass
@@ -253,11 +276,16 @@
# check if resource attendees match the envelope recipient
if len(resource_dns) == 0:
- log.info(_("No resource attendees matching envelope recipient %s, Reject message") % (resource_recipient))
+ log.info(
+ _("No resource attendees matching envelope recipient %s, Reject message") % (
+ resource_recipient
+ )
+ )
+
log.debug("%r" % (itip_events), level=8)
reject(filepath)
- return False
+ return False
# Get the resource details, which includes details on the IMAP folder
# This may append resource collection members to recource_dns
@@ -276,23 +304,44 @@
# find initial reservation referenced by the reply
if reference_uid:
- (event, master) = find_existing_event(reference_uid, itip_event['recurrence-id'], receiving_resource)
- log.debug(_("iTip REPLY to %r, %r; matches %r") % (reference_uid, itip_event['recurrence-id'], type(event)), level=8)
+ (event, master) = find_existing_event(
+ reference_uid,
+ itip_event['recurrence-id'],
+ receiving_resource
+ )
+
+ log.debug(
+ _("iTip REPLY to %r, %r; matches %r") % (
+ reference_uid,
+ itip_event['recurrence-id'],
+ type(event)
+ ),
+ level=8
+ )
if event:
try:
sender_attendee = itip_event['xml'].get_attendee_by_email(sender_email)
owner_reply = sender_attendee.get_participant_status()
- log.debug(_("Sender Attendee: %r => %r") % (sender_attendee, owner_reply), level=8)
- except Exception, e:
+ log.debug(
+ _("Sender Attendee: %r => %r") % (sender_attendee, owner_reply),
+ level=8
+ )
+
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Could not find envelope sender attendee: %r") % (e))
continue
# compare sequence number to avoid outdated replies
if not itip_event['sequence'] == event.get_sequence():
- log.info(_("The iTip reply sequence (%r) doesn't match the referred event version (%r). Ignoring.") % (
- itip_event['sequence'], event.get_sequence()
- ))
+ log.info(
+ _("The iTip reply sequence (%r) doesn't match the referred event version (%r). Ignoring.") % (
+ itip_event['sequence'],
+ event.get_sequence()
+ )
+ )
+
continue
# forward owner response comment
@@ -313,7 +362,11 @@
sender_attendee.get_participant_status(True), reference_uid
))
else:
- log.info(_("Event referenced by this REPLY (%r) not found in resource calendar") % (reference_uid))
+ log.info(
+ _("Event referenced by this REPLY (%r) not found in resource calendar") % (
+ reference_uid
+ )
+ )
else:
log.info(_("No event reference found in this REPLY. Ignoring."))
@@ -324,9 +377,17 @@
# else:
try:
- receiving_attendee = itip_event['xml'].get_attendee_by_email(receiving_resource['mail'])
- log.debug(_("Receiving Resource: %r; %r") % (receiving_resource, receiving_attendee), level=8)
- except Exception, e:
+ receiving_attendee = itip_event['xml'].get_attendee_by_email(
+ receiving_resource['mail']
+ )
+
+ log.debug(
+ _("Receiving Resource: %r; %r") % (receiving_resource, receiving_attendee),
+ level=8
+ )
+
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Could not find envelope attendee: %r") % (e))
continue
@@ -337,23 +398,53 @@
if (att_delegated or att_nonpart) and not att_rsvp:
done = True
- log.debug(_("Recipient %r is non-participant, ignoring message") % (receiving_resource['mail']), level=8)
+
+ log.debug(
+ _("Recipient %r is non-participant, ignoring message") % (
+ receiving_resource['mail']
+ ),
+ level=8
+ )
# process CANCEL messages
if not done and itip_event['method'] == "CANCEL":
for resource in resource_dns:
- if resources[resource]['mail'] in [a.get_email() for a in itip_event['xml'].get_attendees()] \
- and resources[resource].has_key('kolabtargetfolder'):
- (event, master) = find_existing_event(itip_event['uid'], itip_event['recurrence-id'], resources[resource])
- if event is None:
- log.debug(_("Cancellation for an event %r: not found, skipping") % (itip_event['uid']), level=8)
+ r_emails = [a.get_email() for a in itip_event['xml'].get_attendees()]
+ _resource = resources[resource]
+
+ if _resource['mail'] in r_emails and 'kolabtargetfolder' in _resource:
+ (event, master) = find_existing_event(
+ itip_event['uid'],
+ itip_event['recurrence-id'],
+ _resource
+ )
+
+ if not event:
+ continue
+
# remove entire event
- elif master is None:
- log.debug(_("Cancellation for entire event %r: deleting") % (itip_event['uid']), level=8)
- delete_resource_event(itip_event['uid'], resources[resource], event._msguid)
+ if master is None:
+ log.debug(
+ _("Cancellation for entire event %r: deleting") % (itip_event['uid']),
+ level=8
+ )
+
+ delete_resource_event(
+ itip_event['uid'],
+ resources[resource],
+ event._msguid
+ )
+
# just cancel one single occurrence: add exception with status=cancelled
else:
- log.debug(_("Cancellation for a single occurrence %r of %r: updating...") % (itip_event['recurrence-id'], itip_event['uid']), level=8)
+ log.debug(
+ _("Cancellation for a single occurrence %r of %r: updating...") % (
+ itip_event['recurrence-id'],
+ itip_event['uid']
+ ),
+ level=8
+ )
+
event.set_status('CANCELLED')
event.set_transparency(True)
_itip_event = dict(xml=event, uid=event.get_uid(), _master=master)
@@ -367,9 +458,13 @@
cleanup()
return
-
# do the magic for the receiving attendee
- (available_resource, itip_event) = check_availability(itip_events, resource_dns, resources, receiving_attendee)
+ (available_resource, itip_event) = check_availability(
+ itip_events,
+ resource_dns,
+ resources,
+ receiving_attendee
+ )
_reject = False
resource = None
@@ -377,10 +472,12 @@
# accept reservation
if available_resource is not None:
- if available_resource['mail'] in [a.get_email() for a in itip_event['xml'].get_attendees()]:
+ atts = [a.get_email() for a in itip_event['xml'].get_attendees()]
+ if available_resource['mail'] in atts:
# check if reservation was delegated
- if available_resource['mail'] != receiving_resource['mail'] and receiving_attendee.get_participant_status() == kolabformat.PartDelegated:
- original_resource = receiving_resource
+ if available_resource['mail'] != receiving_resource['mail']:
+ if receiving_attendee.get_participant_status() == kolabformat.PartDelegated:
+ original_resource = receiving_resource
resource = available_resource
else:
@@ -390,20 +487,33 @@
if available_resource.has_key('memberof'):
original_resource = resources[available_resource['memberof']]
- if original_resource['mail'] in [a.get_email() for a in itip_event['xml'].get_attendees()]:
+ atts = [a.get_email() for a in itip_event['xml'].get_attendees()]
+
+ if original_resource['mail'] in atts:
#
# Delegate:
# - delegator: the original resource collection
# - delegatee: the target resource
#
- itip_event['xml'].delegate(original_resource['mail'], available_resource['mail'], available_resource['cn'])
+ itip_event['xml'].delegate(
+ original_resource['mail'],
+ available_resource['mail'],
+ available_resource['cn']
+ )
# set delegator to NON-PARTICIPANT and RSVP=FALSE
delegator = itip_event['xml'].get_attendee_by_email(original_resource['mail'])
delegator.set_role(kolabformat.NonParticipant)
delegator.set_rsvp(False)
- log.debug(_("Delegate invitation for resource collection %r to %r") % (original_resource['mail'], available_resource['mail']), level=8)
+ log.debug(
+ _("Delegate invitation for resource collection %r to %r") % (
+ original_resource['mail'],
+ available_resource['mail']
+ ),
+ level=8
+ )
+
resource = available_resource
# Look for ACT_REJECT policy
@@ -418,11 +528,32 @@
break
if resource is not None and not _reject:
- log.debug(_("Accept invitation for individual resource %r / %r") % (resource['dn'], resource['mail']), level=8)
- accept_reservation_request(itip_event, resource, original_resource, False, invitationpolicy)
+ log.debug(
+ _("Accept invitation for individual resource %r / %r") % (
+ resource['dn'],
+ resource['mail']
+ ),
+ level=8
+ )
+
+ accept_reservation_request(
+ itip_event,
+ resource,
+ original_resource,
+ False,
+ invitationpolicy
+ )
+
else:
resource = resources[resource_dns[0]] # this is the receiving resource record
- log.debug(_("Decline invitation for individual resource %r / %r") % (resource['dn'], resource['mail']), level=8)
+ log.debug(
+ _("Decline invitation for individual resource %r / %r") % (
+ resource['dn'],
+ resource['mail']
+ ),
+ level=8
+ )
+
decline_reservation_request(itip_event, resource)
cleanup()
@@ -463,7 +594,8 @@
if resource_attrs.has_key('kolabtargetfolder'):
try:
expunge_resource_calendar(resource_attrs['kolabtargetfolder'])
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Expunge resource calendar for %s (%s) failed: %r") % (
resource_dn, resource_attrs['kolabtargetfolder'], e
))
@@ -507,11 +639,10 @@
typ, data = imap.imap.m.fetch(num, '(RFC822)')
- event_message = message_from_string(data[0][1])
-
try:
event = event_from_message(message_from_string(data[0][1]))
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to parse event from message %s/%s: %r") % (mailbox, num, e))
continue
@@ -551,7 +682,8 @@
# sets the 'conflicting' flag and adds a list of conflicting events found
try:
num_messages += read_resource_calendar(resources[resource], itip_events)
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to read resource calendar for %r: %r") % (resource, e))
end = time.time()
@@ -704,15 +836,15 @@
try:
msguid = re.search(r"\WUID (\d+)", data[0][0]).group(1)
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception:
log.error(_("No UID found in IMAP response: %r") % (data[0][0]))
continue
- event_message = message_from_string(data[0][1])
-
try:
event = event_from_message(message_from_string(data[0][1]))
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to parse event from message %s/%s: %r") % (mailbox, num, e))
continue
@@ -756,7 +888,8 @@
try:
imap.imap.m.select(imap.folder_quote(mailbox))
typ, data = imap.imap.m.search(None, '(UNDELETED HEADER SUBJECT "%s")' % (uid))
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to access resource calendar:: %r") % (e))
return event
@@ -765,7 +898,8 @@
try:
msguid = re.search(r"\WUID (\d+)", data[0][0]).group(1)
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("No UID found in IMAP response: %r") % (data[0][0]))
continue
@@ -792,7 +926,8 @@
if event is not None:
setattr(event, '_msguid', msguid)
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to parse event from message %s/%s: %r") % (mailbox, num, e))
event = None
master = None
@@ -918,7 +1053,8 @@
)
return result
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to save event to resource calendar at %r: %r") % (
resource['kolabtargetfolder'], e
))
@@ -956,7 +1092,8 @@
imap.imap.m.expunge()
return True
- except Exception, e:
+ # pylint: disable=broad-except
+ except Exception as e:
log.error(_("Failed to delete calendar object %r from folder %r: %r") % (
uid, targetfolder, e
))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 4:16 PM (2 h, 36 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18782121
Default Alt Text
D629.1775492189.diff (24 KB)
Attached To
Mode
D629: Avoid cancelling the status of an event that has not been found
Attached
Detach File
Event Timeline