Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_versioned_choice(self):
field = ChoiceField('foo', field_uri='bar', choices={
Choice('c1'), Choice('c2', supported_from=EXCHANGE_2010)
})
with self.assertRaises(ValueError):
field.clean('XXX') # Value must be a valid choice
field.clean('c2', version=None)
with self.assertRaises(ErrorInvalidServerVersion):
field.clean('c2', version=Version(EXCHANGE_2007))
field.clean('c2', version=Version(EXCHANGE_2010))
field.clean('c2', version=Version(EXCHANGE_2013))
]
__slots__ = tuple(f.name for f in FIELDS)
class MultiFieldIndexedElement(IndexedElement):
"""Base class for all classes that implement an indexed element with multiple fields"""
__slots__ = tuple()
class PhysicalAddress(MultiFieldIndexedElement):
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/entry-physicaladdress"""
ELEMENT_NAME = 'Entry'
FIELDS = [
LabelField('label', field_uri='Key', choices={
Choice('Business'), Choice('Home'), Choice('Other')
}, default='Business'),
NamedSubField('street', field_uri='Street'), # Street, house number, etc.
NamedSubField('city', field_uri='City'),
NamedSubField('state', field_uri='State'),
NamedSubField('country', field_uri='CountryOrRegion'),
NamedSubField('zipcode', field_uri='PostalCode'),
]
__slots__ = tuple(f.name for f in FIELDS)
def clean(self, version=None):
# pylint: disable=access-member-before-definition
if isinstance(self.zipcode, int):
self.zipcode = text_type(self.zipcode)
super(PhysicalAddress, self).clean(version=version)
is_required=True, default='Unknown'),
]
FIELDS = Item.FIELDS + LOCAL_FIELDS
__slots__ = tuple(f.name for f in LOCAL_FIELDS)
class MeetingRequest(BaseMeetingItem, AcceptDeclineMixIn):
"""
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/meetingrequest
"""
ELEMENT_NAME = 'MeetingRequest'
LOCAL_FIELDS = [
ChoiceField('meeting_request_type', field_uri='meetingRequest:MeetingRequestType',
choices={Choice('FullUpdate'), Choice('InformationalUpdate'), Choice('NewMeetingRequest'),
Choice('None'), Choice('Outdated'), Choice('PrincipalWantsCopy'),
Choice('SilentUpdate')},
default='None'),
ChoiceField('intended_free_busy_status', field_uri='meetingRequest:IntendedFreeBusyStatus', choices={
Choice('Free'), Choice('Tentative'), Choice('Busy'), Choice('OOF'), Choice('NoData')},
is_required=True, default='Busy'),
] + [f for f in CalendarItem.LOCAL_FIELDS[1:] if f.name != 'is_response_requested']
# FIELDS on this element are shuffled compared to other elements
culture_idx = None
for i, field in enumerate(Item.FIELDS):
if field.name == 'culture':
culture_idx = i
break
FIELDS = Item.FIELDS[:culture_idx + 1] + BaseMeetingItem.LOCAL_FIELDS + LOCAL_FIELDS + Item.FIELDS[culture_idx + 1:]
__slots__ = tuple(f.name for f in LOCAL_FIELDS)
self.status = Task.COMPLETED
self.percent_complete = Decimal(100)
self.save()
class Contact(Item):
"""
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/contact
"""
ELEMENT_NAME = 'Contact'
LOCAL_FIELDS = [
TextField('file_as', field_uri='contacts:FileAs'),
ChoiceField('file_as_mapping', field_uri='contacts:FileAsMapping', choices={
Choice('None'), Choice('LastCommaFirst'), Choice('FirstSpaceLast'), Choice('Company'),
Choice('LastCommaFirstCompany'), Choice('CompanyLastFirst'), Choice('LastFirst'),
Choice('LastFirstCompany'), Choice('CompanyLastCommaFirst'), Choice('LastFirstSuffix'),
Choice('LastSpaceFirstCompany'), Choice('CompanyLastSpaceFirst'), Choice('LastSpaceFirst'),
Choice('DisplayName'), Choice('FirstName'), Choice('LastFirstMiddleSuffix'), Choice('LastName'),
Choice('Empty'),
}),
TextField('display_name', field_uri='contacts:DisplayName', is_required=True),
CharField('given_name', field_uri='contacts:GivenName'),
TextField('initials', field_uri='contacts:Initials'),
CharField('middle_name', field_uri='contacts:MiddleName'),
TextField('nickname', field_uri='contacts:Nickname'),
# Placeholder for CompleteName
TextField('company_name', field_uri='contacts:CompanyName'),
EmailAddressesField('email_addresses', field_uri='contacts:EmailAddress'),
PhysicalAddressField('physical_addresses', field_uri='contacts:PhysicalAddress'),
PhoneNumberField('phone_numbers', field_uri='contacts:PhoneNumber'),
TextField('assistant_name', field_uri='contacts:AssistantName'),
DateTimeField('birthday', field_uri='contacts:Birthday'),
__slots__ = tuple(f.name for f in LOCAL_FIELDS)
class MeetingRequest(BaseMeetingItem, AcceptDeclineMixIn):
"""
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/meetingrequest
"""
ELEMENT_NAME = 'MeetingRequest'
LOCAL_FIELDS = [
ChoiceField('meeting_request_type', field_uri='meetingRequest:MeetingRequestType',
choices={Choice('FullUpdate'), Choice('InformationalUpdate'), Choice('NewMeetingRequest'),
Choice('None'), Choice('Outdated'), Choice('PrincipalWantsCopy'),
Choice('SilentUpdate')},
default='None'),
ChoiceField('intended_free_busy_status', field_uri='meetingRequest:IntendedFreeBusyStatus', choices={
Choice('Free'), Choice('Tentative'), Choice('Busy'), Choice('OOF'), Choice('NoData')},
is_required=True, default='Busy'),
] + [f for f in CalendarItem.LOCAL_FIELDS[1:] if f.name != 'is_response_requested']
# FIELDS on this element are shuffled compared to other elements
culture_idx = None
for i, field in enumerate(Item.FIELDS):
if field.name == 'culture':
culture_idx = i
break
FIELDS = Item.FIELDS[:culture_idx + 1] + BaseMeetingItem.LOCAL_FIELDS + LOCAL_FIELDS + Item.FIELDS[culture_idx + 1:]
__slots__ = tuple(f.name for f in LOCAL_FIELDS)
class MeetingMessage(BaseMeetingItem):
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/meetingmessage"""
LabelField('label', field_uri='Key', choices={
Choice('EmailAddress1'), Choice('EmailAddress2'), Choice('EmailAddress3')
}, default='EmailAddress1'),
EmailSubField('email'),
]
__slots__ = tuple(f.name for f in FIELDS)
class PhoneNumber(SingleFieldIndexedElement):
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/entry-phonenumber"""
ELEMENT_NAME = 'Entry'
FIELDS = [
LabelField('label', field_uri='Key', choices={
Choice('AssistantPhone'), Choice('BusinessFax'), Choice('BusinessPhone'), Choice('BusinessPhone2'),
Choice('Callback'), Choice('CarPhone'), Choice('CompanyMainPhone'), Choice('HomeFax'), Choice('HomePhone'),
Choice('HomePhone2'), Choice('Isdn'), Choice('MobilePhone'), Choice('OtherFax'), Choice('OtherTelephone'),
Choice('Pager'), Choice('PrimaryPhone'), Choice('RadioPhone'), Choice('Telex'), Choice('TtyTddPhone'),
}, default='PrimaryPhone'),
SubField('phone_number'),
]
__slots__ = tuple(f.name for f in FIELDS)
class MultiFieldIndexedElement(IndexedElement):
"""Base class for all classes that implement an indexed element with multiple fields"""
__slots__ = tuple()
class PhysicalAddress(MultiFieldIndexedElement):
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/entry-physicaladdress"""
MimeContentField('mime_content', field_uri='item:MimeContent', is_read_only_after_send=True),
EWSElementField('parent_folder_id', field_uri='item:ParentFolderId', value_cls=ParentFolderId,
is_read_only=True),
CharField('item_class', field_uri='item:ItemClass', is_read_only=True),
CharField('subject', field_uri='item:Subject'),
ChoiceField('sensitivity', field_uri='item:Sensitivity', choices={
Choice('Normal'), Choice('Personal'), Choice('Private'), Choice('Confidential')
}, is_required=True, default='Normal'),
TextField('text_body', field_uri='item:TextBody', is_read_only=True, supported_from=EXCHANGE_2013),
BodyField('body', field_uri='item:Body'), # Accepts and returns Body or HTMLBody instances
AttachmentField('attachments', field_uri='item:Attachments'), # ItemAttachment or FileAttachment
DateTimeField('datetime_received', field_uri='item:DateTimeReceived', is_read_only=True),
IntegerField('size', field_uri='item:Size', is_read_only=True), # Item size in bytes
CharListField('categories', field_uri='item:Categories'),
ChoiceField('importance', field_uri='item:Importance', choices={
Choice('Low'), Choice('Normal'), Choice('High')
}, is_required=True, default='Normal'),
TextField('in_reply_to', field_uri='item:InReplyTo'),
BooleanField('is_submitted', field_uri='item:IsSubmitted', is_read_only=True),
BooleanField('is_draft', field_uri='item:IsDraft', is_read_only=True),
BooleanField('is_from_me', field_uri='item:IsFromMe', is_read_only=True),
BooleanField('is_resend', field_uri='item:IsResend', is_read_only=True),
BooleanField('is_unmodified', field_uri='item:IsUnmodified', is_read_only=True),
MessageHeaderField('headers', field_uri='item:InternetMessageHeaders', is_read_only=True),
DateTimeField('datetime_sent', field_uri='item:DateTimeSent', is_read_only=True),
DateTimeField('datetime_created', field_uri='item:DateTimeCreated', is_read_only=True),
# Placeholder for ResponseObjects
DateTimeField('reminder_due_by', field_uri='item:ReminderDueBy', is_required_after_save=True,
is_searchable=False),
BooleanField('reminder_is_set', field_uri='item:ReminderIsSet', is_required=True, default=False),
IntegerField('reminder_minutes_before_start', field_uri='item:ReminderMinutesBeforeStart',
is_required_after_save=True, min=0, default=0),
ELEMENT_NAME = 'FolderId'
__slots__ = tuple()
class Mailbox(EWSElement):
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/mailbox"""
ELEMENT_NAME = 'Mailbox'
FIELDS = [
TextField('name', field_uri='Name'),
EmailAddressField('email_address', field_uri='EmailAddress'),
ChoiceField('routing_type', field_uri='RoutingType', choices={Choice('SMTP')}, default='SMTP'),
ChoiceField('mailbox_type', field_uri='MailboxType', choices={
Choice('Mailbox'), Choice('PublicDL'), Choice('PrivateDL'), Choice('Contact'), Choice('PublicFolder'),
Choice('Unknown'), Choice('OneOff'), Choice('GroupMailbox', supported_from=EXCHANGE_2013)
}, default='Mailbox'),
EWSElementField('item_id', value_cls=ItemId, is_read_only=True),
]
__slots__ = tuple(f.name for f in FIELDS)
def clean(self, version=None):
super(Mailbox, self).clean(version=version)
if not self.email_address and not self.item_id:
# See "Remarks" section of
# https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/mailbox
raise ValueError("Mailbox must have either 'email_address' or 'item_id' set")
def __hash__(self):
# Exchange may add 'mailbox_type' and 'name' on insert. We're satisfied if the item_id or email address matches.
if self.item_id:
class Item(BaseItem):
"""
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/item
"""
ELEMENT_NAME = 'Item'
LOCAL_FIELDS = [
MimeContentField('mime_content', field_uri='item:MimeContent', is_read_only_after_send=True),
EWSElementField('parent_folder_id', field_uri='item:ParentFolderId', value_cls=ParentFolderId,
is_read_only=True),
CharField('item_class', field_uri='item:ItemClass', is_read_only=True),
CharField('subject', field_uri='item:Subject'),
ChoiceField('sensitivity', field_uri='item:Sensitivity', choices={
Choice('Normal'), Choice('Personal'), Choice('Private'), Choice('Confidential')
}, is_required=True, default='Normal'),
TextField('text_body', field_uri='item:TextBody', is_read_only=True, supported_from=EXCHANGE_2013),
BodyField('body', field_uri='item:Body'), # Accepts and returns Body or HTMLBody instances
AttachmentField('attachments', field_uri='item:Attachments'), # ItemAttachment or FileAttachment
DateTimeField('datetime_received', field_uri='item:DateTimeReceived', is_read_only=True),
IntegerField('size', field_uri='item:Size', is_read_only=True), # Item size in bytes
CharListField('categories', field_uri='item:Categories'),
ChoiceField('importance', field_uri='item:Importance', choices={
Choice('Low'), Choice('Normal'), Choice('High')
}, is_required=True, default='Normal'),
TextField('in_reply_to', field_uri='item:InReplyTo'),
BooleanField('is_submitted', field_uri='item:IsSubmitted', is_read_only=True),
BooleanField('is_draft', field_uri='item:IsDraft', is_read_only=True),
BooleanField('is_from_me', field_uri='item:IsFromMe', is_read_only=True),
BooleanField('is_resend', field_uri='item:IsResend', is_read_only=True),
BooleanField('is_unmodified', field_uri='item:IsUnmodified', is_read_only=True),