@backtomyfuture/exchange-cli-win32-x64 0.1.10
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/VCRUNTIME140.dll +0 -0
- package/bin/_internal/VCRUNTIME140_1.dll +0 -0
- package/bin/_internal/_asyncio.pyd +0 -0
- package/bin/_internal/_bz2.pyd +0 -0
- package/bin/_internal/_cffi_backend.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/_ctypes.pyd +0 -0
- package/bin/_internal/_decimal.pyd +0 -0
- package/bin/_internal/_elementtree.pyd +0 -0
- package/bin/_internal/_hashlib.pyd +0 -0
- package/bin/_internal/_lzma.pyd +0 -0
- package/bin/_internal/_multiprocessing.pyd +0 -0
- package/bin/_internal/_overlapped.pyd +0 -0
- package/bin/_internal/_queue.pyd +0 -0
- package/bin/_internal/_socket.pyd +0 -0
- package/bin/_internal/_ssl.pyd +0 -0
- package/bin/_internal/_uuid.pyd +0 -0
- package/bin/_internal/_wmi.pyd +0 -0
- package/bin/_internal/_zoneinfo.pyd +0 -0
- package/bin/_internal/ada92cb5d92a588d1b93__mypyc.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/api-ms-win-core-console-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-datetime-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-debug-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-errorhandling-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-fibers-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-fibers-l1-1-1.dll +0 -0
- package/bin/_internal/api-ms-win-core-file-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-file-l1-2-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-file-l2-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-handle-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-heap-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-interlocked-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-kernel32-legacy-l1-1-1.dll +0 -0
- package/bin/_internal/api-ms-win-core-libraryloader-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-localization-l1-2-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-memory-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-namedpipe-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-processenvironment-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-processthreads-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-processthreads-l1-1-1.dll +0 -0
- package/bin/_internal/api-ms-win-core-profile-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-rtlsupport-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-string-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-synch-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-synch-l1-2-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-sysinfo-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-sysinfo-l1-2-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-timezone-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-core-util-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-conio-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-convert-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-environment-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-filesystem-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-heap-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-locale-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-math-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-process-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-stdio-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-string-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-time-l1-1-0.dll +0 -0
- package/bin/_internal/api-ms-win-crt-utility-l1-1-0.dll +0 -0
- package/bin/_internal/base_library.zip +0 -0
- package/bin/_internal/certifi/cacert.pem +3959 -0
- package/bin/_internal/certifi/py.typed +0 -0
- package/bin/_internal/charset_normalizer/cd.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/charset_normalizer/md.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/click-8.4.2.dist-info/INSTALLER +1 -0
- package/bin/_internal/click-8.4.2.dist-info/METADATA +84 -0
- package/bin/_internal/click-8.4.2.dist-info/RECORD +40 -0
- package/bin/_internal/click-8.4.2.dist-info/WHEEL +4 -0
- package/bin/_internal/click-8.4.2.dist-info/licenses/LICENSE.txt +28 -0
- package/bin/_internal/cryptography/hazmat/bindings/_rust.pyd +0 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/INSTALLER +1 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/METADATA +110 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/RECORD +195 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/WHEEL +4 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/licenses/LICENSE +3 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/licenses/LICENSE.APACHE +202 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/licenses/LICENSE.BSD +27 -0
- 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/WHEEL +5 -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.dll +0 -0
- package/bin/_internal/libffi-8.dll +0 -0
- package/bin/_internal/libssl-3.dll +0 -0
- package/bin/_internal/lxml/_elementpath.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/lxml/builder.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/lxml/etree.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/lxml/html/_difflib.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/lxml/html/diff.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/lxml/isoschematron/resources/rng/iso-schematron.rng +709 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/RNG2Schtrn.xsl +75 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/XSD2Schtrn.xsl +77 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_abstract_expand.xsl +313 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_dsdl_include.xsl +1160 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_message.xsl +55 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_skeleton_for_xslt1.xsl +1796 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_svrl_for_xslt1.xsl +588 -0
- package/bin/_internal/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/readme.txt +84 -0
- package/bin/_internal/lxml/objectify.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/lxml/sax.cp312-win_amd64.pyd +0 -0
- package/bin/_internal/pyexpat.pyd +0 -0
- package/bin/_internal/python3.dll +0 -0
- package/bin/_internal/python312.dll +0 -0
- package/bin/_internal/select.pyd +0 -0
- package/bin/_internal/setuptools/_vendor/jaraco/text/Lorem ipsum.txt +2 -0
- package/bin/_internal/sspilib/raw/_context_attributes.pyd +0 -0
- package/bin/_internal/sspilib/raw/_credential.pyd +0 -0
- package/bin/_internal/sspilib/raw/_credential_attributes.pyd +0 -0
- package/bin/_internal/sspilib/raw/_message.pyd +0 -0
- package/bin/_internal/sspilib/raw/_ntstatus.pyd +0 -0
- package/bin/_internal/sspilib/raw/_security_buffer.pyd +0 -0
- package/bin/_internal/sspilib/raw/_security_context.pyd +0 -0
- package/bin/_internal/sspilib/raw/_security_package.pyd +0 -0
- package/bin/_internal/sspilib/raw/_text.pyd +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Abidjan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Accra +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Addis_Ababa +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Algiers +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Asmara +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Asmera +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Bamako +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Bangui +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Banjul +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Bissau +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Blantyre +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Brazzaville +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Bujumbura +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Cairo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Casablanca +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Ceuta +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Conakry +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Dakar +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Dar_es_Salaam +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Djibouti +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Douala +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/El_Aaiun +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Freetown +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Gaborone +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Harare +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Johannesburg +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Juba +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Kampala +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Khartoum +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Kigali +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Kinshasa +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Lagos +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Libreville +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Lome +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Luanda +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Lubumbashi +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Lusaka +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Malabo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Maputo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Maseru +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Mbabane +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Mogadishu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Monrovia +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Nairobi +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Ndjamena +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Niamey +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Nouakchott +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Ouagadougou +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Porto-Novo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Sao_Tome +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Timbuktu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Tripoli +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Tunis +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Windhoek +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Adak +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Anchorage +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Anguilla +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Antigua +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Araguaina +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Buenos_Aires +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Catamarca +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/ComodRivadavia +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Cordoba +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Jujuy +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/La_Rioja +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Mendoza +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Rio_Gallegos +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Salta +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/San_Juan +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/San_Luis +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Tucuman +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Argentina/Ushuaia +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Aruba +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Asuncion +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Atikokan +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Atka +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Bahia +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Bahia_Banderas +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Barbados +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Belem +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Belize +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Blanc-Sablon +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Boa_Vista +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Bogota +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Boise +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Buenos_Aires +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Cambridge_Bay +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Campo_Grande +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Cancun +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Caracas +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Catamarca +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Cayenne +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Cayman +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Chicago +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Chihuahua +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Ciudad_Juarez +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Coral_Harbour +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Cordoba +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Costa_Rica +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Coyhaique +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Creston +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Cuiaba +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Curacao +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Danmarkshavn +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Dawson +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Dawson_Creek +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Denver +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Detroit +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Dominica +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Edmonton +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Eirunepe +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/El_Salvador +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Ensenada +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Fort_Nelson +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Fort_Wayne +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Fortaleza +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Glace_Bay +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Godthab +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Goose_Bay +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Grand_Turk +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Grenada +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Guadeloupe +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Guatemala +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Guayaquil +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Guyana +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Halifax +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Havana +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Hermosillo +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Indianapolis +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Knox +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Marengo +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Petersburg +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Tell_City +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Vevay +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Vincennes +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indiana/Winamac +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Indianapolis +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Inuvik +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Iqaluit +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Jamaica +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Jujuy +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Juneau +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Kentucky/Louisville +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Kentucky/Monticello +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Knox_IN +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Kralendijk +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/La_Paz +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Lima +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Los_Angeles +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Louisville +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Lower_Princes +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Maceio +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Managua +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Manaus +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Marigot +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Martinique +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Matamoros +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Mazatlan +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Mendoza +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Menominee +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Merida +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Metlakatla +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Mexico_City +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Miquelon +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Moncton +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Monterrey +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Montevideo +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Montreal +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Montserrat +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Nassau +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/New_York +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Nipigon +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Nome +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Noronha +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/North_Dakota/Beulah +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/North_Dakota/Center +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/North_Dakota/New_Salem +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Nuuk +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Ojinaga +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Panama +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Pangnirtung +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Paramaribo +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Phoenix +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Port-au-Prince +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Port_of_Spain +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Porto_Acre +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Porto_Velho +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Puerto_Rico +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Punta_Arenas +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Rainy_River +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Rankin_Inlet +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Recife +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Regina +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Resolute +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Rio_Branco +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Rosario +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Santa_Isabel +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Santarem +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Santiago +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Santo_Domingo +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Sao_Paulo +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Scoresbysund +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Shiprock +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Sitka +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/St_Barthelemy +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/St_Johns +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/St_Kitts +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/St_Lucia +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/St_Thomas +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/St_Vincent +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Swift_Current +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Tegucigalpa +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Thule +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Thunder_Bay +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Tijuana +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Toronto +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Tortola +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Vancouver +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Virgin +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Whitehorse +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Winnipeg +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Yakutat +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Yellowknife +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Casey +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Davis +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/DumontDUrville +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Macquarie +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Mawson +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/McMurdo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Palmer +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Rothera +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/South_Pole +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Syowa +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Troll +0 -0
- package/bin/_internal/tzdata/zoneinfo/Antarctica/Vostok +0 -0
- package/bin/_internal/tzdata/zoneinfo/Arctic/Longyearbyen +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Aden +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Almaty +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Amman +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Anadyr +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Aqtau +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Aqtobe +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ashgabat +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ashkhabad +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Atyrau +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Baghdad +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Bahrain +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Baku +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Bangkok +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Barnaul +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Beirut +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Bishkek +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Brunei +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Calcutta +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Chita +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Choibalsan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Chongqing +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Chungking +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Colombo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Dacca +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Damascus +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Dhaka +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Dili +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Dubai +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Dushanbe +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Famagusta +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Gaza +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Harbin +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Hebron +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Hong_Kong +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Hovd +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Irkutsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Istanbul +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Jakarta +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Jayapura +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Jerusalem +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kabul +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kamchatka +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Karachi +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kashgar +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kathmandu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Katmandu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Khandyga +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kolkata +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Krasnoyarsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kuala_Lumpur +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kuching +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Kuwait +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Macao +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Macau +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Magadan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Makassar +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Manila +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Muscat +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Nicosia +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Novokuznetsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Novosibirsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Omsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Oral +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Phnom_Penh +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Pontianak +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Pyongyang +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Qatar +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Qostanay +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Qyzylorda +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Rangoon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Riyadh +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Saigon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Sakhalin +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Samarkand +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Seoul +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Shanghai +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Singapore +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Srednekolymsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Taipei +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Tashkent +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Tbilisi +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Tehran +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Tel_Aviv +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Thimbu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Thimphu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Tokyo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Tomsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ujung_Pandang +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ulaanbaatar +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ulan_Bator +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Urumqi +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ust-Nera +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Vientiane +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Vladivostok +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Yakutsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Yangon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Yekaterinburg +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Yerevan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Azores +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Bermuda +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Canary +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Cape_Verde +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Faeroe +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Faroe +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Jan_Mayen +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Madeira +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Reykjavik +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/South_Georgia +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/St_Helena +0 -0
- package/bin/_internal/tzdata/zoneinfo/Atlantic/Stanley +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/ACT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Adelaide +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Brisbane +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Broken_Hill +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Canberra +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Currie +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Darwin +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Eucla +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Hobart +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/LHI +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Lindeman +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Lord_Howe +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Melbourne +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/NSW +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/North +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Perth +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Queensland +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/South +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Sydney +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Tasmania +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Victoria +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/West +0 -0
- package/bin/_internal/tzdata/zoneinfo/Australia/Yancowinna +0 -0
- package/bin/_internal/tzdata/zoneinfo/Brazil/Acre +0 -0
- package/bin/_internal/tzdata/zoneinfo/Brazil/DeNoronha +0 -0
- package/bin/_internal/tzdata/zoneinfo/Brazil/East +0 -0
- package/bin/_internal/tzdata/zoneinfo/Brazil/West +0 -0
- package/bin/_internal/tzdata/zoneinfo/CET +0 -0
- package/bin/_internal/tzdata/zoneinfo/CST6CDT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Atlantic +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Central +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Eastern +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Mountain +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Newfoundland +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Pacific +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Saskatchewan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Yukon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Chile/Continental +0 -0
- package/bin/_internal/tzdata/zoneinfo/Chile/EasterIsland +0 -0
- package/bin/_internal/tzdata/zoneinfo/Cuba +0 -0
- package/bin/_internal/tzdata/zoneinfo/EET +0 -0
- package/bin/_internal/tzdata/zoneinfo/EST +0 -0
- package/bin/_internal/tzdata/zoneinfo/EST5EDT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Egypt +0 -0
- package/bin/_internal/tzdata/zoneinfo/Eire +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+0 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+1 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+10 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+11 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+12 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+2 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+3 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+4 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+5 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+6 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+7 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+8 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT+9 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-0 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-1 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-10 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-11 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-12 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-13 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-14 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-2 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-3 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-4 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-5 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-6 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-7 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-8 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT-9 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/GMT0 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/Greenwich +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/UCT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/UTC +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/Universal +0 -0
- package/bin/_internal/tzdata/zoneinfo/Etc/Zulu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Amsterdam +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Andorra +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Astrakhan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Athens +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Belfast +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Belgrade +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Berlin +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Bratislava +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Brussels +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Bucharest +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Budapest +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Busingen +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Chisinau +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Copenhagen +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Dublin +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Gibraltar +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Guernsey +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Helsinki +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Isle_of_Man +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Istanbul +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Jersey +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Kaliningrad +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Kiev +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Kirov +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Kyiv +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Lisbon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Ljubljana +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/London +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Luxembourg +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Madrid +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Malta +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Mariehamn +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Minsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Monaco +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Moscow +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Nicosia +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Oslo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Paris +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Podgorica +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Prague +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Riga +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Rome +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Samara +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/San_Marino +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Sarajevo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Saratov +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Simferopol +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Skopje +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Sofia +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Stockholm +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Tallinn +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Tirane +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Tiraspol +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Ulyanovsk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Uzhgorod +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Vaduz +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Vatican +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Vienna +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Vilnius +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Volgograd +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Warsaw +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Zagreb +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Zaporozhye +0 -0
- package/bin/_internal/tzdata/zoneinfo/Europe/Zurich +0 -0
- package/bin/_internal/tzdata/zoneinfo/Factory +0 -0
- package/bin/_internal/tzdata/zoneinfo/GB +0 -0
- package/bin/_internal/tzdata/zoneinfo/GB-Eire +0 -0
- package/bin/_internal/tzdata/zoneinfo/GMT +0 -0
- package/bin/_internal/tzdata/zoneinfo/GMT+0 +0 -0
- package/bin/_internal/tzdata/zoneinfo/GMT-0 +0 -0
- package/bin/_internal/tzdata/zoneinfo/GMT0 +0 -0
- package/bin/_internal/tzdata/zoneinfo/Greenwich +0 -0
- package/bin/_internal/tzdata/zoneinfo/HST +0 -0
- package/bin/_internal/tzdata/zoneinfo/Hongkong +0 -0
- package/bin/_internal/tzdata/zoneinfo/Iceland +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Antananarivo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Chagos +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Christmas +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Cocos +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Comoro +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Kerguelen +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Mahe +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Maldives +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Mauritius +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Mayotte +0 -0
- package/bin/_internal/tzdata/zoneinfo/Indian/Reunion +0 -0
- package/bin/_internal/tzdata/zoneinfo/Iran +0 -0
- package/bin/_internal/tzdata/zoneinfo/Israel +0 -0
- package/bin/_internal/tzdata/zoneinfo/Jamaica +0 -0
- package/bin/_internal/tzdata/zoneinfo/Japan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Kwajalein +0 -0
- package/bin/_internal/tzdata/zoneinfo/Libya +0 -0
- package/bin/_internal/tzdata/zoneinfo/MET +0 -0
- package/bin/_internal/tzdata/zoneinfo/MST +0 -0
- package/bin/_internal/tzdata/zoneinfo/MST7MDT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Mexico/BajaNorte +0 -0
- package/bin/_internal/tzdata/zoneinfo/Mexico/BajaSur +0 -0
- package/bin/_internal/tzdata/zoneinfo/Mexico/General +0 -0
- package/bin/_internal/tzdata/zoneinfo/NZ +0 -0
- package/bin/_internal/tzdata/zoneinfo/NZ-CHAT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Navajo +0 -0
- package/bin/_internal/tzdata/zoneinfo/PRC +0 -0
- package/bin/_internal/tzdata/zoneinfo/PST8PDT +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Apia +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Auckland +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Bougainville +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Chatham +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Chuuk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Easter +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Efate +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Enderbury +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Fakaofo +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Fiji +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Funafuti +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Galapagos +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Gambier +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Guadalcanal +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Guam +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Honolulu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Johnston +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Kanton +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Kiritimati +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Kosrae +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Kwajalein +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Majuro +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Marquesas +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Midway +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Nauru +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Niue +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Norfolk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Noumea +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Pago_Pago +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Palau +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Pitcairn +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Pohnpei +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Ponape +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Port_Moresby +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Rarotonga +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Saipan +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Samoa +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Tahiti +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Tarawa +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Tongatapu +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Truk +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Wake +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Wallis +0 -0
- package/bin/_internal/tzdata/zoneinfo/Pacific/Yap +0 -0
- package/bin/_internal/tzdata/zoneinfo/Poland +0 -0
- package/bin/_internal/tzdata/zoneinfo/Portugal +0 -0
- package/bin/_internal/tzdata/zoneinfo/ROC +0 -0
- package/bin/_internal/tzdata/zoneinfo/ROK +0 -0
- package/bin/_internal/tzdata/zoneinfo/Singapore +0 -0
- package/bin/_internal/tzdata/zoneinfo/Turkey +0 -0
- package/bin/_internal/tzdata/zoneinfo/UCT +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Alaska +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Aleutian +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Arizona +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Central +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/East-Indiana +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Eastern +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Hawaii +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Indiana-Starke +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Michigan +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Mountain +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Pacific +0 -0
- package/bin/_internal/tzdata/zoneinfo/US/Samoa +0 -0
- package/bin/_internal/tzdata/zoneinfo/UTC +0 -0
- package/bin/_internal/tzdata/zoneinfo/Universal +0 -0
- package/bin/_internal/tzdata/zoneinfo/W-SU +0 -0
- package/bin/_internal/tzdata/zoneinfo/WET +0 -0
- package/bin/_internal/tzdata/zoneinfo/Zulu +0 -0
- package/bin/_internal/tzdata/zoneinfo/iso3166.tab +279 -0
- package/bin/_internal/tzdata/zoneinfo/leapseconds +86 -0
- package/bin/_internal/tzdata/zoneinfo/tzdata.zi +4180 -0
- package/bin/_internal/tzdata/zoneinfo/zone.tab +448 -0
- package/bin/_internal/tzdata/zoneinfo/zone1970.tab +375 -0
- package/bin/_internal/tzdata/zoneinfo/zonenow.tab +299 -0
- package/bin/_internal/tzdata/zones +598 -0
- package/bin/_internal/ucrtbase.dll +0 -0
- package/bin/_internal/unicodedata.pyd +0 -0
- package/bin/exchange-cli.exe +0 -0
- package/package.json +20 -0
|
@@ -0,0 +1,954 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import logging
|
|
3
|
+
from contextlib import suppress
|
|
4
|
+
from fnmatch import fnmatch
|
|
5
|
+
from operator import attrgetter
|
|
6
|
+
|
|
7
|
+
from ..errors import (
|
|
8
|
+
ErrorAccessDenied,
|
|
9
|
+
ErrorCannotDeleteObject,
|
|
10
|
+
ErrorCannotEmptyFolder,
|
|
11
|
+
ErrorDeleteDistinguishedFolder,
|
|
12
|
+
ErrorFolderNotFound,
|
|
13
|
+
ErrorItemNotFound,
|
|
14
|
+
ErrorRecoverableItemsAccessDenied,
|
|
15
|
+
InvalidTypeError,
|
|
16
|
+
)
|
|
17
|
+
from ..fields import (
|
|
18
|
+
CharField,
|
|
19
|
+
EffectiveRightsField,
|
|
20
|
+
EWSElementField,
|
|
21
|
+
Field,
|
|
22
|
+
FieldPath,
|
|
23
|
+
IdElementField,
|
|
24
|
+
IntegerField,
|
|
25
|
+
InvalidField,
|
|
26
|
+
PermissionSetField,
|
|
27
|
+
)
|
|
28
|
+
from ..items import HARD_DELETE, ITEM_CLASSES
|
|
29
|
+
from ..items import SHALLOW as SHALLOW_ITEMS
|
|
30
|
+
from ..items import CalendarItem, RegisterMixIn
|
|
31
|
+
from ..properties import (
|
|
32
|
+
DistinguishedFolderId,
|
|
33
|
+
EWSMeta,
|
|
34
|
+
FolderId,
|
|
35
|
+
Mailbox,
|
|
36
|
+
ParentFolderId,
|
|
37
|
+
UserConfiguration,
|
|
38
|
+
UserConfigurationName,
|
|
39
|
+
UserConfigurationNameMNS,
|
|
40
|
+
)
|
|
41
|
+
from ..queryset import DoesNotExist, SearchableMixIn
|
|
42
|
+
from ..util import TNS, is_iterable, require_id
|
|
43
|
+
from ..version import EXCHANGE_2007_SP1, EXCHANGE_2010, EXCHANGE_2016, SupportedVersionClassMixIn
|
|
44
|
+
from .collections import FolderCollection, PullSubscription, PushSubscription, StreamingSubscription, SyncCompleted
|
|
45
|
+
from .queryset import DEEP as DEEP_FOLDERS
|
|
46
|
+
from .queryset import MISSING_FOLDER_ERRORS
|
|
47
|
+
from .queryset import SHALLOW as SHALLOW_FOLDERS
|
|
48
|
+
from .queryset import SingleFolderQuerySet
|
|
49
|
+
|
|
50
|
+
log = logging.getLogger(__name__)
|
|
51
|
+
|
|
52
|
+
DELETE_FOLDER_ERRORS = (
|
|
53
|
+
ErrorAccessDenied,
|
|
54
|
+
ErrorCannotDeleteObject,
|
|
55
|
+
ErrorCannotEmptyFolder,
|
|
56
|
+
ErrorItemNotFound,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class BaseFolder(RegisterMixIn, SearchableMixIn, SupportedVersionClassMixIn, metaclass=EWSMeta):
|
|
61
|
+
"""Base class for all classes that implement a folder."""
|
|
62
|
+
|
|
63
|
+
ELEMENT_NAME = "Folder"
|
|
64
|
+
NAMESPACE = TNS
|
|
65
|
+
# See https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/distinguishedfolderid
|
|
66
|
+
DISTINGUISHED_FOLDER_ID = None
|
|
67
|
+
# Default item type for this folder. See
|
|
68
|
+
# https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxosfld/68a85898-84fe-43c4-b166-4711c13cdd61
|
|
69
|
+
CONTAINER_CLASS = None
|
|
70
|
+
supported_item_models = ITEM_CLASSES # The Item types that this folder can contain. Default is all
|
|
71
|
+
# Whether this folder type is allowed with the GetFolder service
|
|
72
|
+
get_folder_allowed = True
|
|
73
|
+
DEFAULT_FOLDER_TRAVERSAL_DEPTH = DEEP_FOLDERS
|
|
74
|
+
DEFAULT_ITEM_TRAVERSAL_DEPTH = SHALLOW_ITEMS
|
|
75
|
+
LOCALIZED_NAMES = {} # A map of (str)locale: (tuple)localized_folder_names
|
|
76
|
+
ITEM_MODEL_MAP = {cls.response_tag(): cls for cls in ITEM_CLASSES}
|
|
77
|
+
ID_ELEMENT_CLS = FolderId
|
|
78
|
+
|
|
79
|
+
_id = IdElementField(field_uri="folder:FolderId", value_cls=ID_ELEMENT_CLS)
|
|
80
|
+
_distinguished_id = IdElementField(
|
|
81
|
+
field_uri="folder:DistinguishedFolderId", value_cls=DistinguishedFolderId, supported_from=EXCHANGE_2016
|
|
82
|
+
)
|
|
83
|
+
parent_folder_id = EWSElementField(field_uri="folder:ParentFolderId", value_cls=ParentFolderId, is_read_only=True)
|
|
84
|
+
folder_class = CharField(field_uri="folder:FolderClass", is_required_after_save=True)
|
|
85
|
+
name = CharField(field_uri="folder:DisplayName")
|
|
86
|
+
total_count = IntegerField(field_uri="folder:TotalCount", is_read_only=True)
|
|
87
|
+
child_folder_count = IntegerField(field_uri="folder:ChildFolderCount", is_read_only=True)
|
|
88
|
+
unread_count = IntegerField(field_uri="folder:UnreadCount", is_read_only=True)
|
|
89
|
+
|
|
90
|
+
__slots__ = "item_sync_state", "folder_sync_state"
|
|
91
|
+
|
|
92
|
+
# Used to register extended properties
|
|
93
|
+
INSERT_AFTER_FIELD = "child_folder_count"
|
|
94
|
+
|
|
95
|
+
def __init__(self, **kwargs):
|
|
96
|
+
self.item_sync_state = kwargs.pop("item_sync_state", None)
|
|
97
|
+
self.folder_sync_state = kwargs.pop("folder_sync_state", None)
|
|
98
|
+
super().__init__(**kwargs)
|
|
99
|
+
if self._distinguished_id and not self._distinguished_id.mailbox and self.account:
|
|
100
|
+
# Ensure that distinguished IDs have a mailbox, but don't override a custom mailbox (e.g. shared folders)
|
|
101
|
+
self._distinguished_id.mailbox = Mailbox(email_address=self.account.primary_smtp_address)
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
@abc.abstractmethod
|
|
105
|
+
def account(self):
|
|
106
|
+
"""Return the account this folder belongs to"""
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
@abc.abstractmethod
|
|
110
|
+
def root(self):
|
|
111
|
+
"""Return the root folder this folder belongs to"""
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
@abc.abstractmethod
|
|
115
|
+
def parent(self):
|
|
116
|
+
"""Return the parent folder of this folder"""
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def is_distinguished(self):
|
|
120
|
+
return self._distinguished_id or (self.DISTINGUISHED_FOLDER_ID and not self._id)
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def is_deletable(self):
|
|
124
|
+
return not self.is_distinguished
|
|
125
|
+
|
|
126
|
+
def clean(self, version=None):
|
|
127
|
+
super().clean(version=version)
|
|
128
|
+
# Set a default folder class for new folders. A folder class cannot be changed after saving.
|
|
129
|
+
if self.id is None and self.folder_class is None:
|
|
130
|
+
self.folder_class = self.CONTAINER_CLASS
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def children(self):
|
|
134
|
+
# It's dangerous to return a generator here because we may then call methods on a child that result in the
|
|
135
|
+
# cache being updated while it's iterated.
|
|
136
|
+
return FolderCollection(account=self.account, folders=self.root.get_children(self))
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def parts(self):
|
|
140
|
+
parts = [self]
|
|
141
|
+
f = self.parent
|
|
142
|
+
while f:
|
|
143
|
+
parts.insert(0, f)
|
|
144
|
+
f = f.parent
|
|
145
|
+
return parts
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def absolute(self):
|
|
149
|
+
return "".join(f"/{p.name}" for p in self.parts)
|
|
150
|
+
|
|
151
|
+
def _walk(self):
|
|
152
|
+
for c in self.children:
|
|
153
|
+
yield c
|
|
154
|
+
yield from c.walk()
|
|
155
|
+
|
|
156
|
+
def walk(self):
|
|
157
|
+
return FolderCollection(account=self.account, folders=self._walk())
|
|
158
|
+
|
|
159
|
+
def _glob(self, pattern):
|
|
160
|
+
split_pattern = pattern.split("/", maxsplit=1)
|
|
161
|
+
head, tail = (split_pattern[0], None) if len(split_pattern) == 1 else split_pattern
|
|
162
|
+
if head == "":
|
|
163
|
+
# We got an absolute path. Restart globbing at root
|
|
164
|
+
yield from self.root.glob(tail or "*")
|
|
165
|
+
elif head == "..":
|
|
166
|
+
# Relative path with reference to parent. Restart globbing at parent
|
|
167
|
+
if not self.parent:
|
|
168
|
+
raise ValueError("Already at top")
|
|
169
|
+
yield from self.parent.glob(tail or "*")
|
|
170
|
+
elif head == "**":
|
|
171
|
+
# Match anything here or in any sub-folder at arbitrary depth
|
|
172
|
+
for c in self.walk():
|
|
173
|
+
# fnmatch() may be case-sensitive depending on operating system:
|
|
174
|
+
# force a case-insensitive match since case appears not to
|
|
175
|
+
# matter for folders in Exchange
|
|
176
|
+
if fnmatch(c.name.lower(), (tail or "*").lower()):
|
|
177
|
+
yield c
|
|
178
|
+
else:
|
|
179
|
+
# Regular pattern
|
|
180
|
+
for c in self.children:
|
|
181
|
+
# See note above on fnmatch() case-sensitivity
|
|
182
|
+
if not fnmatch(c.name.lower(), head.lower()):
|
|
183
|
+
continue
|
|
184
|
+
if tail is None:
|
|
185
|
+
yield c
|
|
186
|
+
continue
|
|
187
|
+
yield from c.glob(tail)
|
|
188
|
+
|
|
189
|
+
def glob(self, pattern):
|
|
190
|
+
return FolderCollection(account=self.account, folders=self._glob(pattern))
|
|
191
|
+
|
|
192
|
+
def tree(self):
|
|
193
|
+
"""Return a string representation of the folder structure of this folder. Example:
|
|
194
|
+
|
|
195
|
+
root
|
|
196
|
+
├── inbox
|
|
197
|
+
│ └── todos
|
|
198
|
+
└── archive
|
|
199
|
+
├── Last Job
|
|
200
|
+
├── exchangelib issues
|
|
201
|
+
└── Mom
|
|
202
|
+
"""
|
|
203
|
+
tree = f"{self.name}\n"
|
|
204
|
+
children = list(self.children)
|
|
205
|
+
for i, c in enumerate(sorted(children, key=attrgetter("name")), start=1):
|
|
206
|
+
nodes = c.tree().split("\n")
|
|
207
|
+
for j, node in enumerate(nodes, start=1):
|
|
208
|
+
if i != len(children) and j == 1:
|
|
209
|
+
# Not the last child, but the first node, which is the name of the child
|
|
210
|
+
tree += f"├── {node}\n"
|
|
211
|
+
elif i != len(children) and j > 1:
|
|
212
|
+
# Not the last child, and not name of child
|
|
213
|
+
tree += f"│ {node}\n"
|
|
214
|
+
elif i == len(children) and j == 1:
|
|
215
|
+
# Not the last child, but the first node, which is the name of the child
|
|
216
|
+
tree += f"└── {node}\n"
|
|
217
|
+
else: # Last child and not name of child
|
|
218
|
+
tree += f" {node}\n"
|
|
219
|
+
return tree.strip()
|
|
220
|
+
|
|
221
|
+
@classmethod
|
|
222
|
+
def _get_distinguished(cls, folder):
|
|
223
|
+
if not cls.DISTINGUISHED_FOLDER_ID:
|
|
224
|
+
raise ValueError(f"Class {cls} must have a DISTINGUISHED_FOLDER_ID value")
|
|
225
|
+
try:
|
|
226
|
+
return cls.resolve(account=folder.account, folder=folder)
|
|
227
|
+
except MISSING_FOLDER_ERRORS as e:
|
|
228
|
+
raise ErrorFolderNotFound(f"Could not find distinguished folder {cls.DISTINGUISHED_FOLDER_ID!r} ({e})")
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def has_distinguished_name(self):
|
|
232
|
+
return self.name and self.DISTINGUISHED_FOLDER_ID and self.name.lower() == self.DISTINGUISHED_FOLDER_ID.lower()
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def localized_names(cls, locale):
|
|
236
|
+
# Return localized names for a specific locale. If no locale-specific names exist, return the default names,
|
|
237
|
+
# if any.
|
|
238
|
+
return tuple(s.lower() for s in cls.LOCALIZED_NAMES.get(locale, cls.LOCALIZED_NAMES.get(None, [cls.__name__])))
|
|
239
|
+
|
|
240
|
+
@staticmethod
|
|
241
|
+
def folder_cls_from_container_class(container_class):
|
|
242
|
+
"""Return a reasonable folder class given a container class, e.g. 'IPF.Note'. Don't iterate WELLKNOWN_FOLDERS
|
|
243
|
+
because many folder classes have the same CONTAINER_CLASS.
|
|
244
|
+
|
|
245
|
+
:param container_class:
|
|
246
|
+
:return:
|
|
247
|
+
"""
|
|
248
|
+
from .known_folders import (
|
|
249
|
+
ApplicationData,
|
|
250
|
+
Calendar,
|
|
251
|
+
CompanyContacts,
|
|
252
|
+
Contacts,
|
|
253
|
+
ConversationSettings,
|
|
254
|
+
CrawlerData,
|
|
255
|
+
DlpPolicyEvaluation,
|
|
256
|
+
EventCheckPoints,
|
|
257
|
+
FreeBusyCache,
|
|
258
|
+
GALContacts,
|
|
259
|
+
Messages,
|
|
260
|
+
OrganizationalContacts,
|
|
261
|
+
PeopleCentricConversationBuddies,
|
|
262
|
+
RecipientCache,
|
|
263
|
+
RecoveryPoints,
|
|
264
|
+
Reminders,
|
|
265
|
+
RSSFeeds,
|
|
266
|
+
Signal,
|
|
267
|
+
SwssItems,
|
|
268
|
+
Tasks,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
for folder_cls in (
|
|
272
|
+
ApplicationData,
|
|
273
|
+
Calendar,
|
|
274
|
+
CompanyContacts,
|
|
275
|
+
Contacts,
|
|
276
|
+
ConversationSettings,
|
|
277
|
+
CrawlerData,
|
|
278
|
+
DlpPolicyEvaluation,
|
|
279
|
+
EventCheckPoints,
|
|
280
|
+
FreeBusyCache,
|
|
281
|
+
GALContacts,
|
|
282
|
+
Messages,
|
|
283
|
+
OrganizationalContacts,
|
|
284
|
+
PeopleCentricConversationBuddies,
|
|
285
|
+
RSSFeeds,
|
|
286
|
+
RecipientCache,
|
|
287
|
+
RecoveryPoints,
|
|
288
|
+
Reminders,
|
|
289
|
+
Signal,
|
|
290
|
+
SwssItems,
|
|
291
|
+
Tasks,
|
|
292
|
+
):
|
|
293
|
+
if folder_cls.CONTAINER_CLASS == container_class:
|
|
294
|
+
return folder_cls
|
|
295
|
+
raise KeyError()
|
|
296
|
+
|
|
297
|
+
@classmethod
|
|
298
|
+
def item_model_from_tag(cls, tag):
|
|
299
|
+
try:
|
|
300
|
+
return cls.ITEM_MODEL_MAP[tag]
|
|
301
|
+
except KeyError:
|
|
302
|
+
raise ValueError(f"Item type {tag} was unexpected in a {cls.__name__} folder")
|
|
303
|
+
|
|
304
|
+
@classmethod
|
|
305
|
+
def allowed_item_fields(cls, version):
|
|
306
|
+
# Return non-ID fields of all item classes allowed in this folder type
|
|
307
|
+
fields = set()
|
|
308
|
+
for item_model in cls.supported_item_models:
|
|
309
|
+
fields.update(set(item_model.supported_fields(version=version)))
|
|
310
|
+
return fields
|
|
311
|
+
|
|
312
|
+
def validate_item_field(self, field, version):
|
|
313
|
+
FolderCollection(account=self.account, folders=[self]).validate_item_field(field=field, version=version)
|
|
314
|
+
|
|
315
|
+
def normalize_fields(self, fields):
|
|
316
|
+
# Takes a list of fieldnames, Field or FieldPath objects pointing to item fields. Turns them into FieldPath
|
|
317
|
+
# objects and adds internal timezone fields if necessary. Assume fields are already validated.
|
|
318
|
+
fields = list(fields)
|
|
319
|
+
has_start, has_end = False, False
|
|
320
|
+
for i, field_path in enumerate(fields):
|
|
321
|
+
# Allow both Field and FieldPath instances and string field paths as input
|
|
322
|
+
if isinstance(field_path, str):
|
|
323
|
+
field_path = FieldPath.from_string(field_path=field_path, folder=self)
|
|
324
|
+
fields[i] = field_path
|
|
325
|
+
elif isinstance(field_path, Field):
|
|
326
|
+
field_path = FieldPath(field=field_path)
|
|
327
|
+
fields[i] = field_path
|
|
328
|
+
if field_path.field.name == "start":
|
|
329
|
+
has_start = True
|
|
330
|
+
elif field_path.field.name == "end":
|
|
331
|
+
has_end = True
|
|
332
|
+
|
|
333
|
+
# For CalendarItem items, we want to inject internal timezone fields. See also CalendarItem.clean()
|
|
334
|
+
if CalendarItem in self.supported_item_models:
|
|
335
|
+
meeting_tz_field, start_tz_field, end_tz_field = CalendarItem.timezone_fields()
|
|
336
|
+
if self.account.version.build < EXCHANGE_2010:
|
|
337
|
+
if has_start or has_end:
|
|
338
|
+
fields.append(FieldPath(field=meeting_tz_field))
|
|
339
|
+
else:
|
|
340
|
+
if has_start:
|
|
341
|
+
fields.append(FieldPath(field=start_tz_field))
|
|
342
|
+
if has_end:
|
|
343
|
+
fields.append(FieldPath(field=end_tz_field))
|
|
344
|
+
return fields
|
|
345
|
+
|
|
346
|
+
@classmethod
|
|
347
|
+
def get_item_field_by_fieldname(cls, fieldname):
|
|
348
|
+
for item_model in cls.supported_item_models:
|
|
349
|
+
with suppress(InvalidField):
|
|
350
|
+
return item_model.get_field_by_fieldname(fieldname)
|
|
351
|
+
raise InvalidField(f"{fieldname!r} is not a valid field name on {cls.supported_item_models}")
|
|
352
|
+
|
|
353
|
+
def get(self, *args, **kwargs):
|
|
354
|
+
return FolderCollection(account=self.account, folders=[self]).get(*args, **kwargs)
|
|
355
|
+
|
|
356
|
+
def all(self):
|
|
357
|
+
return FolderCollection(account=self.account, folders=[self]).all()
|
|
358
|
+
|
|
359
|
+
def none(self):
|
|
360
|
+
return FolderCollection(account=self.account, folders=[self]).none()
|
|
361
|
+
|
|
362
|
+
def filter(self, *args, **kwargs):
|
|
363
|
+
return FolderCollection(account=self.account, folders=[self]).filter(*args, **kwargs)
|
|
364
|
+
|
|
365
|
+
def exclude(self, *args, **kwargs):
|
|
366
|
+
return FolderCollection(account=self.account, folders=[self]).exclude(*args, **kwargs)
|
|
367
|
+
|
|
368
|
+
def people(self):
|
|
369
|
+
# No point in using a FolderCollection because FindPeople only supports one folder
|
|
370
|
+
return FolderCollection(account=self.account, folders=[self]).people()
|
|
371
|
+
|
|
372
|
+
def bulk_create(self, items, *args, **kwargs):
|
|
373
|
+
return self.account.bulk_create(folder=self, items=items, *args, **kwargs)
|
|
374
|
+
|
|
375
|
+
def save(self, update_fields=None):
|
|
376
|
+
from ..services import CreateFolder, UpdateFolder
|
|
377
|
+
|
|
378
|
+
if self.id is None:
|
|
379
|
+
# New folder
|
|
380
|
+
if update_fields:
|
|
381
|
+
raise ValueError("'update_fields' is only valid for updates")
|
|
382
|
+
res = CreateFolder(account=self.account).get(parent_folder=self.parent, folders=[self])
|
|
383
|
+
self._id = self.ID_ELEMENT_CLS(res.id, res.changekey)
|
|
384
|
+
self.root.add_folder(self) # Add this folder to the cache
|
|
385
|
+
return self
|
|
386
|
+
|
|
387
|
+
# Update folder
|
|
388
|
+
if not update_fields:
|
|
389
|
+
# The fields to update was not specified explicitly. Update all fields where update is possible
|
|
390
|
+
update_fields = []
|
|
391
|
+
for f in self.supported_fields(version=self.account.version):
|
|
392
|
+
if f.is_read_only:
|
|
393
|
+
# These cannot be changed
|
|
394
|
+
continue
|
|
395
|
+
if (f.is_required or f.is_required_after_save) and (
|
|
396
|
+
getattr(self, f.name) is None or (f.is_list and not getattr(self, f.name))
|
|
397
|
+
):
|
|
398
|
+
# These are required and cannot be deleted
|
|
399
|
+
continue
|
|
400
|
+
update_fields.append(f.name)
|
|
401
|
+
res = UpdateFolder(account=self.account).get(folders=[(self, update_fields)])
|
|
402
|
+
folder_id, changekey = res.id, res.changekey
|
|
403
|
+
if self.id != folder_id:
|
|
404
|
+
raise ValueError("ID mismatch")
|
|
405
|
+
# Don't check changekey value. It may not change on no-op updates
|
|
406
|
+
self.changekey = changekey
|
|
407
|
+
self.root.update_folder(self) # Update the folder in the cache
|
|
408
|
+
return self
|
|
409
|
+
|
|
410
|
+
def move(self, to_folder):
|
|
411
|
+
from ..services import MoveFolder
|
|
412
|
+
|
|
413
|
+
res = MoveFolder(account=self.account).get(folders=[self], to_folder=to_folder)
|
|
414
|
+
folder_id, changekey = res.id, res.changekey
|
|
415
|
+
if self.id != folder_id:
|
|
416
|
+
raise ValueError("ID mismatch")
|
|
417
|
+
# Don't check changekey value. It may not change on no-op moves
|
|
418
|
+
self.changekey = changekey
|
|
419
|
+
self.parent_folder_id = ParentFolderId(id=to_folder.id, changekey=to_folder.changekey)
|
|
420
|
+
self.root.update_folder(self) # Update the folder in the cache
|
|
421
|
+
|
|
422
|
+
def delete(self, delete_type=HARD_DELETE):
|
|
423
|
+
from ..services import DeleteFolder
|
|
424
|
+
|
|
425
|
+
DeleteFolder(account=self.account).get(folders=[self], delete_type=delete_type)
|
|
426
|
+
self.root.remove_folder(self) # Remove the updated folder from the cache
|
|
427
|
+
self._id = None
|
|
428
|
+
|
|
429
|
+
def empty(self, delete_type=HARD_DELETE, delete_sub_folders=False):
|
|
430
|
+
from ..services import EmptyFolder
|
|
431
|
+
|
|
432
|
+
EmptyFolder(account=self.account).get(
|
|
433
|
+
folders=[self], delete_type=delete_type, delete_sub_folders=delete_sub_folders
|
|
434
|
+
)
|
|
435
|
+
if delete_sub_folders:
|
|
436
|
+
# We don't know exactly what was deleted, so invalidate the entire folder cache to be safe
|
|
437
|
+
self.root.clear_cache()
|
|
438
|
+
|
|
439
|
+
def wipe(self, page_size=None, chunk_size=None, _seen=None, _level=0):
|
|
440
|
+
# Recursively deletes all items in this folder, and all sub-folders and their content. Attempts to protect
|
|
441
|
+
# distinguished folders from being deleted. Use with caution!
|
|
442
|
+
from .known_folders import Audits
|
|
443
|
+
|
|
444
|
+
_seen = _seen or set()
|
|
445
|
+
if self.id in _seen:
|
|
446
|
+
raise RecursionError(f"We already tried to wipe {self}")
|
|
447
|
+
if _level > 16:
|
|
448
|
+
raise RecursionError(f"Max recursion level reached: {_level}")
|
|
449
|
+
_seen.add(self.id)
|
|
450
|
+
if isinstance(self, Audits):
|
|
451
|
+
# Shortcircuit because this folder can have many items that are all non-deletable
|
|
452
|
+
log.warning("Cannot wipe audits folder %s", self)
|
|
453
|
+
return
|
|
454
|
+
if self.is_distinguished and "recoverableitems" in self.DISTINGUISHED_FOLDER_ID:
|
|
455
|
+
log.warning("Cannot wipe recoverable items folder %s", self)
|
|
456
|
+
return
|
|
457
|
+
log.warning("Wiping %s", self)
|
|
458
|
+
has_non_deletable_subfolders = any(not f.is_deletable for f in self.children)
|
|
459
|
+
try:
|
|
460
|
+
if has_non_deletable_subfolders:
|
|
461
|
+
self.empty()
|
|
462
|
+
else:
|
|
463
|
+
self.empty(delete_sub_folders=True)
|
|
464
|
+
except ErrorRecoverableItemsAccessDenied:
|
|
465
|
+
log.warning("Access denied to %s. Skipping", self)
|
|
466
|
+
return
|
|
467
|
+
except DELETE_FOLDER_ERRORS:
|
|
468
|
+
try:
|
|
469
|
+
if has_non_deletable_subfolders:
|
|
470
|
+
raise # We already tried this
|
|
471
|
+
self.empty()
|
|
472
|
+
except DELETE_FOLDER_ERRORS:
|
|
473
|
+
log.warning("Not allowed to empty %s. Trying to delete items instead", self)
|
|
474
|
+
kwargs = {}
|
|
475
|
+
if page_size is not None:
|
|
476
|
+
kwargs["page_size"] = page_size
|
|
477
|
+
if chunk_size is not None:
|
|
478
|
+
kwargs["chunk_size"] = chunk_size
|
|
479
|
+
try:
|
|
480
|
+
self.all().delete(**kwargs)
|
|
481
|
+
except DELETE_FOLDER_ERRORS:
|
|
482
|
+
log.warning("Not allowed to delete items in %s", self)
|
|
483
|
+
_level += 1
|
|
484
|
+
for f in self.children:
|
|
485
|
+
f.wipe(page_size=page_size, chunk_size=chunk_size, _seen=_seen, _level=_level)
|
|
486
|
+
# Remove non-distinguished children that are empty and have no sub-folders
|
|
487
|
+
if f.is_deletable and not f.children:
|
|
488
|
+
log.warning("Deleting folder %s", f)
|
|
489
|
+
try:
|
|
490
|
+
f.delete()
|
|
491
|
+
except ErrorDeleteDistinguishedFolder:
|
|
492
|
+
log.warning("Tried to delete a distinguished folder (%s)", f)
|
|
493
|
+
|
|
494
|
+
def test_access(self):
|
|
495
|
+
"""Does a simple FindItem to test (read) access to the folder. Maybe the account doesn't exist, maybe the
|
|
496
|
+
service user doesn't have access to the calendar. This will throw the most common errors.
|
|
497
|
+
"""
|
|
498
|
+
self.all().exists()
|
|
499
|
+
return True
|
|
500
|
+
|
|
501
|
+
@classmethod
|
|
502
|
+
def _kwargs_from_elem(cls, elem, account):
|
|
503
|
+
# Check for 'DisplayName' element before collecting kwargs because that clears the elements
|
|
504
|
+
has_name_elem = elem.find(cls.get_field_by_fieldname("name").response_tag()) is not None
|
|
505
|
+
kwargs = {f.name: f.from_xml(elem=elem, account=account) for f in cls.FIELDS}
|
|
506
|
+
if has_name_elem and not kwargs["name"]:
|
|
507
|
+
# When we request the 'DisplayName' property, some folders may still be returned with an empty value.
|
|
508
|
+
# Assign a default name to these folders.
|
|
509
|
+
kwargs["name"] = cls.DISTINGUISHED_FOLDER_ID
|
|
510
|
+
return kwargs
|
|
511
|
+
|
|
512
|
+
def to_id(self):
|
|
513
|
+
# Use self._distinguished_id as-is if we have it. This could be a DistinguishedFolderId with a mailbox pointing
|
|
514
|
+
# to a shared mailbox.
|
|
515
|
+
if self._distinguished_id:
|
|
516
|
+
return self._distinguished_id
|
|
517
|
+
if self._id:
|
|
518
|
+
return self._id
|
|
519
|
+
if not self.DISTINGUISHED_FOLDER_ID:
|
|
520
|
+
raise ValueError(f"{self} must be a distinguished folder or have an ID")
|
|
521
|
+
self._distinguished_id = DistinguishedFolderId(
|
|
522
|
+
id=self.DISTINGUISHED_FOLDER_ID,
|
|
523
|
+
mailbox=Mailbox(email_address=self.account.primary_smtp_address),
|
|
524
|
+
)
|
|
525
|
+
return self._distinguished_id
|
|
526
|
+
|
|
527
|
+
@classmethod
|
|
528
|
+
def resolve(cls, account, folder):
|
|
529
|
+
# Resolve a single folder
|
|
530
|
+
folders = list(FolderCollection(account=account, folders=[folder]).resolve())
|
|
531
|
+
if not folders:
|
|
532
|
+
raise ErrorFolderNotFound(f"Could not find folder {folder!r}")
|
|
533
|
+
if len(folders) != 1:
|
|
534
|
+
raise ValueError(f"Expected result length 1, but got {folders}")
|
|
535
|
+
f = folders[0]
|
|
536
|
+
if isinstance(f, Exception):
|
|
537
|
+
raise f
|
|
538
|
+
if f.__class__ != cls:
|
|
539
|
+
raise ValueError(f"Expected folder {f!r} to be a {cls} instance")
|
|
540
|
+
return f
|
|
541
|
+
|
|
542
|
+
@require_id
|
|
543
|
+
def refresh(self):
|
|
544
|
+
fresh_folder = self.resolve(account=self.account, folder=self)
|
|
545
|
+
if self.id != fresh_folder.id:
|
|
546
|
+
raise ValueError("ID mismatch")
|
|
547
|
+
# Apparently, the changekey may get updated
|
|
548
|
+
for f in self.FIELDS:
|
|
549
|
+
setattr(self, f.name, getattr(fresh_folder, f.name))
|
|
550
|
+
return self
|
|
551
|
+
|
|
552
|
+
@require_id
|
|
553
|
+
def get_user_configuration(self, name, properties=None):
|
|
554
|
+
from ..services import GetUserConfiguration
|
|
555
|
+
from ..services.get_user_configuration import ALL
|
|
556
|
+
|
|
557
|
+
if properties is None:
|
|
558
|
+
properties = ALL
|
|
559
|
+
return GetUserConfiguration(account=self.account).get(
|
|
560
|
+
user_configuration_name=UserConfigurationNameMNS(name=name, folder=self),
|
|
561
|
+
properties=properties,
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
@require_id
|
|
565
|
+
def create_user_configuration(self, name, dictionary=None, xml_data=None, binary_data=None):
|
|
566
|
+
from ..services import CreateUserConfiguration
|
|
567
|
+
|
|
568
|
+
user_configuration = UserConfiguration(
|
|
569
|
+
user_configuration_name=UserConfigurationName(name=name, folder=self),
|
|
570
|
+
dictionary=dictionary,
|
|
571
|
+
xml_data=xml_data,
|
|
572
|
+
binary_data=binary_data,
|
|
573
|
+
)
|
|
574
|
+
return CreateUserConfiguration(account=self.account).get(user_configuration=user_configuration)
|
|
575
|
+
|
|
576
|
+
@require_id
|
|
577
|
+
def update_user_configuration(self, name, dictionary=None, xml_data=None, binary_data=None):
|
|
578
|
+
from ..services import UpdateUserConfiguration
|
|
579
|
+
|
|
580
|
+
user_configuration = UserConfiguration(
|
|
581
|
+
user_configuration_name=UserConfigurationName(name=name, folder=self),
|
|
582
|
+
dictionary=dictionary,
|
|
583
|
+
xml_data=xml_data,
|
|
584
|
+
binary_data=binary_data,
|
|
585
|
+
)
|
|
586
|
+
return UpdateUserConfiguration(account=self.account).get(user_configuration=user_configuration)
|
|
587
|
+
|
|
588
|
+
@require_id
|
|
589
|
+
def delete_user_configuration(self, name):
|
|
590
|
+
from ..services import DeleteUserConfiguration
|
|
591
|
+
|
|
592
|
+
return DeleteUserConfiguration(account=self.account).get(
|
|
593
|
+
user_configuration_name=UserConfigurationNameMNS(name=name, folder=self)
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
@require_id
|
|
597
|
+
def subscribe_to_pull(self, event_types=None, watermark=None, timeout=60):
|
|
598
|
+
"""Create a pull subscription.
|
|
599
|
+
|
|
600
|
+
:param event_types: List of event types to subscribe to. Possible values defined in SubscribeToPull.EVENT_TYPES
|
|
601
|
+
:param watermark: An event bookmark as returned by some sync services
|
|
602
|
+
:param timeout: Timeout of the subscription, in minutes. Timeout is reset when the server receives a
|
|
603
|
+
GetEvents request for this subscription.
|
|
604
|
+
:return: The subscription ID and a watermark
|
|
605
|
+
"""
|
|
606
|
+
from ..services import SubscribeToPull
|
|
607
|
+
|
|
608
|
+
if event_types is None:
|
|
609
|
+
event_types = SubscribeToPull.EVENT_TYPES
|
|
610
|
+
return FolderCollection(account=self.account, folders=[self]).subscribe_to_pull(
|
|
611
|
+
event_types=event_types,
|
|
612
|
+
watermark=watermark,
|
|
613
|
+
timeout=timeout,
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
@require_id
|
|
617
|
+
def subscribe_to_push(self, callback_url, event_types=None, watermark=None, status_frequency=1):
|
|
618
|
+
"""Create a push subscription.
|
|
619
|
+
|
|
620
|
+
:param callback_url: A client-defined URL that the server will call
|
|
621
|
+
:param event_types: List of event types to subscribe to. Possible values defined in SubscribeToPush.EVENT_TYPES
|
|
622
|
+
:param watermark: An event bookmark as returned by some sync services
|
|
623
|
+
:param status_frequency: The frequency, in minutes, that the callback URL will be called with.
|
|
624
|
+
:return: The subscription ID and a watermark
|
|
625
|
+
"""
|
|
626
|
+
from ..services import SubscribeToPush
|
|
627
|
+
|
|
628
|
+
if event_types is None:
|
|
629
|
+
event_types = SubscribeToPush.EVENT_TYPES
|
|
630
|
+
return FolderCollection(account=self.account, folders=[self]).subscribe_to_push(
|
|
631
|
+
event_types=event_types,
|
|
632
|
+
watermark=watermark,
|
|
633
|
+
status_frequency=status_frequency,
|
|
634
|
+
callback_url=callback_url,
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
@require_id
|
|
638
|
+
def subscribe_to_streaming(self, event_types=None):
|
|
639
|
+
"""Create a streaming subscription.
|
|
640
|
+
|
|
641
|
+
:param event_types: List of event types to subscribe to. Possible values defined in SubscribeToPush.EVENT_TYPES
|
|
642
|
+
:return: The subscription ID
|
|
643
|
+
"""
|
|
644
|
+
from ..services import SubscribeToStreaming
|
|
645
|
+
|
|
646
|
+
if event_types is None:
|
|
647
|
+
event_types = SubscribeToStreaming.EVENT_TYPES
|
|
648
|
+
return FolderCollection(account=self.account, folders=[self]).subscribe_to_streaming(event_types=event_types)
|
|
649
|
+
|
|
650
|
+
@require_id
|
|
651
|
+
def pull_subscription(self, **kwargs):
|
|
652
|
+
return PullSubscription(target=self, **kwargs)
|
|
653
|
+
|
|
654
|
+
@require_id
|
|
655
|
+
def push_subscription(self, **kwargs):
|
|
656
|
+
return PushSubscription(target=self, **kwargs)
|
|
657
|
+
|
|
658
|
+
@require_id
|
|
659
|
+
def streaming_subscription(self, **kwargs):
|
|
660
|
+
return StreamingSubscription(target=self, **kwargs)
|
|
661
|
+
|
|
662
|
+
def unsubscribe(self, subscription_id):
|
|
663
|
+
"""Unsubscribe. Only applies to pull and streaming notifications.
|
|
664
|
+
|
|
665
|
+
:param subscription_id: A subscription ID as acquired by .subscribe_to_[pull|streaming]()
|
|
666
|
+
:return: True
|
|
667
|
+
|
|
668
|
+
This method doesn't need the current folder instance, but it makes sense to keep the method along the other
|
|
669
|
+
sync methods.
|
|
670
|
+
"""
|
|
671
|
+
from ..services import Unsubscribe
|
|
672
|
+
|
|
673
|
+
return Unsubscribe(account=self.account).get(subscription_id=subscription_id)
|
|
674
|
+
|
|
675
|
+
def sync_items(self, sync_state=None, only_fields=None, ignore=None, max_changes_returned=None, sync_scope=None):
|
|
676
|
+
"""Return all item changes to a folder, as a generator. If sync_state is specified, get all item changes after
|
|
677
|
+
this sync state. After fully consuming the generator, self.item_sync_state will hold the new sync state.
|
|
678
|
+
|
|
679
|
+
:param sync_state: The state of the sync. Returned by a successful call to the SyncFolderItems service.
|
|
680
|
+
:param only_fields: A list of string or FieldPath items specifying the fields to fetch. Default to all fields
|
|
681
|
+
:param ignore: A list of Item IDs to ignore in the sync
|
|
682
|
+
:param max_changes_returned: The max number of change
|
|
683
|
+
:param sync_scope: Specify whether to return just items, or items and folder associated information. Possible
|
|
684
|
+
values are specified in SyncFolderItems.SYNC_SCOPES
|
|
685
|
+
:return: A generator of (change_type, item) tuples
|
|
686
|
+
"""
|
|
687
|
+
if not sync_state:
|
|
688
|
+
sync_state = self.item_sync_state
|
|
689
|
+
try:
|
|
690
|
+
yield from FolderCollection(account=self.account, folders=[self]).sync_items(
|
|
691
|
+
sync_state=sync_state,
|
|
692
|
+
only_fields=only_fields,
|
|
693
|
+
ignore=ignore,
|
|
694
|
+
max_changes_returned=max_changes_returned,
|
|
695
|
+
sync_scope=sync_scope,
|
|
696
|
+
)
|
|
697
|
+
except SyncCompleted as e:
|
|
698
|
+
# Set the new sync state on the folder instance
|
|
699
|
+
self.item_sync_state = e.sync_state
|
|
700
|
+
|
|
701
|
+
def sync_hierarchy(self, sync_state=None, only_fields=None):
|
|
702
|
+
"""Return all folder changes to a folder hierarchy, as a generator. If sync_state is specified, get all folder
|
|
703
|
+
changes after this sync state. After fully consuming the generator, self.folder_sync_state will hold the new
|
|
704
|
+
sync state.
|
|
705
|
+
|
|
706
|
+
:param sync_state: The state of the sync. Returned by a successful call to the SyncFolderItems service.
|
|
707
|
+
:param only_fields: A list of string or FieldPath items specifying the fields to fetch. Default to all fields
|
|
708
|
+
:return:
|
|
709
|
+
"""
|
|
710
|
+
if not sync_state:
|
|
711
|
+
sync_state = self.folder_sync_state
|
|
712
|
+
try:
|
|
713
|
+
yield from FolderCollection(account=self.account, folders=[self]).sync_hierarchy(
|
|
714
|
+
sync_state=sync_state,
|
|
715
|
+
only_fields=only_fields,
|
|
716
|
+
)
|
|
717
|
+
except SyncCompleted as e:
|
|
718
|
+
# Set the new sync state on the folder instance
|
|
719
|
+
self.folder_sync_state = e.sync_state
|
|
720
|
+
|
|
721
|
+
def get_events(self, subscription_id, watermark):
|
|
722
|
+
"""Get events since the given watermark. Non-blocking.
|
|
723
|
+
|
|
724
|
+
:param subscription_id: A subscription ID as acquired by .subscribe_to_[pull|push]()
|
|
725
|
+
:param watermark: Either the watermark from the subscription, or as returned by the last .get_events() call.
|
|
726
|
+
:return: A Notification object containing a list of events
|
|
727
|
+
|
|
728
|
+
This method doesn't need the current folder instance, but it makes sense to keep the method along the other
|
|
729
|
+
sync methods.
|
|
730
|
+
"""
|
|
731
|
+
from ..services import GetEvents
|
|
732
|
+
|
|
733
|
+
svc = GetEvents(account=self.account)
|
|
734
|
+
while True:
|
|
735
|
+
notification = svc.get(subscription_id=subscription_id, watermark=watermark)
|
|
736
|
+
yield notification
|
|
737
|
+
if not notification.more_events:
|
|
738
|
+
break
|
|
739
|
+
|
|
740
|
+
def get_streaming_events(self, subscription_id_or_ids, connection_timeout=1, max_notifications_returned=None):
|
|
741
|
+
"""Get events since the subscription was created, in streaming mode. This method will block as many minutes
|
|
742
|
+
as specified by 'connection_timeout'.
|
|
743
|
+
|
|
744
|
+
:param subscription_id_or_ids: A subscription ID, or list of IDs, as acquired by .subscribe_to_streaming()
|
|
745
|
+
:param connection_timeout: Timeout of the connection, in minutes. The connection is closed after this timeout
|
|
746
|
+
is reached.
|
|
747
|
+
:param max_notifications_returned: If specified, will exit after receiving this number of notifications
|
|
748
|
+
:return: A generator of Notification objects, each containing a list of events
|
|
749
|
+
|
|
750
|
+
This method doesn't need the current folder instance, but it makes sense to keep the method along the other
|
|
751
|
+
sync methods.
|
|
752
|
+
"""
|
|
753
|
+
from ..services import GetStreamingEvents
|
|
754
|
+
|
|
755
|
+
svc = GetStreamingEvents(account=self.account)
|
|
756
|
+
subscription_ids = (
|
|
757
|
+
subscription_id_or_ids
|
|
758
|
+
if is_iterable(subscription_id_or_ids, generators_allowed=True)
|
|
759
|
+
else [subscription_id_or_ids]
|
|
760
|
+
)
|
|
761
|
+
for i, notification in enumerate(
|
|
762
|
+
svc.call(subscription_ids=subscription_ids, connection_timeout=connection_timeout), start=1
|
|
763
|
+
):
|
|
764
|
+
yield notification
|
|
765
|
+
if max_notifications_returned and i >= max_notifications_returned:
|
|
766
|
+
svc.stop_streaming()
|
|
767
|
+
break
|
|
768
|
+
|
|
769
|
+
def __floordiv__(self, other):
|
|
770
|
+
"""Support the some_folder // 'child_folder' // 'child_of_child_folder' navigation syntax.
|
|
771
|
+
|
|
772
|
+
Works like as __truediv__ but does not touch the folder cache.
|
|
773
|
+
|
|
774
|
+
This is useful if the folder hierarchy contains a huge number of folders, and you don't want to fetch them all
|
|
775
|
+
|
|
776
|
+
:param other:
|
|
777
|
+
:return:
|
|
778
|
+
"""
|
|
779
|
+
if other == "..":
|
|
780
|
+
raise ValueError("Cannot get parent without a folder cache")
|
|
781
|
+
|
|
782
|
+
if other == ".":
|
|
783
|
+
return self
|
|
784
|
+
|
|
785
|
+
# Assume an exact match on the folder name in a shallow search will only return at most one folder
|
|
786
|
+
try:
|
|
787
|
+
return SingleFolderQuerySet(account=self.account, folder=self).depth(SHALLOW_FOLDERS).get(name=other)
|
|
788
|
+
except DoesNotExist:
|
|
789
|
+
raise ErrorFolderNotFound(f"No subfolder with name {other!r}")
|
|
790
|
+
|
|
791
|
+
def __truediv__(self, other):
|
|
792
|
+
"""Support the some_folder / 'child_folder' / 'child_of_child_folder' navigation syntax."""
|
|
793
|
+
if other == "..":
|
|
794
|
+
if not self.parent:
|
|
795
|
+
raise ValueError("Already at top")
|
|
796
|
+
return self.parent
|
|
797
|
+
if other == ".":
|
|
798
|
+
return self
|
|
799
|
+
for c in self.children:
|
|
800
|
+
# Folders are case-insensitive server-side. Let's do that here as well.
|
|
801
|
+
if c.name.lower() == other.lower():
|
|
802
|
+
return c
|
|
803
|
+
raise ErrorFolderNotFound(f"No subfolder with name {other!r}")
|
|
804
|
+
|
|
805
|
+
def __repr__(self):
|
|
806
|
+
return self.__class__.__name__ + repr(
|
|
807
|
+
(
|
|
808
|
+
self.root,
|
|
809
|
+
self.name,
|
|
810
|
+
self.total_count,
|
|
811
|
+
self.unread_count,
|
|
812
|
+
self.child_folder_count,
|
|
813
|
+
self.folder_class,
|
|
814
|
+
self.id,
|
|
815
|
+
self.changekey,
|
|
816
|
+
)
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
def __str__(self):
|
|
820
|
+
return f"{self.__class__.__name__} ({self.name})"
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
class Folder(BaseFolder):
|
|
824
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/folder"""
|
|
825
|
+
|
|
826
|
+
permission_set = PermissionSetField(field_uri="folder:PermissionSet", supported_from=EXCHANGE_2007_SP1)
|
|
827
|
+
effective_rights = EffectiveRightsField(
|
|
828
|
+
field_uri="folder:EffectiveRights", is_read_only=True, supported_from=EXCHANGE_2007_SP1
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
__slots__ = ("_root",)
|
|
832
|
+
|
|
833
|
+
def __init__(self, **kwargs):
|
|
834
|
+
self._root = kwargs.pop("root", None) # This is a pointer to the root of the folder hierarchy
|
|
835
|
+
parent = kwargs.pop("parent", None)
|
|
836
|
+
if parent:
|
|
837
|
+
if self.root:
|
|
838
|
+
if parent.root != self.root:
|
|
839
|
+
raise ValueError("'parent.root' must match 'root'")
|
|
840
|
+
else:
|
|
841
|
+
self._root = parent.root
|
|
842
|
+
if "parent_folder_id" in kwargs and parent.id != kwargs["parent_folder_id"]:
|
|
843
|
+
raise ValueError("'parent_folder_id' must match 'parent' ID")
|
|
844
|
+
kwargs["parent_folder_id"] = ParentFolderId(id=parent.id, changekey=parent.changekey)
|
|
845
|
+
super().__init__(**kwargs)
|
|
846
|
+
|
|
847
|
+
@property
|
|
848
|
+
def account(self):
|
|
849
|
+
if self.root is None:
|
|
850
|
+
return None
|
|
851
|
+
return self.root.account
|
|
852
|
+
|
|
853
|
+
@property
|
|
854
|
+
def root(self):
|
|
855
|
+
return self._root
|
|
856
|
+
|
|
857
|
+
@classmethod
|
|
858
|
+
def register(cls, *args, **kwargs):
|
|
859
|
+
if cls is not Folder:
|
|
860
|
+
raise TypeError("For folders, custom fields must be registered on the Folder class")
|
|
861
|
+
return super().register(*args, **kwargs)
|
|
862
|
+
|
|
863
|
+
@classmethod
|
|
864
|
+
def deregister(cls, *args, **kwargs):
|
|
865
|
+
if cls is not Folder:
|
|
866
|
+
raise TypeError("For folders, custom fields must be registered on the Folder class")
|
|
867
|
+
return super().deregister(*args, **kwargs)
|
|
868
|
+
|
|
869
|
+
@property
|
|
870
|
+
def parent(self):
|
|
871
|
+
if not self.parent_folder_id:
|
|
872
|
+
return None
|
|
873
|
+
if self.parent_folder_id.id == self.id:
|
|
874
|
+
# Some folders have a parent that references itself. Avoid circular references here
|
|
875
|
+
return None
|
|
876
|
+
return self.root.get_folder(self.parent_folder_id)
|
|
877
|
+
|
|
878
|
+
@parent.setter
|
|
879
|
+
def parent(self, value):
|
|
880
|
+
if value is None:
|
|
881
|
+
self.parent_folder_id = None
|
|
882
|
+
else:
|
|
883
|
+
if not isinstance(value, BaseFolder):
|
|
884
|
+
raise InvalidTypeError("value", value, BaseFolder)
|
|
885
|
+
self._root = value.root
|
|
886
|
+
self.parent_folder_id = ParentFolderId(id=value.id, changekey=value.changekey)
|
|
887
|
+
|
|
888
|
+
def clean(self, version=None):
|
|
889
|
+
from .roots import RootOfHierarchy
|
|
890
|
+
|
|
891
|
+
super().clean(version=version)
|
|
892
|
+
if self.root and not isinstance(self.root, RootOfHierarchy):
|
|
893
|
+
raise InvalidTypeError("root", self.root, RootOfHierarchy)
|
|
894
|
+
|
|
895
|
+
@classmethod
|
|
896
|
+
def get_distinguished(cls, root):
|
|
897
|
+
"""Get the distinguished folder for this folder class.
|
|
898
|
+
|
|
899
|
+
:param root:
|
|
900
|
+
:return:
|
|
901
|
+
"""
|
|
902
|
+
return cls._get_distinguished(
|
|
903
|
+
folder=cls(
|
|
904
|
+
_distinguished_id=DistinguishedFolderId(
|
|
905
|
+
id=cls.DISTINGUISHED_FOLDER_ID,
|
|
906
|
+
mailbox=Mailbox(email_address=root.account.primary_smtp_address),
|
|
907
|
+
),
|
|
908
|
+
root=root,
|
|
909
|
+
)
|
|
910
|
+
)
|
|
911
|
+
|
|
912
|
+
@classmethod
|
|
913
|
+
def from_xml_with_root(cls, elem, root):
|
|
914
|
+
folder = cls.from_xml(elem=elem, account=root.account)
|
|
915
|
+
folder_cls = cls
|
|
916
|
+
if cls == Folder:
|
|
917
|
+
# We were called on the generic Folder class. Try to find a more specific class to return objects as.
|
|
918
|
+
#
|
|
919
|
+
# The "FolderClass" element value is the only indication we have in the FindFolder response of which
|
|
920
|
+
# folder class we should create the folder with. And many folders share the same 'FolderClass' value, e.g.
|
|
921
|
+
# Inbox and DeletedItems. We want to distinguish between these because otherwise we can't locate the right
|
|
922
|
+
# folders types for e.g. Account.inbox and Account.trash.
|
|
923
|
+
#
|
|
924
|
+
# We should be able to just use the name, but apparently default folder names can be renamed to a set of
|
|
925
|
+
# localized names using a PowerShell command:
|
|
926
|
+
# https://docs.microsoft.com/en-us/powershell/module/exchange/client-access/Set-MailboxRegionalConfiguration
|
|
927
|
+
#
|
|
928
|
+
# Instead, search for a folder class using the localized name. If none are found, fall back to getting the
|
|
929
|
+
# folder class by the "FolderClass" value.
|
|
930
|
+
#
|
|
931
|
+
# The returned XML may contain neither folder class nor name. In that case, we default to the generic
|
|
932
|
+
# Folder class.
|
|
933
|
+
if folder.name:
|
|
934
|
+
with suppress(KeyError):
|
|
935
|
+
# TODO: fld_class.LOCALIZED_NAMES is most definitely neither complete nor authoritative
|
|
936
|
+
folder_cls = root.folder_cls_from_folder_name(
|
|
937
|
+
folder_name=folder.name,
|
|
938
|
+
folder_class=folder.folder_class,
|
|
939
|
+
locale=root.account.locale,
|
|
940
|
+
)
|
|
941
|
+
log.debug("Folder class %s matches localized folder name %s", folder_cls, folder.name)
|
|
942
|
+
if folder.folder_class and folder_cls == Folder:
|
|
943
|
+
with suppress(KeyError):
|
|
944
|
+
folder_cls = cls.folder_cls_from_container_class(container_class=folder.folder_class)
|
|
945
|
+
log.debug(
|
|
946
|
+
"Folder class %s matches container class %s (%s)", folder_cls, folder.folder_class, folder.name
|
|
947
|
+
)
|
|
948
|
+
if folder_cls == Folder:
|
|
949
|
+
log.debug("Fallback to class Folder (folder_class %s, name %s)", folder.folder_class, folder.name)
|
|
950
|
+
# Some servers return folders in a FindFolder result that have a DistinguishedFolderId element that the same
|
|
951
|
+
# server cannot handle in a GetFolder request. Only set the DistinguishedFolderId field if we recognize the ID.
|
|
952
|
+
if folder._distinguished_id and not folder_cls.DISTINGUISHED_FOLDER_ID:
|
|
953
|
+
folder._distinguished_id = None
|
|
954
|
+
return folder_cls(root=root, **{f.name: getattr(folder, f.name) for f in folder.FIELDS})
|