@backtomyfuture/exchange-cli-darwin-arm64 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/_internal/Python +0 -0
- package/bin/_internal/Python.framework/Python +0 -0
- package/bin/_internal/Python.framework/Resources/Info.plist +3 -3
- package/bin/_internal/Python.framework/Versions/3.12/Python +0 -0
- package/bin/_internal/Python.framework/Versions/{3.14 → 3.12}/Resources/Info.plist +3 -3
- package/bin/_internal/Python.framework/Versions/Current/Python +0 -0
- package/bin/_internal/Python.framework/Versions/Current/Resources/Info.plist +3 -3
- package/bin/_internal/_cffi_backend.cpython-312-darwin.so +0 -0
- package/bin/_internal/ada92cb5d92a588d1b93__mypyc.cpython-312-darwin.so +0 -0
- package/bin/_internal/base_library.zip +0 -0
- package/bin/_internal/certifi/cacert.pem +125 -660
- package/bin/_internal/charset_normalizer/{md.cpython-314-darwin.so → cd.cpython-312-darwin.so} +0 -0
- package/bin/_internal/charset_normalizer/{cd.cpython-314-darwin.so → md.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/METADATA +1 -1
- package/bin/_internal/click-8.4.2.dist-info/RECORD +40 -0
- package/bin/_internal/cryptography/hazmat/bindings/_rust.abi3.so +0 -0
- package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/METADATA +7 -36
- package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/RECORD +137 -122
- package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/WHEEL +1 -1
- package/bin/_internal/cryptography-48.0.1.dist-info/sboms/cryptography-rust.cyclonedx.json +1362 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/sboms/sbom.json +43 -0
- package/bin/_internal/exchangelib/__init__.py +120 -0
- package/bin/_internal/exchangelib/account.py +896 -0
- package/bin/_internal/exchangelib/attachments.py +268 -0
- package/bin/_internal/exchangelib/autodiscover/__init__.py +24 -0
- package/bin/_internal/exchangelib/autodiscover/cache.py +150 -0
- package/bin/_internal/exchangelib/autodiscover/discovery.py +491 -0
- package/bin/_internal/exchangelib/autodiscover/protocol.py +58 -0
- package/bin/_internal/exchangelib/configuration.py +106 -0
- package/bin/_internal/exchangelib/credentials.py +319 -0
- package/bin/_internal/exchangelib/errors.py +1710 -0
- package/bin/_internal/exchangelib/ewsdatetime.py +309 -0
- package/bin/_internal/exchangelib/extended_properties.py +311 -0
- package/bin/_internal/exchangelib/fields.py +1842 -0
- package/bin/_internal/exchangelib/folders/__init__.py +249 -0
- package/bin/_internal/exchangelib/folders/base.py +954 -0
- package/bin/_internal/exchangelib/folders/collections.py +576 -0
- package/bin/_internal/exchangelib/folders/known_folders.py +856 -0
- package/bin/_internal/exchangelib/folders/queryset.py +187 -0
- package/bin/_internal/exchangelib/folders/roots.py +390 -0
- package/bin/_internal/exchangelib/indexed_properties.py +96 -0
- package/bin/_internal/exchangelib/items/__init__.py +147 -0
- package/bin/_internal/exchangelib/items/base.py +241 -0
- package/bin/_internal/exchangelib/items/calendar_item.py +466 -0
- package/bin/_internal/exchangelib/items/contact.py +263 -0
- package/bin/_internal/exchangelib/items/item.py +413 -0
- package/bin/_internal/exchangelib/items/message.py +201 -0
- package/bin/_internal/exchangelib/items/post.py +38 -0
- package/bin/_internal/exchangelib/items/task.py +139 -0
- package/bin/_internal/exchangelib/properties.py +2364 -0
- package/bin/_internal/exchangelib/protocol.py +823 -0
- package/bin/_internal/exchangelib/queryset.py +691 -0
- package/bin/_internal/exchangelib/recurrence.py +349 -0
- package/bin/_internal/exchangelib/restriction.py +568 -0
- package/bin/_internal/exchangelib/services/__init__.py +117 -0
- package/bin/_internal/exchangelib/services/archive_item.py +33 -0
- package/bin/_internal/exchangelib/services/common.py +983 -0
- package/bin/_internal/exchangelib/services/convert_id.py +45 -0
- package/bin/_internal/exchangelib/services/copy_item.py +7 -0
- package/bin/_internal/exchangelib/services/create_attachment.py +34 -0
- package/bin/_internal/exchangelib/services/create_folder.py +45 -0
- package/bin/_internal/exchangelib/services/create_item.py +97 -0
- package/bin/_internal/exchangelib/services/create_user_configuration.py +19 -0
- package/bin/_internal/exchangelib/services/delete_attachment.py +28 -0
- package/bin/_internal/exchangelib/services/delete_folder.py +21 -0
- package/bin/_internal/exchangelib/services/delete_item.py +51 -0
- package/bin/_internal/exchangelib/services/delete_user_configuration.py +19 -0
- package/bin/_internal/exchangelib/services/empty_folder.py +25 -0
- package/bin/_internal/exchangelib/services/expand_dl.py +21 -0
- package/bin/_internal/exchangelib/services/export_items.py +27 -0
- package/bin/_internal/exchangelib/services/find_folder.py +80 -0
- package/bin/_internal/exchangelib/services/find_item.py +112 -0
- package/bin/_internal/exchangelib/services/find_people.py +106 -0
- package/bin/_internal/exchangelib/services/get_attachment.py +117 -0
- package/bin/_internal/exchangelib/services/get_delegate.py +45 -0
- package/bin/_internal/exchangelib/services/get_events.py +39 -0
- package/bin/_internal/exchangelib/services/get_folder.py +65 -0
- package/bin/_internal/exchangelib/services/get_item.py +41 -0
- package/bin/_internal/exchangelib/services/get_mail_tips.py +43 -0
- package/bin/_internal/exchangelib/services/get_persona.py +31 -0
- package/bin/_internal/exchangelib/services/get_room_lists.py +21 -0
- package/bin/_internal/exchangelib/services/get_rooms.py +21 -0
- package/bin/_internal/exchangelib/services/get_searchable_mailboxes.py +48 -0
- package/bin/_internal/exchangelib/services/get_server_time_zones.py +39 -0
- package/bin/_internal/exchangelib/services/get_streaming_events.py +102 -0
- package/bin/_internal/exchangelib/services/get_user_availability.py +67 -0
- package/bin/_internal/exchangelib/services/get_user_configuration.py +43 -0
- package/bin/_internal/exchangelib/services/get_user_oof_settings.py +40 -0
- package/bin/_internal/exchangelib/services/get_user_settings.py +87 -0
- package/bin/_internal/exchangelib/services/inbox_rules.py +104 -0
- package/bin/_internal/exchangelib/services/mark_as_junk.py +27 -0
- package/bin/_internal/exchangelib/services/move_folder.py +27 -0
- package/bin/_internal/exchangelib/services/move_item.py +28 -0
- package/bin/_internal/exchangelib/services/resolve_names.py +104 -0
- package/bin/_internal/exchangelib/services/send_item.py +26 -0
- package/bin/_internal/exchangelib/services/send_notification.py +43 -0
- package/bin/_internal/exchangelib/services/set_user_oof_settings.py +34 -0
- package/bin/_internal/exchangelib/services/subscribe.py +125 -0
- package/bin/_internal/exchangelib/services/sync_folder_hierarchy.py +95 -0
- package/bin/_internal/exchangelib/services/sync_folder_items.py +77 -0
- package/bin/_internal/exchangelib/services/unsubscribe.py +21 -0
- package/bin/_internal/exchangelib/services/update_folder.py +158 -0
- package/bin/_internal/exchangelib/services/update_item.py +113 -0
- package/bin/_internal/exchangelib/services/update_user_configuration.py +17 -0
- package/bin/_internal/exchangelib/services/upload_items.py +47 -0
- package/bin/_internal/exchangelib/settings.py +88 -0
- package/bin/_internal/exchangelib/transport.py +214 -0
- package/bin/_internal/exchangelib/util.py +894 -0
- package/bin/_internal/exchangelib/version.py +320 -0
- package/bin/_internal/exchangelib/winzone.py +662 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/INSTALLER +1 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/METADATA +77 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/RECORD +184 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/licenses/LICENSE +21 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/top_level.txt +1 -0
- package/bin/_internal/libcrypto.3.dylib +0 -0
- package/bin/_internal/libssl.3.dylib +0 -0
- package/bin/_internal/lxml/_elementpath.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/builder.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/{etree.cpython-314-darwin.so → etree.cpython-312-darwin.so} +0 -0
- package/bin/_internal/lxml/html/_difflib.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/html/diff.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/{objectify.cpython-314-darwin.so → objectify.cpython-312-darwin.so} +0 -0
- package/bin/_internal/lxml/sax.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_asyncio.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/termios.cpython-314-darwin.so → python3.12/lib-dynload/_bisect.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_sha2.cpython-314-darwin.so → python3.12/lib-dynload/_blake2.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_bz2.cpython-314-darwin.so → python3.12/lib-dynload/_bz2.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_cn.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_cn.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_hk.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_hk.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_interpqueues.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_iso2022.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_jp.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_jp.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_kr.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_kr.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_tw.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_tw.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_statistics.cpython-314-darwin.so → python3.12/lib-dynload/_contextvars.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_csv.cpython-314-darwin.so → python3.12/lib-dynload/_csv.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_ctypes.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_datetime.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_dbm.cpython-314-darwin.so → python3.12/lib-dynload/_dbm.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_decimal.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_elementtree.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_hashlib.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_heapq.cpython-314-darwin.so → python3.12/lib-dynload/_heapq.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_json.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_lzma.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_md5.cpython-314-darwin.so → python3.12/lib-dynload/_md5.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_multibytecodec.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_multiprocessing.cpython-314-darwin.so → python3.12/lib-dynload/_multiprocessing.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_opcode.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_pickle.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_bisect.cpython-314-darwin.so → python3.12/lib-dynload/_posixshmem.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_posixsubprocess.cpython-314-darwin.so → python3.12/lib-dynload/_posixsubprocess.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_queue.cpython-314-darwin.so → python3.12/lib-dynload/_queue.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_random.cpython-314-darwin.so → python3.12/lib-dynload/_random.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_scproxy.cpython-314-darwin.so → python3.12/lib-dynload/_scproxy.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_sha1.cpython-314-darwin.so → python3.12/lib-dynload/_sha1.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_sha2.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_blake2.cpython-314-darwin.so → python3.12/lib-dynload/_sha3.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_socket.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_ssl.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_posixshmem.cpython-314-darwin.so → python3.12/lib-dynload/_statistics.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_struct.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_uuid.cpython-314-darwin.so → python3.12/lib-dynload/_uuid.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_zoneinfo.cpython-314-darwin.so → python3.12/lib-dynload/_zoneinfo.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/array.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/binascii.cpython-314-darwin.so → python3.12/lib-dynload/binascii.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/fcntl.cpython-314-darwin.so → python3.12/lib-dynload/fcntl.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/grp.cpython-314-darwin.so → python3.12/lib-dynload/grp.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/math.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_sha3.cpython-314-darwin.so → python3.12/lib-dynload/mmap.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/pyexpat.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/readline.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/resource.cpython-314-darwin.so → python3.12/lib-dynload/resource.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/select.cpython-314-darwin.so → python3.12/lib-dynload/select.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/syslog.cpython-314-darwin.so → python3.12/lib-dynload/syslog.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/termios.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/unicodedata.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/zlib.cpython-312-darwin.so +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Casablanca +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/El_Aaiun +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Edmonton +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Vancouver +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Yellowknife +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Saigon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Mountain +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Pacific +0 -0
- package/bin/_internal/tzdata/zoneinfo/leapseconds +4 -4
- package/bin/_internal/tzdata/zoneinfo/tzdata.zi +11 -131
- package/bin/_internal/tzdata/zoneinfo/zone.tab +2 -2
- package/bin/_internal/tzdata/zoneinfo/zone1970.tab +2 -2
- package/bin/_internal/tzdata/zoneinfo/zonenow.tab +8 -2
- package/bin/exchange-cli +0 -0
- package/package.json +10 -7
- package/bin/_internal/81d243bd2c585b0f4821__mypyc.cpython-314-darwin.so +0 -0
- package/bin/_internal/Python.framework/Versions/3.14/Python +0 -0
- package/bin/_internal/_cffi_backend.cpython-314-darwin.so +0 -0
- package/bin/_internal/click-8.3.2.dist-info/RECORD +0 -40
- package/bin/_internal/liblzma.5.dylib +0 -0
- package/bin/_internal/libmpdec.4.dylib +0 -0
- package/bin/_internal/libzstd.1.dylib +0 -0
- package/bin/_internal/lxml/_elementpath.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/builder.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/html/_difflib.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/html/diff.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/sax.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_asyncio.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_codecs_iso2022.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_ctypes.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_decimal.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_elementtree.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_hashlib.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_hmac.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_interpreters.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_json.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_lzma.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_multibytecodec.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_pickle.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_socket.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_ssl.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_struct.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_zstd.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/array.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/math.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/mmap.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/pyexpat.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/readline.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/unicodedata.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/zlib.cpython-314-darwin.so +0 -0
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/INSTALLER +0 -1
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/METADATA +0 -133
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/RECORD +0 -21
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/REQUESTED +0 -0
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/licenses/LICENSE +0 -73
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/top_level.txt +0 -1
- /package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/INSTALLER +0 -0
- /package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/WHEEL +0 -0
- /package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/licenses/LICENSE.txt +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/INSTALLER +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/licenses/LICENSE +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/licenses/LICENSE.APACHE +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/licenses/LICENSE.BSD +0 -0
- /package/bin/_internal/{setuptools/_vendor/importlib_metadata-8.7.1.dist-info → exchangelib-5.6.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from ..errors import InvalidEnumValue
|
|
4
|
+
from ..items import ID_ONLY, ITEM_TRAVERSAL_CHOICES, SHAPE_CHOICES, Persona
|
|
5
|
+
from ..util import MNS, create_element, set_xml_value
|
|
6
|
+
from ..version import EXCHANGE_2013
|
|
7
|
+
from .common import EWSPagingService, folder_ids_element, shape_element
|
|
8
|
+
|
|
9
|
+
log = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class FindPeople(EWSPagingService):
|
|
13
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findpeople-operation"""
|
|
14
|
+
|
|
15
|
+
SERVICE_NAME = "FindPeople"
|
|
16
|
+
element_container_name = f"{{{MNS}}}People"
|
|
17
|
+
supported_from = EXCHANGE_2013
|
|
18
|
+
|
|
19
|
+
def __init__(self, *args, **kwargs):
|
|
20
|
+
super().__init__(*args, **kwargs)
|
|
21
|
+
# A hack to communicate parsing args to _elems_to_objs()
|
|
22
|
+
self.additional_fields = None
|
|
23
|
+
self.shape = None
|
|
24
|
+
|
|
25
|
+
def call(self, folder, additional_fields, restriction, order_fields, shape, query_string, depth, max_items, offset):
|
|
26
|
+
"""Find items in an account. This service can only be called on a single folder.
|
|
27
|
+
|
|
28
|
+
:param folder: the Folder object to query
|
|
29
|
+
:param additional_fields: the extra fields that should be returned with the item, as FieldPath objects
|
|
30
|
+
:param restriction: a Restriction object for
|
|
31
|
+
:param order_fields: the fields to sort the results by
|
|
32
|
+
:param shape: The set of attributes to return
|
|
33
|
+
:param query_string: a QueryString object
|
|
34
|
+
:param depth: How deep in the folder structure to search for items
|
|
35
|
+
:param max_items: the max number of items to return
|
|
36
|
+
:param offset: the offset relative to the first item in the item collection. Usually 0.
|
|
37
|
+
|
|
38
|
+
:return: XML elements for the matching items
|
|
39
|
+
"""
|
|
40
|
+
if shape not in SHAPE_CHOICES:
|
|
41
|
+
raise InvalidEnumValue("shape", shape, SHAPE_CHOICES)
|
|
42
|
+
if depth not in ITEM_TRAVERSAL_CHOICES:
|
|
43
|
+
raise InvalidEnumValue("depth", depth, ITEM_TRAVERSAL_CHOICES)
|
|
44
|
+
self.additional_fields = additional_fields
|
|
45
|
+
self.shape = shape
|
|
46
|
+
return self._elems_to_objs(
|
|
47
|
+
self._paged_call(
|
|
48
|
+
payload_func=self.get_payload,
|
|
49
|
+
max_items=max_items,
|
|
50
|
+
folders=[folder], # We just need the list to satisfy self._paged_call()
|
|
51
|
+
**dict(
|
|
52
|
+
additional_fields=additional_fields,
|
|
53
|
+
restriction=restriction,
|
|
54
|
+
order_fields=order_fields,
|
|
55
|
+
query_string=query_string,
|
|
56
|
+
shape=shape,
|
|
57
|
+
depth=depth,
|
|
58
|
+
page_size=self.page_size,
|
|
59
|
+
offset=offset,
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def _elem_to_obj(self, elem):
|
|
65
|
+
if self.shape == ID_ONLY and self.additional_fields is None:
|
|
66
|
+
return Persona.id_from_xml(elem)
|
|
67
|
+
return Persona.from_xml(elem, account=self.account)
|
|
68
|
+
|
|
69
|
+
def get_payload(
|
|
70
|
+
self, folders, additional_fields, restriction, order_fields, query_string, shape, depth, page_size, offset=0
|
|
71
|
+
):
|
|
72
|
+
# We actually only support a single folder, but self._paged_call() sends us a list
|
|
73
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=dict(Traversal=depth))
|
|
74
|
+
payload.append(
|
|
75
|
+
shape_element(
|
|
76
|
+
tag="m:PersonaShape", shape=shape, additional_fields=additional_fields, version=self.account.version
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
payload.append(
|
|
80
|
+
create_element(
|
|
81
|
+
"m:IndexedPageItemView", attrs=dict(MaxEntriesReturned=page_size, Offset=offset, BasePoint="Beginning")
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
if restriction:
|
|
85
|
+
payload.append(restriction.to_xml(version=self.account.version))
|
|
86
|
+
if order_fields:
|
|
87
|
+
payload.append(set_xml_value(create_element("m:SortOrder"), order_fields, version=self.account.version))
|
|
88
|
+
payload.append(folder_ids_element(folders=folders, version=self.account.version, tag="m:ParentFolderId"))
|
|
89
|
+
if query_string:
|
|
90
|
+
payload.append(query_string.to_xml(version=self.account.version))
|
|
91
|
+
return payload
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def _get_paging_values(elem):
|
|
95
|
+
"""Find paging values. The paging element from FindPeople is different from other paging containers."""
|
|
96
|
+
item_count = int(elem.find(f"{{{MNS}}}TotalNumberOfPeopleInView").text)
|
|
97
|
+
first_matching = int(elem.find(f"{{{MNS}}}FirstMatchingRowIndex").text)
|
|
98
|
+
first_loaded = int(elem.find(f"{{{MNS}}}FirstLoadedRowIndex").text)
|
|
99
|
+
log.debug(
|
|
100
|
+
"Got page with total items %s, first matching %s, first loaded %s ",
|
|
101
|
+
item_count,
|
|
102
|
+
first_matching,
|
|
103
|
+
first_loaded,
|
|
104
|
+
)
|
|
105
|
+
next_offset = None # GetPersona does not support fetching more pages
|
|
106
|
+
return item_count, next_offset
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from itertools import chain
|
|
2
|
+
|
|
3
|
+
from ..attachments import FileAttachment, ItemAttachment
|
|
4
|
+
from ..errors import InvalidEnumValue
|
|
5
|
+
from ..util import (
|
|
6
|
+
MNS,
|
|
7
|
+
DummyResponse,
|
|
8
|
+
ElementNotFound,
|
|
9
|
+
StreamingBase64Parser,
|
|
10
|
+
StreamingContentHandler,
|
|
11
|
+
add_xml_child,
|
|
12
|
+
create_element,
|
|
13
|
+
set_xml_value,
|
|
14
|
+
)
|
|
15
|
+
from .common import EWSAccountService, attachment_ids_element
|
|
16
|
+
|
|
17
|
+
# https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/bodytype
|
|
18
|
+
BODY_TYPE_CHOICES = ("Best", "HTML", "Text")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GetAttachment(EWSAccountService):
|
|
22
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getattachment-operation"""
|
|
23
|
+
|
|
24
|
+
SERVICE_NAME = "GetAttachment"
|
|
25
|
+
element_container_name = f"{{{MNS}}}Attachments"
|
|
26
|
+
cls_map = {cls.response_tag(): cls for cls in (FileAttachment, ItemAttachment)}
|
|
27
|
+
|
|
28
|
+
def call(self, items, include_mime_content, body_type, filter_html_content, additional_fields):
|
|
29
|
+
if body_type and body_type not in BODY_TYPE_CHOICES:
|
|
30
|
+
raise InvalidEnumValue("body_type", body_type, BODY_TYPE_CHOICES)
|
|
31
|
+
return self._elems_to_objs(
|
|
32
|
+
self._chunked_get_elements(
|
|
33
|
+
self.get_payload,
|
|
34
|
+
items=items,
|
|
35
|
+
include_mime_content=include_mime_content,
|
|
36
|
+
body_type=body_type,
|
|
37
|
+
filter_html_content=filter_html_content,
|
|
38
|
+
additional_fields=additional_fields,
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def _elem_to_obj(self, elem):
|
|
43
|
+
return self.cls_map[elem.tag].from_xml(elem=elem, account=self.account)
|
|
44
|
+
|
|
45
|
+
def get_payload(self, items, include_mime_content, body_type, filter_html_content, additional_fields):
|
|
46
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
47
|
+
shape_elem = create_element("m:AttachmentShape")
|
|
48
|
+
if include_mime_content:
|
|
49
|
+
add_xml_child(shape_elem, "t:IncludeMimeContent", "true")
|
|
50
|
+
if body_type:
|
|
51
|
+
add_xml_child(shape_elem, "t:BodyType", body_type)
|
|
52
|
+
if filter_html_content is not None:
|
|
53
|
+
add_xml_child(shape_elem, "t:FilterHtmlContent", "true" if filter_html_content else "false")
|
|
54
|
+
if additional_fields:
|
|
55
|
+
additional_properties = create_element("t:AdditionalProperties")
|
|
56
|
+
expanded_fields = chain(*(f.expand(version=self.account.version) for f in additional_fields))
|
|
57
|
+
set_xml_value(
|
|
58
|
+
additional_properties,
|
|
59
|
+
sorted(expanded_fields, key=lambda f: (getattr(f.field, "field_uri", ""), f.path)),
|
|
60
|
+
version=self.account.version,
|
|
61
|
+
)
|
|
62
|
+
shape_elem.append(additional_properties)
|
|
63
|
+
if len(shape_elem):
|
|
64
|
+
payload.append(shape_elem)
|
|
65
|
+
payload.append(attachment_ids_element(items=items, version=self.account.version))
|
|
66
|
+
return payload
|
|
67
|
+
|
|
68
|
+
def _update_api_version(self, api_version, header):
|
|
69
|
+
if not self.streaming:
|
|
70
|
+
super()._update_api_version(api_version, header)
|
|
71
|
+
# TODO: We're skipping this part in streaming mode because StreamingBase64Parser cannot parse the SOAP header
|
|
72
|
+
|
|
73
|
+
def _get_soap_parts(self, response):
|
|
74
|
+
if not self.streaming:
|
|
75
|
+
return super()._get_soap_parts(response)
|
|
76
|
+
# Pass the response unaltered. We want to use our custom streaming parser
|
|
77
|
+
return None, response
|
|
78
|
+
|
|
79
|
+
def _get_soap_messages(self, body):
|
|
80
|
+
if not self.streaming:
|
|
81
|
+
return super()._get_soap_messages(body)
|
|
82
|
+
# 'body' is actually the raw response passed on by '_get_soap_parts'
|
|
83
|
+
r = body
|
|
84
|
+
parser = StreamingBase64Parser()
|
|
85
|
+
field = FileAttachment.get_field_by_fieldname("_content")
|
|
86
|
+
handler = StreamingContentHandler(parser=parser, ns=field.namespace, element_name=field.field_uri)
|
|
87
|
+
parser.setContentHandler(handler)
|
|
88
|
+
return parser.parse(r)
|
|
89
|
+
|
|
90
|
+
def stream_file_content(self, attachment_id):
|
|
91
|
+
# The streaming XML parser can only stream content of one attachment
|
|
92
|
+
payload = self.get_payload(
|
|
93
|
+
items=[attachment_id],
|
|
94
|
+
include_mime_content=False,
|
|
95
|
+
body_type=None,
|
|
96
|
+
filter_html_content=None,
|
|
97
|
+
additional_fields=None,
|
|
98
|
+
)
|
|
99
|
+
self.streaming = True
|
|
100
|
+
try:
|
|
101
|
+
yield from self._get_response_xml(payload=payload)
|
|
102
|
+
except ElementNotFound as enf:
|
|
103
|
+
# When the returned XML does not contain a Content element, ElementNotFound is thrown by parser.parse().
|
|
104
|
+
# Let the non-streaming SOAP parser parse the response and hook into the normal exception handling.
|
|
105
|
+
# Wrap in DummyResponse because _get_soap_parts() expects an iter_content() method.
|
|
106
|
+
response = DummyResponse(content=enf.data)
|
|
107
|
+
_, body = super()._get_soap_parts(response=response)
|
|
108
|
+
# TODO: We're skipping ._update_api_version() here because we don't have access to the 'api_version' used.
|
|
109
|
+
res = super()._get_soap_messages(body=body)
|
|
110
|
+
for e in self._get_elements_in_response(response=res):
|
|
111
|
+
if isinstance(e, Exception):
|
|
112
|
+
raise e
|
|
113
|
+
# The returned content did not contain any EWS exceptions. Give up and re-raise the original exception.
|
|
114
|
+
raise enf
|
|
115
|
+
finally:
|
|
116
|
+
self.stop_streaming()
|
|
117
|
+
self.streaming = False
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from ..properties import DelegateUser, DLMailbox, UserId # The service expects a Mailbox element in the MNS namespace
|
|
2
|
+
from ..util import MNS, create_element, set_xml_value
|
|
3
|
+
from ..version import EXCHANGE_2007_SP1
|
|
4
|
+
from .common import EWSAccountService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GetDelegate(EWSAccountService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getdelegate-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "GetDelegate"
|
|
11
|
+
ERRORS_TO_CATCH_IN_RESPONSE = ()
|
|
12
|
+
supported_from = EXCHANGE_2007_SP1
|
|
13
|
+
|
|
14
|
+
def call(self, user_ids, include_permissions):
|
|
15
|
+
return self._elems_to_objs(
|
|
16
|
+
self._chunked_get_elements(
|
|
17
|
+
self.get_payload,
|
|
18
|
+
items=user_ids or [None],
|
|
19
|
+
mailbox=DLMailbox(email_address=self.account.primary_smtp_address),
|
|
20
|
+
include_permissions=include_permissions,
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def _elem_to_obj(self, elem):
|
|
25
|
+
return DelegateUser.from_xml(elem=elem, account=self.account)
|
|
26
|
+
|
|
27
|
+
def get_payload(self, user_ids, mailbox, include_permissions):
|
|
28
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=dict(IncludePermissions=include_permissions))
|
|
29
|
+
set_xml_value(payload, mailbox, version=self.protocol.version)
|
|
30
|
+
if user_ids != [None]:
|
|
31
|
+
user_ids_elem = create_element("m:UserIds")
|
|
32
|
+
for user_id in user_ids:
|
|
33
|
+
if isinstance(user_id, str):
|
|
34
|
+
user_id = UserId(primary_smtp_address=user_id)
|
|
35
|
+
set_xml_value(user_ids_elem, user_id, version=self.protocol.version)
|
|
36
|
+
set_xml_value(payload, user_ids_elem, version=self.protocol.version)
|
|
37
|
+
return payload
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def _get_elements_in_container(cls, container):
|
|
41
|
+
return container.findall(DelegateUser.response_tag())
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def _response_message_tag(cls):
|
|
45
|
+
return f"{{{MNS}}}DelegateUserResponseMessageType"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from ..properties import Notification
|
|
4
|
+
from ..util import create_element
|
|
5
|
+
from .common import EWSAccountService, add_xml_child
|
|
6
|
+
|
|
7
|
+
log = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GetEvents(EWSAccountService):
|
|
11
|
+
"""MSDN:
|
|
12
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getevents-operation
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
SERVICE_NAME = "GetEvents"
|
|
16
|
+
prefer_affinity = True
|
|
17
|
+
|
|
18
|
+
def call(self, subscription_id, watermark):
|
|
19
|
+
return self._elems_to_objs(
|
|
20
|
+
self._get_elements(
|
|
21
|
+
payload=self.get_payload(
|
|
22
|
+
subscription_id=subscription_id,
|
|
23
|
+
watermark=watermark,
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def _elem_to_obj(self, elem):
|
|
29
|
+
return Notification.from_xml(elem=elem, account=None)
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def _get_elements_in_container(cls, container):
|
|
33
|
+
return container.findall(Notification.response_tag())
|
|
34
|
+
|
|
35
|
+
def get_payload(self, subscription_id, watermark):
|
|
36
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
37
|
+
add_xml_child(payload, "m:SubscriptionId", subscription_id)
|
|
38
|
+
add_xml_child(payload, "m:Watermark", watermark)
|
|
39
|
+
return payload
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from ..errors import (
|
|
2
|
+
ErrorAccessDenied,
|
|
3
|
+
ErrorFolderNotFound,
|
|
4
|
+
ErrorInvalidOperation,
|
|
5
|
+
ErrorItemNotFound,
|
|
6
|
+
ErrorNoPublicFolderReplicaAvailable,
|
|
7
|
+
)
|
|
8
|
+
from ..util import MNS, create_element
|
|
9
|
+
from .common import EWSAccountService, folder_ids_element, parse_folder_elem, shape_element
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GetFolder(EWSAccountService):
|
|
13
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getfolder-operation"""
|
|
14
|
+
|
|
15
|
+
SERVICE_NAME = "GetFolder"
|
|
16
|
+
element_container_name = f"{{{MNS}}}Folders"
|
|
17
|
+
ERRORS_TO_CATCH_IN_RESPONSE = EWSAccountService.ERRORS_TO_CATCH_IN_RESPONSE + (
|
|
18
|
+
ErrorAccessDenied,
|
|
19
|
+
ErrorFolderNotFound,
|
|
20
|
+
ErrorNoPublicFolderReplicaAvailable,
|
|
21
|
+
ErrorInvalidOperation,
|
|
22
|
+
ErrorItemNotFound,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args, **kwargs):
|
|
26
|
+
super().__init__(*args, **kwargs)
|
|
27
|
+
self.folders = [] # A hack to communicate parsing args to _elems_to_objs()
|
|
28
|
+
|
|
29
|
+
def call(self, folders, additional_fields, shape):
|
|
30
|
+
"""Take a folder ID and returns the full information for that folder.
|
|
31
|
+
|
|
32
|
+
:param folders: a list of Folder objects
|
|
33
|
+
:param additional_fields: the extra fields that should be returned with the folder, as FieldPath objects
|
|
34
|
+
:param shape: The set of attributes to return
|
|
35
|
+
|
|
36
|
+
:return: XML elements for the folders, in stable order
|
|
37
|
+
"""
|
|
38
|
+
# We can't easily find the correct folder class from the returned XML. Instead, return objects with the same
|
|
39
|
+
# class as the folder instance it was requested with.
|
|
40
|
+
self.folders = list(folders) # Convert to a list, in case 'folders' is a generator. We're iterating twice.
|
|
41
|
+
return self._elems_to_objs(
|
|
42
|
+
self._chunked_get_elements(
|
|
43
|
+
self.get_payload,
|
|
44
|
+
items=self.folders,
|
|
45
|
+
additional_fields=additional_fields,
|
|
46
|
+
shape=shape,
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def _elems_to_objs(self, elems):
|
|
51
|
+
for folder, elem in zip(self.folders, elems):
|
|
52
|
+
if isinstance(elem, Exception):
|
|
53
|
+
yield elem
|
|
54
|
+
continue
|
|
55
|
+
yield parse_folder_elem(elem=elem, folder=folder)
|
|
56
|
+
|
|
57
|
+
def get_payload(self, folders, additional_fields, shape):
|
|
58
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
59
|
+
payload.append(
|
|
60
|
+
shape_element(
|
|
61
|
+
tag="m:FolderShape", shape=shape, additional_fields=additional_fields, version=self.account.version
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
payload.append(folder_ids_element(folders=folders, version=self.account.version))
|
|
65
|
+
return payload
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from ..folders.base import BaseFolder
|
|
2
|
+
from ..util import MNS, create_element
|
|
3
|
+
from .common import EWSAccountService, item_ids_element, shape_element
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetItem(EWSAccountService):
|
|
7
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getitem-operation"""
|
|
8
|
+
|
|
9
|
+
SERVICE_NAME = "GetItem"
|
|
10
|
+
element_container_name = f"{{{MNS}}}Items"
|
|
11
|
+
|
|
12
|
+
def call(self, items, additional_fields, shape):
|
|
13
|
+
"""Return all items in an account that correspond to a list of ID's, in stable order.
|
|
14
|
+
|
|
15
|
+
:param items: a list of (id, changekey) tuples or Item objects
|
|
16
|
+
:param additional_fields: the extra fields that should be returned with the item, as FieldPath objects
|
|
17
|
+
:param shape: The shape of returned objects
|
|
18
|
+
|
|
19
|
+
:return: XML elements for the items, in stable order
|
|
20
|
+
"""
|
|
21
|
+
return self._elems_to_objs(
|
|
22
|
+
self._chunked_get_elements(
|
|
23
|
+
self.get_payload,
|
|
24
|
+
items=items,
|
|
25
|
+
additional_fields=additional_fields,
|
|
26
|
+
shape=shape,
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def _elem_to_obj(self, elem):
|
|
31
|
+
return BaseFolder.item_model_from_tag(elem.tag).from_xml(elem=elem, account=self.account)
|
|
32
|
+
|
|
33
|
+
def get_payload(self, items, additional_fields, shape):
|
|
34
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
35
|
+
payload.append(
|
|
36
|
+
shape_element(
|
|
37
|
+
tag="m:ItemShape", shape=shape, additional_fields=additional_fields, version=self.account.version
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
payload.append(item_ids_element(items=items, version=self.account.version))
|
|
41
|
+
return payload
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from ..properties import MailTips
|
|
2
|
+
from ..util import MNS, create_element, set_xml_value
|
|
3
|
+
from .common import EWSService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetMailTips(EWSService):
|
|
7
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getmailtips-operation"""
|
|
8
|
+
|
|
9
|
+
SERVICE_NAME = "GetMailTips"
|
|
10
|
+
|
|
11
|
+
def call(self, sending_as, recipients, mail_tips_requested):
|
|
12
|
+
return self._elems_to_objs(
|
|
13
|
+
self._chunked_get_elements(
|
|
14
|
+
self.get_payload,
|
|
15
|
+
items=recipients,
|
|
16
|
+
sending_as=sending_as,
|
|
17
|
+
mail_tips_requested=mail_tips_requested,
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def _elem_to_obj(self, elem):
|
|
22
|
+
return MailTips.from_xml(elem=elem, account=None)
|
|
23
|
+
|
|
24
|
+
def get_payload(self, recipients, sending_as, mail_tips_requested):
|
|
25
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
26
|
+
set_xml_value(payload, sending_as, version=self.protocol.version)
|
|
27
|
+
|
|
28
|
+
recipients_elem = create_element("m:Recipients")
|
|
29
|
+
for recipient in recipients:
|
|
30
|
+
set_xml_value(recipients_elem, recipient, version=self.protocol.version)
|
|
31
|
+
payload.append(recipients_elem)
|
|
32
|
+
|
|
33
|
+
if mail_tips_requested:
|
|
34
|
+
set_xml_value(payload, mail_tips_requested, version=self.protocol.version)
|
|
35
|
+
return payload
|
|
36
|
+
|
|
37
|
+
def _get_elements_in_response(self, response):
|
|
38
|
+
for msg in response:
|
|
39
|
+
yield self._get_element_container(message=msg, name=MailTips.response_tag())
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def _response_message_tag(cls):
|
|
43
|
+
return f"{{{MNS}}}MailTipsResponseMessageType"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from ..items import Persona
|
|
2
|
+
from ..properties import PersonaId
|
|
3
|
+
from ..util import MNS, create_element, set_xml_value
|
|
4
|
+
from .common import EWSAccountService, to_item_id
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GetPersona(EWSAccountService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getpersona-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "GetPersona"
|
|
11
|
+
|
|
12
|
+
def call(self, personas):
|
|
13
|
+
# GetPersona only accepts one persona ID per request. Crazy.
|
|
14
|
+
for persona in personas:
|
|
15
|
+
yield from self._elems_to_objs(self._get_elements(payload=self.get_payload(persona=persona)))
|
|
16
|
+
|
|
17
|
+
def _elem_to_obj(self, elem):
|
|
18
|
+
return Persona.from_xml(elem=elem, account=None)
|
|
19
|
+
|
|
20
|
+
def get_payload(self, persona):
|
|
21
|
+
return set_xml_value(
|
|
22
|
+
create_element(f"m:{self.SERVICE_NAME}"), to_item_id(persona, PersonaId), version=self.protocol.version
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def _get_elements_in_container(cls, container):
|
|
27
|
+
return container.findall(f"{{{MNS}}}{Persona.ELEMENT_NAME}")
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def _response_tag(cls):
|
|
31
|
+
return f"{{{MNS}}}{cls.SERVICE_NAME}ResponseMessage"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from ..properties import RoomList
|
|
2
|
+
from ..util import MNS, create_element
|
|
3
|
+
from ..version import EXCHANGE_2010
|
|
4
|
+
from .common import EWSService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GetRoomLists(EWSService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getroomlists-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "GetRoomLists"
|
|
11
|
+
element_container_name = f"{{{MNS}}}RoomLists"
|
|
12
|
+
supported_from = EXCHANGE_2010
|
|
13
|
+
|
|
14
|
+
def call(self):
|
|
15
|
+
return self._elems_to_objs(self._get_elements(payload=self.get_payload()))
|
|
16
|
+
|
|
17
|
+
def _elem_to_obj(self, elem):
|
|
18
|
+
return RoomList.from_xml(elem=elem, account=None)
|
|
19
|
+
|
|
20
|
+
def get_payload(self):
|
|
21
|
+
return create_element(f"m:{self.SERVICE_NAME}")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from ..properties import Room
|
|
2
|
+
from ..util import MNS, create_element, set_xml_value
|
|
3
|
+
from ..version import EXCHANGE_2010
|
|
4
|
+
from .common import EWSService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GetRooms(EWSService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getrooms-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "GetRooms"
|
|
11
|
+
element_container_name = f"{{{MNS}}}Rooms"
|
|
12
|
+
supported_from = EXCHANGE_2010
|
|
13
|
+
|
|
14
|
+
def call(self, room_list):
|
|
15
|
+
return self._elems_to_objs(self._get_elements(payload=self.get_payload(room_list=room_list)))
|
|
16
|
+
|
|
17
|
+
def _elem_to_obj(self, elem):
|
|
18
|
+
return Room.from_xml(elem=elem, account=None)
|
|
19
|
+
|
|
20
|
+
def get_payload(self, room_list):
|
|
21
|
+
return set_xml_value(create_element(f"m:{self.SERVICE_NAME}"), room_list, version=self.protocol.version)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from ..errors import MalformedResponseError
|
|
2
|
+
from ..properties import FailedMailbox, SearchableMailbox
|
|
3
|
+
from ..util import MNS, add_xml_child, create_element
|
|
4
|
+
from ..version import EXCHANGE_2013
|
|
5
|
+
from .common import EWSService
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GetSearchableMailboxes(EWSService):
|
|
9
|
+
"""MSDN:
|
|
10
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getsearchablemailboxes-operation
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
SERVICE_NAME = "GetSearchableMailboxes"
|
|
14
|
+
element_container_name = f"{{{MNS}}}SearchableMailboxes"
|
|
15
|
+
failed_mailboxes_container_name = f"{{{MNS}}}FailedMailboxes"
|
|
16
|
+
supported_from = EXCHANGE_2013
|
|
17
|
+
cls_map = {cls.response_tag(): cls for cls in (SearchableMailbox, FailedMailbox)}
|
|
18
|
+
|
|
19
|
+
def call(self, search_filter, expand_group_membership):
|
|
20
|
+
return self._elems_to_objs(
|
|
21
|
+
self._get_elements(
|
|
22
|
+
payload=self.get_payload(
|
|
23
|
+
search_filter=search_filter,
|
|
24
|
+
expand_group_membership=expand_group_membership,
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def _elem_to_obj(self, elem):
|
|
30
|
+
return self.cls_map[elem.tag].from_xml(elem=elem, account=None)
|
|
31
|
+
|
|
32
|
+
def get_payload(self, search_filter, expand_group_membership):
|
|
33
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
34
|
+
if search_filter:
|
|
35
|
+
add_xml_child(payload, "m:SearchFilter", search_filter)
|
|
36
|
+
if expand_group_membership is not None:
|
|
37
|
+
add_xml_child(payload, "m:ExpandGroupMembership", "true" if expand_group_membership else "false")
|
|
38
|
+
return payload
|
|
39
|
+
|
|
40
|
+
def _get_elements_in_response(self, response):
|
|
41
|
+
for msg in response:
|
|
42
|
+
for container_name in (self.element_container_name, self.failed_mailboxes_container_name):
|
|
43
|
+
try:
|
|
44
|
+
container = self._get_element_container(message=msg, name=container_name)
|
|
45
|
+
except MalformedResponseError:
|
|
46
|
+
# Responses may contain no mailboxes of either kind. _get_element_container() does not accept this.
|
|
47
|
+
continue
|
|
48
|
+
yield from self._get_elements_in_container(container=container)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from ..properties import TimeZoneDefinition
|
|
2
|
+
from ..util import MNS, create_element, peek, set_xml_value
|
|
3
|
+
from ..version import EXCHANGE_2010
|
|
4
|
+
from .common import EWSService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GetServerTimeZones(EWSService):
|
|
8
|
+
"""MSDN:
|
|
9
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getservertimezones-operation
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
SERVICE_NAME = "GetServerTimeZones"
|
|
13
|
+
element_container_name = f"{{{MNS}}}TimeZoneDefinitions"
|
|
14
|
+
supported_from = EXCHANGE_2010
|
|
15
|
+
|
|
16
|
+
def call(self, timezones=None, return_full_timezone_data=False):
|
|
17
|
+
return self._elems_to_objs(
|
|
18
|
+
self._get_elements(
|
|
19
|
+
payload=self.get_payload(timezones=timezones, return_full_timezone_data=return_full_timezone_data)
|
|
20
|
+
)
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
def get_payload(self, timezones, return_full_timezone_data):
|
|
24
|
+
payload = create_element(
|
|
25
|
+
f"m:{self.SERVICE_NAME}",
|
|
26
|
+
attrs=dict(ReturnFullTimeZoneData=return_full_timezone_data),
|
|
27
|
+
)
|
|
28
|
+
if timezones is not None:
|
|
29
|
+
is_empty, timezones = peek(timezones)
|
|
30
|
+
if not is_empty:
|
|
31
|
+
tz_ids = create_element("m:Ids")
|
|
32
|
+
for timezone in timezones:
|
|
33
|
+
tz_id = set_xml_value(create_element("t:Id"), timezone.ms_id)
|
|
34
|
+
tz_ids.append(tz_id)
|
|
35
|
+
payload.append(tz_ids)
|
|
36
|
+
return payload
|
|
37
|
+
|
|
38
|
+
def _elem_to_obj(self, elem):
|
|
39
|
+
return TimeZoneDefinition.from_xml(elem=elem, account=None)
|