@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,45 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue, InvalidTypeError
|
|
2
|
+
from ..properties import ID_FORMATS, AlternateId, AlternatePublicFolderId, AlternatePublicFolderItemId
|
|
3
|
+
from ..util import create_element, set_xml_value
|
|
4
|
+
from .common import EWSService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ConvertId(EWSService):
|
|
8
|
+
"""Take a list of IDs to convert. Returns a list of converted IDs or exception instances, in the same order as the
|
|
9
|
+
input list.
|
|
10
|
+
|
|
11
|
+
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/convertid-operation
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
SERVICE_NAME = "ConvertId"
|
|
15
|
+
cls_map = {cls.response_tag(): cls for cls in (AlternateId, AlternatePublicFolderId, AlternatePublicFolderItemId)}
|
|
16
|
+
|
|
17
|
+
def call(self, items, destination_format):
|
|
18
|
+
if destination_format not in ID_FORMATS:
|
|
19
|
+
raise InvalidEnumValue("destination_format", destination_format, ID_FORMATS)
|
|
20
|
+
return self._elems_to_objs(
|
|
21
|
+
self._chunked_get_elements(self.get_payload, items=items, destination_format=destination_format)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def _elem_to_obj(self, elem):
|
|
25
|
+
return self.cls_map[elem.tag].from_xml(elem, account=None)
|
|
26
|
+
|
|
27
|
+
def get_payload(self, items, destination_format):
|
|
28
|
+
supported_item_classes = AlternateId, AlternatePublicFolderId, AlternatePublicFolderItemId
|
|
29
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=dict(DestinationFormat=destination_format))
|
|
30
|
+
item_ids = create_element("m:SourceIds")
|
|
31
|
+
for item in items:
|
|
32
|
+
if not isinstance(item, supported_item_classes):
|
|
33
|
+
raise InvalidTypeError("item", item, supported_item_classes)
|
|
34
|
+
set_xml_value(item_ids, item, version=None)
|
|
35
|
+
payload.append(item_ids)
|
|
36
|
+
return payload
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def _get_elements_in_container(cls, container):
|
|
40
|
+
# We may have other elements in here, e.g. 'ResponseCode'. Filter away those.
|
|
41
|
+
return (
|
|
42
|
+
container.findall(AlternateId.response_tag())
|
|
43
|
+
+ container.findall(AlternatePublicFolderId.response_tag())
|
|
44
|
+
+ container.findall(AlternatePublicFolderItemId.response_tag())
|
|
45
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from ..attachments import FileAttachment, ItemAttachment
|
|
2
|
+
from ..items import BaseItem
|
|
3
|
+
from ..properties import ParentItemId
|
|
4
|
+
from ..util import MNS, create_element, set_xml_value
|
|
5
|
+
from .common import EWSAccountService, to_item_id
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CreateAttachment(EWSAccountService):
|
|
9
|
+
"""MSDN:
|
|
10
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/createattachment-operation
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
SERVICE_NAME = "CreateAttachment"
|
|
14
|
+
element_container_name = f"{{{MNS}}}Attachments"
|
|
15
|
+
cls_map = {cls.response_tag(): cls for cls in (FileAttachment, ItemAttachment)}
|
|
16
|
+
|
|
17
|
+
def call(self, parent_item, items):
|
|
18
|
+
return self._elems_to_objs(self._chunked_get_elements(self.get_payload, items=items, parent_item=parent_item))
|
|
19
|
+
|
|
20
|
+
def _elem_to_obj(self, elem):
|
|
21
|
+
return self.cls_map[elem.tag].from_xml(elem=elem, account=self.account)
|
|
22
|
+
|
|
23
|
+
def get_payload(self, items, parent_item):
|
|
24
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
25
|
+
version = self.account.version
|
|
26
|
+
if isinstance(parent_item, BaseItem):
|
|
27
|
+
# to_item_id() would convert this to a normal ItemId, but the service wants a ParentItemId
|
|
28
|
+
parent_item = ParentItemId(parent_item.id, parent_item.changekey)
|
|
29
|
+
set_xml_value(payload, to_item_id(parent_item, ParentItemId), version=self.account.version)
|
|
30
|
+
attachments = create_element("m:Attachments")
|
|
31
|
+
for item in items:
|
|
32
|
+
set_xml_value(attachments, item, version=version)
|
|
33
|
+
payload.append(attachments)
|
|
34
|
+
return payload
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from ..errors import ErrorFolderExists
|
|
2
|
+
from ..util import MNS, create_element
|
|
3
|
+
from .common import EWSAccountService, folder_ids_element, parse_folder_elem, set_xml_value
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CreateFolder(EWSAccountService):
|
|
7
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/createfolder-operation"""
|
|
8
|
+
|
|
9
|
+
SERVICE_NAME = "CreateFolder"
|
|
10
|
+
element_container_name = f"{{{MNS}}}Folders"
|
|
11
|
+
ERRORS_TO_CATCH_IN_RESPONSE = EWSAccountService.ERRORS_TO_CATCH_IN_RESPONSE + (ErrorFolderExists,)
|
|
12
|
+
|
|
13
|
+
def __init__(self, *args, **kwargs):
|
|
14
|
+
super().__init__(*args, **kwargs)
|
|
15
|
+
self.folders = [] # A hack to communicate parsing args to _elems_to_objs()
|
|
16
|
+
|
|
17
|
+
def call(self, parent_folder, folders):
|
|
18
|
+
# We can't easily find the correct folder class from the returned XML. Instead, return objects with the same
|
|
19
|
+
# class as the folder instance it was requested with.
|
|
20
|
+
self.folders = list(folders) # Convert to a list, in case 'folders' is a generator. We're iterating twice.
|
|
21
|
+
return self._elems_to_objs(
|
|
22
|
+
self._chunked_get_elements(
|
|
23
|
+
self.get_payload,
|
|
24
|
+
items=self.folders,
|
|
25
|
+
parent_folder=parent_folder,
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def _elems_to_objs(self, elems):
|
|
30
|
+
for folder, elem in zip(self.folders, elems):
|
|
31
|
+
if isinstance(elem, Exception):
|
|
32
|
+
yield elem
|
|
33
|
+
continue
|
|
34
|
+
yield parse_folder_elem(elem=elem, folder=folder)
|
|
35
|
+
|
|
36
|
+
def get_payload(self, folders, parent_folder):
|
|
37
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
38
|
+
payload.append(
|
|
39
|
+
folder_ids_element(folders=[parent_folder], version=self.account.version, tag="m:ParentFolderId")
|
|
40
|
+
)
|
|
41
|
+
folder_elems = create_element("m:Folders")
|
|
42
|
+
for folder in folders:
|
|
43
|
+
set_xml_value(folder_elems, folder, version=self.account.version)
|
|
44
|
+
payload.append(folder_elems)
|
|
45
|
+
return payload
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue, InvalidTypeError
|
|
2
|
+
from ..folders import BaseFolder
|
|
3
|
+
from ..items import (
|
|
4
|
+
MESSAGE_DISPOSITION_CHOICES,
|
|
5
|
+
SAVE_ONLY,
|
|
6
|
+
SEND_AND_SAVE_COPY,
|
|
7
|
+
SEND_MEETING_INVITATIONS_CHOICES,
|
|
8
|
+
SEND_ONLY,
|
|
9
|
+
BulkCreateResult,
|
|
10
|
+
)
|
|
11
|
+
from ..properties import FolderId
|
|
12
|
+
from ..util import MNS, create_element, set_xml_value
|
|
13
|
+
from .common import EWSAccountService, folder_ids_element
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CreateItem(EWSAccountService):
|
|
17
|
+
"""Take a folder and a list of items. Return the result of creation as a list of tuples (success[True|False],
|
|
18
|
+
errormessage), in the same order as the input list.
|
|
19
|
+
|
|
20
|
+
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/createitem-operation
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
SERVICE_NAME = "CreateItem"
|
|
24
|
+
element_container_name = f"{{{MNS}}}Items"
|
|
25
|
+
|
|
26
|
+
def call(self, items, folder, message_disposition, send_meeting_invitations):
|
|
27
|
+
if message_disposition not in MESSAGE_DISPOSITION_CHOICES:
|
|
28
|
+
raise InvalidEnumValue("message_disposition", message_disposition, MESSAGE_DISPOSITION_CHOICES)
|
|
29
|
+
if send_meeting_invitations not in SEND_MEETING_INVITATIONS_CHOICES:
|
|
30
|
+
raise InvalidEnumValue(
|
|
31
|
+
"send_meeting_invitations", send_meeting_invitations, SEND_MEETING_INVITATIONS_CHOICES
|
|
32
|
+
)
|
|
33
|
+
if folder is not None:
|
|
34
|
+
if not isinstance(folder, (BaseFolder, FolderId)):
|
|
35
|
+
raise InvalidTypeError("folder", folder, (BaseFolder, FolderId))
|
|
36
|
+
if folder.account != self.account:
|
|
37
|
+
raise ValueError("Folder must belong to account")
|
|
38
|
+
if message_disposition == SAVE_ONLY and folder is None:
|
|
39
|
+
raise AttributeError("Folder must be supplied when in save-only mode")
|
|
40
|
+
if message_disposition == SEND_AND_SAVE_COPY and folder is None:
|
|
41
|
+
folder = self.account.sent # 'Sent' is default EWS behaviour
|
|
42
|
+
if message_disposition == SEND_ONLY and folder is not None:
|
|
43
|
+
raise AttributeError("Folder must be None in send-ony mode")
|
|
44
|
+
return self._elems_to_objs(
|
|
45
|
+
self._chunked_get_elements(
|
|
46
|
+
self.get_payload,
|
|
47
|
+
items=items,
|
|
48
|
+
folder=folder,
|
|
49
|
+
message_disposition=message_disposition,
|
|
50
|
+
send_meeting_invitations=send_meeting_invitations,
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def _elem_to_obj(self, elem):
|
|
55
|
+
if isinstance(elem, bool):
|
|
56
|
+
return elem
|
|
57
|
+
return BulkCreateResult.from_xml(elem=elem, account=self.account)
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def _get_elements_in_container(cls, container):
|
|
61
|
+
res = super()._get_elements_in_container(container)
|
|
62
|
+
return res or [True]
|
|
63
|
+
|
|
64
|
+
def get_payload(self, items, folder, message_disposition, send_meeting_invitations):
|
|
65
|
+
"""Take a list of Item objects (CalendarItem, Message etc.) and return the XML for a CreateItem request.
|
|
66
|
+
convert items to XML Elements.
|
|
67
|
+
|
|
68
|
+
MessageDisposition is only applicable to email messages, where it is required.
|
|
69
|
+
|
|
70
|
+
SendMeetingInvitations is required for calendar items. It is also applicable to tasks, meeting request
|
|
71
|
+
responses (see
|
|
72
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/createitem-operation-meeting-request
|
|
73
|
+
) and sharing
|
|
74
|
+
invitation accepts (see
|
|
75
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/createitem-acceptsharinginvitation
|
|
76
|
+
). The last two are not supported yet.
|
|
77
|
+
|
|
78
|
+
:param items:
|
|
79
|
+
:param folder:
|
|
80
|
+
:param message_disposition:
|
|
81
|
+
:param send_meeting_invitations:
|
|
82
|
+
"""
|
|
83
|
+
payload = create_element(
|
|
84
|
+
f"m:{self.SERVICE_NAME}",
|
|
85
|
+
attrs=dict(MessageDisposition=message_disposition, SendMeetingInvitations=send_meeting_invitations),
|
|
86
|
+
)
|
|
87
|
+
if folder:
|
|
88
|
+
payload.append(
|
|
89
|
+
folder_ids_element(folders=[folder], version=self.account.version, tag="m:SavedItemFolderId")
|
|
90
|
+
)
|
|
91
|
+
item_elems = create_element("m:Items")
|
|
92
|
+
for item in items:
|
|
93
|
+
if not item.account:
|
|
94
|
+
item.account = self.account
|
|
95
|
+
set_xml_value(item_elems, item, version=self.account.version)
|
|
96
|
+
payload.append(item_elems)
|
|
97
|
+
return payload
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from ..util import create_element, set_xml_value
|
|
2
|
+
from .common import EWSAccountService
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CreateUserConfiguration(EWSAccountService):
|
|
6
|
+
"""MSDN:
|
|
7
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/createuserconfiguration-operation
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "CreateUserConfiguration"
|
|
11
|
+
returns_elements = False
|
|
12
|
+
|
|
13
|
+
def call(self, user_configuration):
|
|
14
|
+
return self._get_elements(payload=self.get_payload(user_configuration=user_configuration))
|
|
15
|
+
|
|
16
|
+
def get_payload(self, user_configuration):
|
|
17
|
+
return set_xml_value(
|
|
18
|
+
create_element(f"m:{self.SERVICE_NAME}"), user_configuration, version=self.protocol.version
|
|
19
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from ..properties import RootItemId
|
|
2
|
+
from ..util import create_element, set_xml_value
|
|
3
|
+
from .common import EWSAccountService, attachment_ids_element
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DeleteAttachment(EWSAccountService):
|
|
7
|
+
"""MSDN:
|
|
8
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/deleteattachment-operation
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
SERVICE_NAME = "DeleteAttachment"
|
|
12
|
+
|
|
13
|
+
def call(self, items):
|
|
14
|
+
return self._elems_to_objs(self._chunked_get_elements(self.get_payload, items=items))
|
|
15
|
+
|
|
16
|
+
def _elem_to_obj(self, elem):
|
|
17
|
+
return RootItemId.from_xml(elem=elem, account=self.account)
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def _get_elements_in_container(cls, container):
|
|
21
|
+
return container.findall(RootItemId.response_tag())
|
|
22
|
+
|
|
23
|
+
def get_payload(self, items):
|
|
24
|
+
return set_xml_value(
|
|
25
|
+
create_element(f"m:{self.SERVICE_NAME}"),
|
|
26
|
+
attachment_ids_element(items=items, version=self.account.version),
|
|
27
|
+
version=self.account.version,
|
|
28
|
+
)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue
|
|
2
|
+
from ..items import DELETE_TYPE_CHOICES
|
|
3
|
+
from ..util import create_element
|
|
4
|
+
from .common import EWSAccountService, folder_ids_element
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DeleteFolder(EWSAccountService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/deletefolder-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "DeleteFolder"
|
|
11
|
+
returns_elements = False
|
|
12
|
+
|
|
13
|
+
def call(self, folders, delete_type):
|
|
14
|
+
if delete_type not in DELETE_TYPE_CHOICES:
|
|
15
|
+
raise InvalidEnumValue("delete_type", delete_type, DELETE_TYPE_CHOICES)
|
|
16
|
+
return self._chunked_get_elements(self.get_payload, items=folders, delete_type=delete_type)
|
|
17
|
+
|
|
18
|
+
def get_payload(self, folders, delete_type):
|
|
19
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=dict(DeleteType=delete_type))
|
|
20
|
+
payload.append(folder_ids_element(folders=folders, version=self.account.version))
|
|
21
|
+
return payload
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue
|
|
2
|
+
from ..items import AFFECTED_TASK_OCCURRENCES_CHOICES, DELETE_TYPE_CHOICES, SEND_MEETING_CANCELLATIONS_CHOICES
|
|
3
|
+
from ..util import create_element
|
|
4
|
+
from ..version import EXCHANGE_2013_SP1
|
|
5
|
+
from .common import EWSAccountService, item_ids_element
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DeleteItem(EWSAccountService):
|
|
9
|
+
"""Take a folder and a list of (id, changekey) tuples. Return result of deletion as a list of tuples
|
|
10
|
+
(success[True|False], errormessage), in the same order as the input list.
|
|
11
|
+
|
|
12
|
+
MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/deleteitem-operation
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
SERVICE_NAME = "DeleteItem"
|
|
16
|
+
returns_elements = False
|
|
17
|
+
|
|
18
|
+
def call(self, items, delete_type, send_meeting_cancellations, affected_task_occurrences, suppress_read_receipts):
|
|
19
|
+
if delete_type not in DELETE_TYPE_CHOICES:
|
|
20
|
+
raise InvalidEnumValue("delete_type", delete_type, DELETE_TYPE_CHOICES)
|
|
21
|
+
if send_meeting_cancellations not in SEND_MEETING_CANCELLATIONS_CHOICES:
|
|
22
|
+
raise InvalidEnumValue(
|
|
23
|
+
"send_meeting_cancellations", send_meeting_cancellations, SEND_MEETING_CANCELLATIONS_CHOICES
|
|
24
|
+
)
|
|
25
|
+
if affected_task_occurrences not in AFFECTED_TASK_OCCURRENCES_CHOICES:
|
|
26
|
+
raise InvalidEnumValue(
|
|
27
|
+
"affected_task_occurrences", affected_task_occurrences, AFFECTED_TASK_OCCURRENCES_CHOICES
|
|
28
|
+
)
|
|
29
|
+
return self._chunked_get_elements(
|
|
30
|
+
self.get_payload,
|
|
31
|
+
items=items,
|
|
32
|
+
delete_type=delete_type,
|
|
33
|
+
send_meeting_cancellations=send_meeting_cancellations,
|
|
34
|
+
affected_task_occurrences=affected_task_occurrences,
|
|
35
|
+
suppress_read_receipts=suppress_read_receipts,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def get_payload(
|
|
39
|
+
self, items, delete_type, send_meeting_cancellations, affected_task_occurrences, suppress_read_receipts
|
|
40
|
+
):
|
|
41
|
+
# Takes a list of (id, changekey) tuples or Item objects and returns the XML for a DeleteItem request.
|
|
42
|
+
attrs = dict(
|
|
43
|
+
DeleteType=delete_type,
|
|
44
|
+
SendMeetingCancellations=send_meeting_cancellations,
|
|
45
|
+
AffectedTaskOccurrences=affected_task_occurrences,
|
|
46
|
+
)
|
|
47
|
+
if self.account.version.build >= EXCHANGE_2013_SP1:
|
|
48
|
+
attrs["SuppressReadReceipts"] = suppress_read_receipts
|
|
49
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=attrs)
|
|
50
|
+
payload.append(item_ids_element(items=items, version=self.account.version))
|
|
51
|
+
return payload
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from ..util import create_element, set_xml_value
|
|
2
|
+
from .common import EWSAccountService
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DeleteUserConfiguration(EWSAccountService):
|
|
6
|
+
"""MSDN:
|
|
7
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/deleteuserconfiguration-operation
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "DeleteUserConfiguration"
|
|
11
|
+
returns_elements = False
|
|
12
|
+
|
|
13
|
+
def call(self, user_configuration_name):
|
|
14
|
+
return self._get_elements(payload=self.get_payload(user_configuration_name=user_configuration_name))
|
|
15
|
+
|
|
16
|
+
def get_payload(self, user_configuration_name):
|
|
17
|
+
return set_xml_value(
|
|
18
|
+
create_element(f"m:{self.SERVICE_NAME}"), user_configuration_name, version=self.account.version
|
|
19
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue
|
|
2
|
+
from ..items import DELETE_TYPE_CHOICES
|
|
3
|
+
from ..util import create_element
|
|
4
|
+
from .common import EWSAccountService, folder_ids_element
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class EmptyFolder(EWSAccountService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/emptyfolder-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "EmptyFolder"
|
|
11
|
+
returns_elements = False
|
|
12
|
+
|
|
13
|
+
def call(self, folders, delete_type, delete_sub_folders):
|
|
14
|
+
if delete_type not in DELETE_TYPE_CHOICES:
|
|
15
|
+
raise InvalidEnumValue("delete_type", delete_type, DELETE_TYPE_CHOICES)
|
|
16
|
+
return self._chunked_get_elements(
|
|
17
|
+
self.get_payload, items=folders, delete_type=delete_type, delete_sub_folders=delete_sub_folders
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def get_payload(self, folders, delete_type, delete_sub_folders):
|
|
21
|
+
payload = create_element(
|
|
22
|
+
f"m:{self.SERVICE_NAME}", attrs=dict(DeleteType=delete_type, DeleteSubFolders=delete_sub_folders)
|
|
23
|
+
)
|
|
24
|
+
payload.append(folder_ids_element(folders=folders, version=self.account.version))
|
|
25
|
+
return payload
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from ..errors import ErrorNameResolutionMultipleResults
|
|
2
|
+
from ..properties import Mailbox
|
|
3
|
+
from ..util import MNS, create_element, set_xml_value
|
|
4
|
+
from .common import EWSService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ExpandDL(EWSService):
|
|
8
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/expanddl-operation"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "ExpandDL"
|
|
11
|
+
element_container_name = f"{{{MNS}}}DLExpansion"
|
|
12
|
+
WARNINGS_TO_IGNORE_IN_RESPONSE = ErrorNameResolutionMultipleResults
|
|
13
|
+
|
|
14
|
+
def call(self, distribution_list):
|
|
15
|
+
return self._elems_to_objs(self._get_elements(payload=self.get_payload(distribution_list=distribution_list)))
|
|
16
|
+
|
|
17
|
+
def _elem_to_obj(self, elem):
|
|
18
|
+
return Mailbox.from_xml(elem, account=None)
|
|
19
|
+
|
|
20
|
+
def get_payload(self, distribution_list):
|
|
21
|
+
return set_xml_value(create_element(f"m:{self.SERVICE_NAME}"), distribution_list, version=self.protocol.version)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from ..errors import ResponseMessageError
|
|
2
|
+
from ..util import MNS, create_element
|
|
3
|
+
from .common import EWSAccountService, item_ids_element
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExportItems(EWSAccountService):
|
|
7
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/exportitems-operation"""
|
|
8
|
+
|
|
9
|
+
ERRORS_TO_CATCH_IN_RESPONSE = ResponseMessageError
|
|
10
|
+
SERVICE_NAME = "ExportItems"
|
|
11
|
+
element_container_name = f"{{{MNS}}}Data"
|
|
12
|
+
|
|
13
|
+
def call(self, items):
|
|
14
|
+
return self._elems_to_objs(self._chunked_get_elements(self.get_payload, items=items))
|
|
15
|
+
|
|
16
|
+
def _elem_to_obj(self, elem):
|
|
17
|
+
return elem.text # All we want is the 64bit string in the 'Data' tag
|
|
18
|
+
|
|
19
|
+
def get_payload(self, items):
|
|
20
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
21
|
+
payload.append(item_ids_element(items=items, version=self.account.version))
|
|
22
|
+
return payload
|
|
23
|
+
|
|
24
|
+
# We need to override this since ExportItemsResponseMessage is formatted a bit differently.
|
|
25
|
+
@classmethod
|
|
26
|
+
def _get_elements_in_container(cls, container):
|
|
27
|
+
return [container]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue
|
|
2
|
+
from ..folders import Folder
|
|
3
|
+
from ..folders.queryset import FOLDER_TRAVERSAL_CHOICES
|
|
4
|
+
from ..items import SHAPE_CHOICES
|
|
5
|
+
from ..util import MNS, TNS, create_element
|
|
6
|
+
from ..version import EXCHANGE_2010
|
|
7
|
+
from .common import EWSPagingService, folder_ids_element, shape_element
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FindFolder(EWSPagingService):
|
|
11
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findfolder-operation"""
|
|
12
|
+
|
|
13
|
+
SERVICE_NAME = "FindFolder"
|
|
14
|
+
element_container_name = f"{{{TNS}}}Folders"
|
|
15
|
+
paging_container_name = f"{{{MNS}}}RootFolder"
|
|
16
|
+
|
|
17
|
+
def __init__(self, *args, **kwargs):
|
|
18
|
+
super().__init__(*args, **kwargs)
|
|
19
|
+
self.root = None # A hack to communicate parsing args to _elems_to_objs()
|
|
20
|
+
|
|
21
|
+
def call(self, folders, additional_fields, restriction, shape, depth, max_items, offset):
|
|
22
|
+
"""Find sub-folders of a folder.
|
|
23
|
+
|
|
24
|
+
:param folders: the folders to act on
|
|
25
|
+
:param additional_fields: the extra fields that should be returned with the folder, as FieldPath objects
|
|
26
|
+
:param restriction: Restriction object that defines the filters for the query
|
|
27
|
+
:param shape: The set of attributes to return
|
|
28
|
+
:param depth: How deep in the folder structure to search for folders
|
|
29
|
+
:param max_items: The maximum number of items to return
|
|
30
|
+
:param offset: the offset relative to the first item in the item collection. Usually 0.
|
|
31
|
+
|
|
32
|
+
:return: XML elements for the matching folders
|
|
33
|
+
"""
|
|
34
|
+
if shape not in SHAPE_CHOICES:
|
|
35
|
+
raise InvalidEnumValue("shape", shape, SHAPE_CHOICES)
|
|
36
|
+
if depth not in FOLDER_TRAVERSAL_CHOICES:
|
|
37
|
+
raise InvalidEnumValue("depth", depth, FOLDER_TRAVERSAL_CHOICES)
|
|
38
|
+
roots = {f.root for f in folders}
|
|
39
|
+
if len(roots) != 1:
|
|
40
|
+
raise ValueError(f"All folders must have the same root hierarchy ({roots})")
|
|
41
|
+
self.root = roots.pop()
|
|
42
|
+
return self._elems_to_objs(
|
|
43
|
+
self._paged_call(
|
|
44
|
+
payload_func=self.get_payload,
|
|
45
|
+
max_items=max_items,
|
|
46
|
+
folders=folders,
|
|
47
|
+
**dict(
|
|
48
|
+
additional_fields=additional_fields,
|
|
49
|
+
restriction=restriction,
|
|
50
|
+
shape=shape,
|
|
51
|
+
depth=depth,
|
|
52
|
+
page_size=self.page_size,
|
|
53
|
+
offset=offset,
|
|
54
|
+
),
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def _elem_to_obj(self, elem):
|
|
59
|
+
return Folder.from_xml_with_root(elem=elem, root=self.root)
|
|
60
|
+
|
|
61
|
+
def get_payload(self, folders, additional_fields, restriction, shape, depth, page_size, offset=0):
|
|
62
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=dict(Traversal=depth))
|
|
63
|
+
payload.append(
|
|
64
|
+
shape_element(
|
|
65
|
+
tag="m:FolderShape", shape=shape, additional_fields=additional_fields, version=self.account.version
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
if self.account.version.build >= EXCHANGE_2010:
|
|
69
|
+
indexed_page_folder_view = create_element(
|
|
70
|
+
"m:IndexedPageFolderView",
|
|
71
|
+
attrs=dict(MaxEntriesReturned=page_size, Offset=offset, BasePoint="Beginning"),
|
|
72
|
+
)
|
|
73
|
+
payload.append(indexed_page_folder_view)
|
|
74
|
+
else:
|
|
75
|
+
if offset != 0:
|
|
76
|
+
raise NotImplementedError("'offset' is only supported for Exchange 2010 servers and later")
|
|
77
|
+
if restriction:
|
|
78
|
+
payload.append(restriction.to_xml(version=self.account.version))
|
|
79
|
+
payload.append(folder_ids_element(folders=folders, version=self.protocol.version, tag="m:ParentFolderIds"))
|
|
80
|
+
return payload
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from ..errors import InvalidEnumValue
|
|
2
|
+
from ..folders.base import BaseFolder
|
|
3
|
+
from ..items import ID_ONLY, ITEM_TRAVERSAL_CHOICES, SHAPE_CHOICES, Item
|
|
4
|
+
from ..util import MNS, TNS, create_element, set_xml_value
|
|
5
|
+
from .common import EWSPagingService, folder_ids_element, shape_element
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FindItem(EWSPagingService):
|
|
9
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/finditem-operation"""
|
|
10
|
+
|
|
11
|
+
SERVICE_NAME = "FindItem"
|
|
12
|
+
element_container_name = f"{{{TNS}}}Items"
|
|
13
|
+
paging_container_name = f"{{{MNS}}}RootFolder"
|
|
14
|
+
|
|
15
|
+
def __init__(self, *args, **kwargs):
|
|
16
|
+
super().__init__(*args, **kwargs)
|
|
17
|
+
# A hack to communicate parsing args to _elems_to_objs()
|
|
18
|
+
self.additional_fields = None
|
|
19
|
+
self.shape = None
|
|
20
|
+
|
|
21
|
+
def call(
|
|
22
|
+
self,
|
|
23
|
+
folders,
|
|
24
|
+
additional_fields,
|
|
25
|
+
restriction,
|
|
26
|
+
order_fields,
|
|
27
|
+
shape,
|
|
28
|
+
query_string,
|
|
29
|
+
depth,
|
|
30
|
+
calendar_view,
|
|
31
|
+
max_items,
|
|
32
|
+
offset,
|
|
33
|
+
):
|
|
34
|
+
"""Find items in an account.
|
|
35
|
+
|
|
36
|
+
:param folders: the folders to act on
|
|
37
|
+
:param additional_fields: the extra fields that should be returned with the item, as FieldPath objects
|
|
38
|
+
:param restriction: a Restriction object for
|
|
39
|
+
:param order_fields: the fields to sort the results by
|
|
40
|
+
:param shape: The set of attributes to return
|
|
41
|
+
:param query_string: a QueryString object
|
|
42
|
+
:param depth: How deep in the folder structure to search for items
|
|
43
|
+
:param calendar_view: If set, returns recurring calendar items unfolded
|
|
44
|
+
:param max_items: the max number of items to return
|
|
45
|
+
:param offset: the offset relative to the first item in the item collection. Usually 0.
|
|
46
|
+
|
|
47
|
+
:return: XML elements for the matching items
|
|
48
|
+
"""
|
|
49
|
+
if shape not in SHAPE_CHOICES:
|
|
50
|
+
raise InvalidEnumValue("shape", shape, SHAPE_CHOICES)
|
|
51
|
+
if depth not in ITEM_TRAVERSAL_CHOICES:
|
|
52
|
+
raise InvalidEnumValue("depth", depth, ITEM_TRAVERSAL_CHOICES)
|
|
53
|
+
self.additional_fields = additional_fields
|
|
54
|
+
self.shape = shape
|
|
55
|
+
return self._elems_to_objs(
|
|
56
|
+
self._paged_call(
|
|
57
|
+
payload_func=self.get_payload,
|
|
58
|
+
max_items=max_items,
|
|
59
|
+
folders=folders,
|
|
60
|
+
**dict(
|
|
61
|
+
additional_fields=additional_fields,
|
|
62
|
+
restriction=restriction,
|
|
63
|
+
order_fields=order_fields,
|
|
64
|
+
query_string=query_string,
|
|
65
|
+
shape=shape,
|
|
66
|
+
depth=depth,
|
|
67
|
+
calendar_view=calendar_view,
|
|
68
|
+
page_size=self.page_size,
|
|
69
|
+
offset=offset,
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def _elem_to_obj(self, elem):
|
|
75
|
+
if self.shape == ID_ONLY and self.additional_fields is None:
|
|
76
|
+
return Item.id_from_xml(elem)
|
|
77
|
+
return BaseFolder.item_model_from_tag(elem.tag).from_xml(elem=elem, account=self.account)
|
|
78
|
+
|
|
79
|
+
def get_payload(
|
|
80
|
+
self,
|
|
81
|
+
folders,
|
|
82
|
+
additional_fields,
|
|
83
|
+
restriction,
|
|
84
|
+
order_fields,
|
|
85
|
+
query_string,
|
|
86
|
+
shape,
|
|
87
|
+
depth,
|
|
88
|
+
calendar_view,
|
|
89
|
+
page_size,
|
|
90
|
+
offset=0,
|
|
91
|
+
):
|
|
92
|
+
payload = create_element(f"m:{self.SERVICE_NAME}", attrs=dict(Traversal=depth))
|
|
93
|
+
payload.append(
|
|
94
|
+
shape_element(
|
|
95
|
+
tag="m:ItemShape", shape=shape, additional_fields=additional_fields, version=self.account.version
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
if calendar_view is None:
|
|
99
|
+
view_type = create_element(
|
|
100
|
+
"m:IndexedPageItemView", attrs=dict(MaxEntriesReturned=page_size, Offset=offset, BasePoint="Beginning")
|
|
101
|
+
)
|
|
102
|
+
else:
|
|
103
|
+
view_type = calendar_view.to_xml(version=self.account.version)
|
|
104
|
+
payload.append(view_type)
|
|
105
|
+
if restriction:
|
|
106
|
+
payload.append(restriction.to_xml(version=self.account.version))
|
|
107
|
+
if order_fields:
|
|
108
|
+
payload.append(set_xml_value(create_element("m:SortOrder"), order_fields, version=self.account.version))
|
|
109
|
+
payload.append(folder_ids_element(folders=folders, version=self.protocol.version, tag="m:ParentFolderIds"))
|
|
110
|
+
if query_string:
|
|
111
|
+
payload.append(query_string.to_xml(version=self.account.version))
|
|
112
|
+
return payload
|