spluspy 2.1.13__tar.gz → 2.2.1__tar.gz
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.
- {spluspy-2.1.13 → spluspy-2.2.1}/PKG-INFO +1 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/pyproject.toml +1 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/__init__.py +2 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/__version__.py +1 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/__init__.py +25 -25
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/account.py +247 -247
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/auth.py +740 -740
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/bots.py +72 -72
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/buttons.py +101 -101
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/chats.py +1339 -1339
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/dialogs.py +614 -711
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/downloads.py +1096 -1096
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/messageparse.py +233 -233
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/messages.py +1528 -1528
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/telegrambaseclient.py +1016 -1016
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/updates.py +776 -776
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/uploads.py +867 -867
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/users.py +631 -631
- spluspy-2.2.1/spluspy/_engine/crypto/__init__.py +10 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/aes.py +101 -111
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/libssl.py +88 -7
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/errors/__init__.py +46 -46
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/__init__.py +140 -140
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/album.py +345 -345
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/callbackquery.py +345 -345
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/chataction.py +458 -458
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/common.py +186 -186
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/inlinequery.py +247 -247
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/messagedeleted.py +57 -57
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/messageedited.py +52 -52
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/messageread.py +143 -143
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/newmessage.py +223 -223
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/raw.py +53 -53
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/events/userupdate.py +310 -310
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/extensions/binaryreader.py +3 -29
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/helpers.py +1 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/connection.py +455 -455
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/tcpmtproxy.py +1 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/websocket.py +387 -423
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/mtprotosender.py +974 -1002
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/mtprotostate.py +285 -285
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/sessions/sqlite.py +1 -6
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/core/__init__.py +26 -26
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/adminlogevent.py +475 -475
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/button.py +346 -346
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/chatgetter.py +154 -154
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/conversation.py +529 -529
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/dialog.py +161 -161
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/forward.py +51 -51
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/inlinebuilder.py +450 -450
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/inlineresult.py +176 -176
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/inlineresults.py +83 -83
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/message.py +1250 -1250
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/messagebutton.py +160 -160
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/sendergetter.py +106 -106
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/utils.py +1570 -1570
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/version.py +1 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/client/client.py +9 -1
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/logger.py +115 -1
- spluspy-2.1.13/spluspy/_engine/crypto/__init__.py +0 -86
- spluspy-2.1.13/spluspy/_engine/crypto/fast_aes.pyx +0 -226
- spluspy-2.1.13/spluspy/_engine/crypto/fast_rsa.pyx +0 -312
- {spluspy-2.1.13 → spluspy-2.2.1}/.gitignore +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/CHANGELOG.md +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/CONTRIBUTING.md +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/Dockerfile +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/LICENSE +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/MANIFEST.in +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/README.md +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/README.rst +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/01_hello_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/02_echo_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/03_command_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/04_private_only.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/05_group_only.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/06_regex_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/07_user_filter.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/08_combined_filters.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/09_inline_keyboard.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/10_reply_keyboard.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/11_message_actions.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/12_media_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/13_fsm_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/14_plugin_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/15_middleware_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/16_scheduler_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/17_conversation.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/18_chat_management.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/19_event_types.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/20_sync_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/21_album_handler.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/22_download_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/23_url_button.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/24_string_session.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/25_error_handling.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/25_working_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/26_message_entities.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/27_search_messages.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/28_poll_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/29_dice_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/30_cache_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/31_reaction_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/32_mark_read_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/33_context_manager.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/34_user_info.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/35_chat_info.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/36_forward_copy.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/37_admin_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/38_media_filters.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/39_status_bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/40_delete_detection.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/41_read_detection.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/42_raw_events.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/43_poll_handler.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/44_reaction_handler.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/45_typing_handler.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/46_get_messages.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/47_iter_messages.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/48_get_members.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/49_resolve_username.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/examples/50_invoke.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/setup.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/_updates/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/_updates/entitycache.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/_updates/messagebox.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/_updates/session.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/client/soroushclient.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/aesctr.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/authkey.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/cdndecrypter.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/factorization.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/crypto/rsa.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/custom.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/errors/common.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/errors/rpcbaseerrors.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/errors/rpcerrorlist.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/extensions/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/extensions/html.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/extensions/markdown.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/extensions/messagepacker.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/functions.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/hints.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/authenticator.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/http.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/tcpabridged.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/tcpfull.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/tcpintermediate.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/connection/tcpobfuscated.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/mtprotoplainsender.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/network/requeststate.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/password.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/requestiter.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/sessions/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/sessions/abstract.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/sessions/memory.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/sessions/string.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/sync.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/alltlobjects.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/core/gzippacked.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/core/messagecontainer.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/core/rpcresult.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/core/tlmessage.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/draft.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/file.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/inputsizedfile.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/participantpermissions.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/qrlogin.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/custom/types.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/account.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/auth.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/bots.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/channels.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/chatlists.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/conference.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/contacts.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/folders.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/help.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/langpack.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/messages.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/payments.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/phone.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/photos.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/premium.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/stats.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/stories.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/thirdParty.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/updates.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/upload.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/functions/users.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/patched/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/tlobject.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/account.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/auth.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/bots.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/channels.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/chatlists.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/conference.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/contacts.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/help.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/messages.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/payments.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/phone.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/photos.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/premium.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/stats.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/stickers.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/storage.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/stories.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/thirdParty.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/update.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/updates.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/upload.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/tl/types/users.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/_engine/types.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/admin.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/afk.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/cli.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/client/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/client/chat_mixin.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/client/conversation.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/client/media_mixin.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/compat.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/config.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/errors/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/errors/exceptions.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/album.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/base.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/callback.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/chat_action.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/edited.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/inline.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/message.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/message_deleted.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/message_read.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/events/user_update.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/filters/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/filters/filters.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/fsm/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/fsm/state.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/middleware/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/middleware/base.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/middleware/rate_limit.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/mirror.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/bot.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/chat.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/enums.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/media.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/message.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/objects.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/models/user.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/client.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/connection.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/http_client.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/mtproto.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/protocols.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/spluspy_adapter.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/network/transport.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/plugins/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/plugins/loader.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/py.typed +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/scheduler/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/scheduler/scheduler.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/session/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/session/base.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/session/memory.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/session/sqlite.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/session/string.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/base.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/entity_cache.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/memory.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/postgres.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/redis.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/storage/sqlite.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/sync/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/sync/client.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/batch.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/cache.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/chat_lock.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/file_transfer.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/helpers.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/rate_limiter.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/resolver.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/spluspy/utils/version_check.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/__init__.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_client.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_filters.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_fsm.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_fsm_enhanced.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_middleware.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_rate_limiter.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_resolver.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_scheduler.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_session.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_storage.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_types.py +0 -0
- {spluspy-2.1.13 → spluspy-2.2.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spluspy
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: A modern async Python library for interacting with Soroush Plus
|
|
5
5
|
Project-URL: Homepage, https://github.com/Itskillmaster/spluspy
|
|
6
6
|
Project-URL: Documentation, https://github.com/Itskillmaster/spluspy#readme
|
|
@@ -71,6 +71,7 @@ from spluspy.network.protocols import IAdapter, ITransport, IStorage, IEventDisp
|
|
|
71
71
|
from spluspy.network.spluspy_adapter import BaseAdapter, SpluspyAdapter, TelethonAdapter, create_adapter
|
|
72
72
|
from spluspy.utils.logger import (
|
|
73
73
|
setup_logging,
|
|
74
|
+
setup_errors_only_logging,
|
|
74
75
|
get_logger,
|
|
75
76
|
set_level,
|
|
76
77
|
log,
|
|
@@ -157,6 +158,7 @@ __all__ = [
|
|
|
157
158
|
"MessageMirror",
|
|
158
159
|
"MessageScheduler",
|
|
159
160
|
"setup_logging",
|
|
161
|
+
"setup_errors_only_logging",
|
|
160
162
|
"get_logger",
|
|
161
163
|
"set_level",
|
|
162
164
|
"log",
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This package defines clients as subclasses of others, and then a single
|
|
3
|
-
`spluspy.client.soroushclient.SoroushClient` which is subclass of them
|
|
4
|
-
all to provide the final unified interface while the methods can live in
|
|
5
|
-
different subclasses to be more maintainable.
|
|
6
|
-
|
|
7
|
-
The ABC is `spluspy.client.telegrambaseclient.SoroushPlusBaseClient` and the
|
|
8
|
-
first implementor is `spluspy.client.users.UserMethods`, since calling
|
|
9
|
-
requests require them to be resolved first, and that requires accessing
|
|
10
|
-
entities (users).
|
|
11
|
-
"""
|
|
12
|
-
from .telegrambaseclient import SoroushPlusBaseClient
|
|
13
|
-
from .users import UserMethods # Required for everything
|
|
14
|
-
from .messageparse import MessageParseMethods # Required for messages
|
|
15
|
-
from .uploads import UploadMethods # Required for messages to send files
|
|
16
|
-
from .updates import UpdateMethods # Required for buttons (register callbacks)
|
|
17
|
-
from .buttons import ButtonMethods # Required for messages to use buttons
|
|
18
|
-
from .messages import MessageMethods
|
|
19
|
-
from .chats import ChatMethods
|
|
20
|
-
from .dialogs import DialogMethods
|
|
21
|
-
from .downloads import DownloadMethods
|
|
22
|
-
from .account import AccountMethods
|
|
23
|
-
from .auth import AuthMethods
|
|
24
|
-
from .bots import BotMethods
|
|
25
|
-
from .soroushclient import SoroushClient
|
|
1
|
+
"""
|
|
2
|
+
This package defines clients as subclasses of others, and then a single
|
|
3
|
+
`spluspy.client.soroushclient.SoroushClient` which is subclass of them
|
|
4
|
+
all to provide the final unified interface while the methods can live in
|
|
5
|
+
different subclasses to be more maintainable.
|
|
6
|
+
|
|
7
|
+
The ABC is `spluspy.client.telegrambaseclient.SoroushPlusBaseClient` and the
|
|
8
|
+
first implementor is `spluspy.client.users.UserMethods`, since calling
|
|
9
|
+
requests require them to be resolved first, and that requires accessing
|
|
10
|
+
entities (users).
|
|
11
|
+
"""
|
|
12
|
+
from .telegrambaseclient import SoroushPlusBaseClient
|
|
13
|
+
from .users import UserMethods # Required for everything
|
|
14
|
+
from .messageparse import MessageParseMethods # Required for messages
|
|
15
|
+
from .uploads import UploadMethods # Required for messages to send files
|
|
16
|
+
from .updates import UpdateMethods # Required for buttons (register callbacks)
|
|
17
|
+
from .buttons import ButtonMethods # Required for messages to use buttons
|
|
18
|
+
from .messages import MessageMethods
|
|
19
|
+
from .chats import ChatMethods
|
|
20
|
+
from .dialogs import DialogMethods
|
|
21
|
+
from .downloads import DownloadMethods
|
|
22
|
+
from .account import AccountMethods
|
|
23
|
+
from .auth import AuthMethods
|
|
24
|
+
from .bots import BotMethods
|
|
25
|
+
from .soroushclient import SoroushClient
|
|
@@ -1,247 +1,247 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
import inspect
|
|
3
|
-
import logging
|
|
4
|
-
import typing
|
|
5
|
-
|
|
6
|
-
from .users import _NOT_A_REQUEST
|
|
7
|
-
from .. import helpers, utils
|
|
8
|
-
from ..tl import functions, TLRequest
|
|
9
|
-
|
|
10
|
-
_log = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
if typing.TYPE_CHECKING:
|
|
13
|
-
from .soroushclient import SoroushClient
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# TODO Make use of :tl:`InvokeWithMessagesRange` somehow
|
|
17
|
-
# For that, we need to use :tl:`GetSplitRanges` first.
|
|
18
|
-
class _TakeoutClient:
|
|
19
|
-
"""
|
|
20
|
-
Proxy object over the client.
|
|
21
|
-
"""
|
|
22
|
-
__PROXY_INTERFACE = ('__enter__', '__exit__', '__aenter__', '__aexit__')
|
|
23
|
-
|
|
24
|
-
def __init__(self, finalize, client, request):
|
|
25
|
-
# We use the name mangling for attributes to make them inaccessible
|
|
26
|
-
# from within the shadowed client object and to distinguish them from
|
|
27
|
-
# its own attributes where needed.
|
|
28
|
-
self.__finalize = finalize
|
|
29
|
-
self.__client = client
|
|
30
|
-
self.__request = request
|
|
31
|
-
self.__success = None
|
|
32
|
-
|
|
33
|
-
@property
|
|
34
|
-
def success(self):
|
|
35
|
-
return self.__success
|
|
36
|
-
|
|
37
|
-
@success.setter
|
|
38
|
-
def success(self, value):
|
|
39
|
-
self.__success = value
|
|
40
|
-
|
|
41
|
-
async def __aenter__(self):
|
|
42
|
-
# Enter/Exit behaviour is "overrode", we don't want to call start.
|
|
43
|
-
client = self.__client
|
|
44
|
-
if client.session.takeout_id is None:
|
|
45
|
-
client.session.takeout_id = (await client(self.__request)).id
|
|
46
|
-
elif self.__request is not None:
|
|
47
|
-
raise ValueError("Can't send a takeout request while another "
|
|
48
|
-
"takeout for the current session still not been finished yet.")
|
|
49
|
-
return self
|
|
50
|
-
|
|
51
|
-
async def __aexit__(self, exc_type, exc_value, traceback):
|
|
52
|
-
if self.__success is None and self.__finalize:
|
|
53
|
-
self.__success = exc_type is None
|
|
54
|
-
|
|
55
|
-
if self.__success is not None:
|
|
56
|
-
result = await self(functions.account.FinishTakeoutSessionRequest(
|
|
57
|
-
self.__success))
|
|
58
|
-
if not result:
|
|
59
|
-
raise ValueError("Failed to finish the takeout.")
|
|
60
|
-
self.session.takeout_id = None
|
|
61
|
-
|
|
62
|
-
__enter__ = helpers._sync_enter
|
|
63
|
-
__exit__ = helpers._sync_exit
|
|
64
|
-
|
|
65
|
-
async def __call__(self, request, ordered=False):
|
|
66
|
-
takeout_id = self.__client.session.takeout_id
|
|
67
|
-
if takeout_id is None:
|
|
68
|
-
raise ValueError('Takeout mode has not been initialized '
|
|
69
|
-
'(are you calling outside of "with"?)')
|
|
70
|
-
|
|
71
|
-
single = not utils.is_list_like(request)
|
|
72
|
-
requests = ((request,) if single else request)
|
|
73
|
-
wrapped = []
|
|
74
|
-
for r in requests:
|
|
75
|
-
if not isinstance(r, TLRequest):
|
|
76
|
-
raise _NOT_A_REQUEST()
|
|
77
|
-
await r.resolve(self, utils)
|
|
78
|
-
wrapped.append(functions.InvokeWithTakeoutRequest(takeout_id, r))
|
|
79
|
-
|
|
80
|
-
return await self.__client(
|
|
81
|
-
wrapped[0] if single else wrapped, ordered=ordered)
|
|
82
|
-
|
|
83
|
-
def __getattribute__(self, name):
|
|
84
|
-
# We access class via type() because __class__ will recurse infinitely.
|
|
85
|
-
# Also note that since we've name-mangled our own class attributes,
|
|
86
|
-
# they'll be passed to __getattribute__() as already decorated. For
|
|
87
|
-
# example, 'self.__client' will be passed as '_TakeoutClient__client'.
|
|
88
|
-
# https://docs.python.org/3/tutorial/classes.html#private-variables
|
|
89
|
-
if name.startswith('__') and name not in type(self).__PROXY_INTERFACE:
|
|
90
|
-
raise AttributeError # force call of __getattr__
|
|
91
|
-
|
|
92
|
-
# Try to access attribute in the proxy object and check for the same
|
|
93
|
-
# attribute in the shadowed object (through our __getattr__) if failed.
|
|
94
|
-
return super().__getattribute__(name)
|
|
95
|
-
|
|
96
|
-
def __getattr__(self, name):
|
|
97
|
-
value = getattr(self.__client, name)
|
|
98
|
-
if inspect.ismethod(value):
|
|
99
|
-
# Emulate bound methods behavior by partially applying our proxy
|
|
100
|
-
# class as the self parameter instead of the client.
|
|
101
|
-
return functools.partial(
|
|
102
|
-
getattr(self.__client.__class__, name), self)
|
|
103
|
-
|
|
104
|
-
return value
|
|
105
|
-
|
|
106
|
-
def __setattr__(self, name, value):
|
|
107
|
-
if name.startswith('_{}__'.format(type(self).__name__.lstrip('_'))):
|
|
108
|
-
# This is our own name-mangled attribute, keep calm.
|
|
109
|
-
return super().__setattr__(name, value)
|
|
110
|
-
return setattr(self.__client, name, value)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
class AccountMethods:
|
|
114
|
-
def takeout(
|
|
115
|
-
self: 'SoroushClient',
|
|
116
|
-
finalize: bool = True,
|
|
117
|
-
*,
|
|
118
|
-
contacts: bool = None,
|
|
119
|
-
users: bool = None,
|
|
120
|
-
chats: bool = None,
|
|
121
|
-
megagroups: bool = None,
|
|
122
|
-
channels: bool = None,
|
|
123
|
-
files: bool = None,
|
|
124
|
-
max_file_size: bool = None) -> 'SoroushClient':
|
|
125
|
-
"""
|
|
126
|
-
Returns a :ref:`spluspy-client` which calls methods behind a takeout session.
|
|
127
|
-
|
|
128
|
-
It does so by creating a proxy object over the current client through
|
|
129
|
-
which making requests will use :tl:`InvokeWithTakeoutRequest` to wrap
|
|
130
|
-
them. In other words, returns the current client modified so that
|
|
131
|
-
requests are done as a takeout:
|
|
132
|
-
|
|
133
|
-
Some of the calls made through the takeout session will have lower
|
|
134
|
-
flood limits. This is useful if you want to export the data from
|
|
135
|
-
conversations or mass-download media, since the rate limits will
|
|
136
|
-
be lower. Only some requests will be affected, and you will need
|
|
137
|
-
to adjust the `wait_time` of methods like `client.iter_messages
|
|
138
|
-
<spluspy.client.messages.MessageMethods.iter_messages>`.
|
|
139
|
-
|
|
140
|
-
By default, all parameters are `None`, and you need to enable those
|
|
141
|
-
you plan to use by setting them to either `True` or `False`.
|
|
142
|
-
|
|
143
|
-
You should ``except errors.TakeoutInitDelayError as e``, since this
|
|
144
|
-
exception will raise depending on the condition of the session. You
|
|
145
|
-
can then access ``e.seconds`` to know how long you should wait for
|
|
146
|
-
before calling the method again.
|
|
147
|
-
|
|
148
|
-
There's also a `success` property available in the takeout proxy
|
|
149
|
-
object, so from the `with` body you can set the boolean result that
|
|
150
|
-
will be sent back to SoroushPlus. But if it's left `None` as by
|
|
151
|
-
default, then the action is based on the `finalize` parameter. If
|
|
152
|
-
it's `True` then the takeout will be finished, and if no exception
|
|
153
|
-
occurred during it, then `True` will be considered as a result.
|
|
154
|
-
Otherwise, the takeout will not be finished and its ID will be
|
|
155
|
-
preserved for future usage as `client.session.takeout_id
|
|
156
|
-
<spluspy.sessions.abstract.Session.takeout_id>`.
|
|
157
|
-
|
|
158
|
-
Arguments
|
|
159
|
-
finalize (`bool`):
|
|
160
|
-
Whether the takeout session should be finalized upon
|
|
161
|
-
exit or not.
|
|
162
|
-
|
|
163
|
-
contacts (`bool`):
|
|
164
|
-
Set to `True` if you plan on downloading contacts.
|
|
165
|
-
|
|
166
|
-
users (`bool`):
|
|
167
|
-
Set to `True` if you plan on downloading information
|
|
168
|
-
from users and their private conversations with you.
|
|
169
|
-
|
|
170
|
-
chats (`bool`):
|
|
171
|
-
Set to `True` if you plan on downloading information
|
|
172
|
-
from small group chats, such as messages and media.
|
|
173
|
-
|
|
174
|
-
megagroups (`bool`):
|
|
175
|
-
Set to `True` if you plan on downloading information
|
|
176
|
-
from megagroups (channels), such as messages and media.
|
|
177
|
-
|
|
178
|
-
channels (`bool`):
|
|
179
|
-
Set to `True` if you plan on downloading information
|
|
180
|
-
from broadcast channels, such as messages and media.
|
|
181
|
-
|
|
182
|
-
files (`bool`):
|
|
183
|
-
Set to `True` if you plan on downloading media and
|
|
184
|
-
you don't only wish to export messages.
|
|
185
|
-
|
|
186
|
-
max_file_size (`int`):
|
|
187
|
-
The maximum file size, in bytes, that you plan
|
|
188
|
-
to download for each message with media.
|
|
189
|
-
|
|
190
|
-
Example
|
|
191
|
-
.. code-block:: python
|
|
192
|
-
|
|
193
|
-
from spluspy
|
|
194
|
-
|
|
195
|
-
try:
|
|
196
|
-
async with client.takeout() as takeout:
|
|
197
|
-
await client.get_messages('me') # normal call
|
|
198
|
-
await takeout.get_messages('me') # wrapped through takeout (less limits)
|
|
199
|
-
|
|
200
|
-
async for message in takeout.iter_messages(chat, wait_time=0):
|
|
201
|
-
... # Do something with the message
|
|
202
|
-
|
|
203
|
-
except errors.TakeoutInitDelayError as e:
|
|
204
|
-
print('Must wait', e.seconds, 'before takeout')
|
|
205
|
-
"""
|
|
206
|
-
request_kwargs = dict(
|
|
207
|
-
contacts=contacts,
|
|
208
|
-
message_users=users,
|
|
209
|
-
message_chats=chats,
|
|
210
|
-
message_megagroups=megagroups,
|
|
211
|
-
message_channels=channels,
|
|
212
|
-
files=files,
|
|
213
|
-
file_max_size=max_file_size
|
|
214
|
-
)
|
|
215
|
-
arg_specified = (arg is not None for arg in request_kwargs.values())
|
|
216
|
-
|
|
217
|
-
if self.session.takeout_id is None or any(arg_specified):
|
|
218
|
-
request = functions.account.InitTakeoutSessionRequest(
|
|
219
|
-
**request_kwargs)
|
|
220
|
-
else:
|
|
221
|
-
request = None
|
|
222
|
-
|
|
223
|
-
return _TakeoutClient(finalize, self, request)
|
|
224
|
-
|
|
225
|
-
async def end_takeout(self: 'SoroushClient', success: bool) -> bool:
|
|
226
|
-
"""
|
|
227
|
-
Finishes the current takeout session.
|
|
228
|
-
|
|
229
|
-
Arguments
|
|
230
|
-
success (`bool`):
|
|
231
|
-
Whether the takeout completed successfully or not.
|
|
232
|
-
|
|
233
|
-
Returns
|
|
234
|
-
`True` if the operation was successful, `False` otherwise.
|
|
235
|
-
|
|
236
|
-
Example
|
|
237
|
-
.. code-block:: python
|
|
238
|
-
|
|
239
|
-
await client.end_takeout(success=False)
|
|
240
|
-
"""
|
|
241
|
-
try:
|
|
242
|
-
async with _TakeoutClient(True, self, None) as takeout:
|
|
243
|
-
takeout.success = success
|
|
244
|
-
except ValueError as e:
|
|
245
|
-
_log.debug('Failed to end takeout: %s', e)
|
|
246
|
-
return False
|
|
247
|
-
return True
|
|
1
|
+
import functools
|
|
2
|
+
import inspect
|
|
3
|
+
import logging
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
from .users import _NOT_A_REQUEST
|
|
7
|
+
from .. import helpers, utils
|
|
8
|
+
from ..tl import functions, TLRequest
|
|
9
|
+
|
|
10
|
+
_log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
if typing.TYPE_CHECKING:
|
|
13
|
+
from .soroushclient import SoroushClient
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# TODO Make use of :tl:`InvokeWithMessagesRange` somehow
|
|
17
|
+
# For that, we need to use :tl:`GetSplitRanges` first.
|
|
18
|
+
class _TakeoutClient:
|
|
19
|
+
"""
|
|
20
|
+
Proxy object over the client.
|
|
21
|
+
"""
|
|
22
|
+
__PROXY_INTERFACE = ('__enter__', '__exit__', '__aenter__', '__aexit__')
|
|
23
|
+
|
|
24
|
+
def __init__(self, finalize, client, request):
|
|
25
|
+
# We use the name mangling for attributes to make them inaccessible
|
|
26
|
+
# from within the shadowed client object and to distinguish them from
|
|
27
|
+
# its own attributes where needed.
|
|
28
|
+
self.__finalize = finalize
|
|
29
|
+
self.__client = client
|
|
30
|
+
self.__request = request
|
|
31
|
+
self.__success = None
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def success(self):
|
|
35
|
+
return self.__success
|
|
36
|
+
|
|
37
|
+
@success.setter
|
|
38
|
+
def success(self, value):
|
|
39
|
+
self.__success = value
|
|
40
|
+
|
|
41
|
+
async def __aenter__(self):
|
|
42
|
+
# Enter/Exit behaviour is "overrode", we don't want to call start.
|
|
43
|
+
client = self.__client
|
|
44
|
+
if client.session.takeout_id is None:
|
|
45
|
+
client.session.takeout_id = (await client(self.__request)).id
|
|
46
|
+
elif self.__request is not None:
|
|
47
|
+
raise ValueError("Can't send a takeout request while another "
|
|
48
|
+
"takeout for the current session still not been finished yet.")
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
async def __aexit__(self, exc_type, exc_value, traceback):
|
|
52
|
+
if self.__success is None and self.__finalize:
|
|
53
|
+
self.__success = exc_type is None
|
|
54
|
+
|
|
55
|
+
if self.__success is not None:
|
|
56
|
+
result = await self(functions.account.FinishTakeoutSessionRequest(
|
|
57
|
+
self.__success))
|
|
58
|
+
if not result:
|
|
59
|
+
raise ValueError("Failed to finish the takeout.")
|
|
60
|
+
self.session.takeout_id = None
|
|
61
|
+
|
|
62
|
+
__enter__ = helpers._sync_enter
|
|
63
|
+
__exit__ = helpers._sync_exit
|
|
64
|
+
|
|
65
|
+
async def __call__(self, request, ordered=False):
|
|
66
|
+
takeout_id = self.__client.session.takeout_id
|
|
67
|
+
if takeout_id is None:
|
|
68
|
+
raise ValueError('Takeout mode has not been initialized '
|
|
69
|
+
'(are you calling outside of "with"?)')
|
|
70
|
+
|
|
71
|
+
single = not utils.is_list_like(request)
|
|
72
|
+
requests = ((request,) if single else request)
|
|
73
|
+
wrapped = []
|
|
74
|
+
for r in requests:
|
|
75
|
+
if not isinstance(r, TLRequest):
|
|
76
|
+
raise _NOT_A_REQUEST()
|
|
77
|
+
await r.resolve(self, utils)
|
|
78
|
+
wrapped.append(functions.InvokeWithTakeoutRequest(takeout_id, r))
|
|
79
|
+
|
|
80
|
+
return await self.__client(
|
|
81
|
+
wrapped[0] if single else wrapped, ordered=ordered)
|
|
82
|
+
|
|
83
|
+
def __getattribute__(self, name):
|
|
84
|
+
# We access class via type() because __class__ will recurse infinitely.
|
|
85
|
+
# Also note that since we've name-mangled our own class attributes,
|
|
86
|
+
# they'll be passed to __getattribute__() as already decorated. For
|
|
87
|
+
# example, 'self.__client' will be passed as '_TakeoutClient__client'.
|
|
88
|
+
# https://docs.python.org/3/tutorial/classes.html#private-variables
|
|
89
|
+
if name.startswith('__') and name not in type(self).__PROXY_INTERFACE:
|
|
90
|
+
raise AttributeError # force call of __getattr__
|
|
91
|
+
|
|
92
|
+
# Try to access attribute in the proxy object and check for the same
|
|
93
|
+
# attribute in the shadowed object (through our __getattr__) if failed.
|
|
94
|
+
return super().__getattribute__(name)
|
|
95
|
+
|
|
96
|
+
def __getattr__(self, name):
|
|
97
|
+
value = getattr(self.__client, name)
|
|
98
|
+
if inspect.ismethod(value):
|
|
99
|
+
# Emulate bound methods behavior by partially applying our proxy
|
|
100
|
+
# class as the self parameter instead of the client.
|
|
101
|
+
return functools.partial(
|
|
102
|
+
getattr(self.__client.__class__, name), self)
|
|
103
|
+
|
|
104
|
+
return value
|
|
105
|
+
|
|
106
|
+
def __setattr__(self, name, value):
|
|
107
|
+
if name.startswith('_{}__'.format(type(self).__name__.lstrip('_'))):
|
|
108
|
+
# This is our own name-mangled attribute, keep calm.
|
|
109
|
+
return super().__setattr__(name, value)
|
|
110
|
+
return setattr(self.__client, name, value)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class AccountMethods:
|
|
114
|
+
def takeout(
|
|
115
|
+
self: 'SoroushClient',
|
|
116
|
+
finalize: bool = True,
|
|
117
|
+
*,
|
|
118
|
+
contacts: bool = None,
|
|
119
|
+
users: bool = None,
|
|
120
|
+
chats: bool = None,
|
|
121
|
+
megagroups: bool = None,
|
|
122
|
+
channels: bool = None,
|
|
123
|
+
files: bool = None,
|
|
124
|
+
max_file_size: bool = None) -> 'SoroushClient':
|
|
125
|
+
"""
|
|
126
|
+
Returns a :ref:`spluspy-client` which calls methods behind a takeout session.
|
|
127
|
+
|
|
128
|
+
It does so by creating a proxy object over the current client through
|
|
129
|
+
which making requests will use :tl:`InvokeWithTakeoutRequest` to wrap
|
|
130
|
+
them. In other words, returns the current client modified so that
|
|
131
|
+
requests are done as a takeout:
|
|
132
|
+
|
|
133
|
+
Some of the calls made through the takeout session will have lower
|
|
134
|
+
flood limits. This is useful if you want to export the data from
|
|
135
|
+
conversations or mass-download media, since the rate limits will
|
|
136
|
+
be lower. Only some requests will be affected, and you will need
|
|
137
|
+
to adjust the `wait_time` of methods like `client.iter_messages
|
|
138
|
+
<spluspy.client.messages.MessageMethods.iter_messages>`.
|
|
139
|
+
|
|
140
|
+
By default, all parameters are `None`, and you need to enable those
|
|
141
|
+
you plan to use by setting them to either `True` or `False`.
|
|
142
|
+
|
|
143
|
+
You should ``except errors.TakeoutInitDelayError as e``, since this
|
|
144
|
+
exception will raise depending on the condition of the session. You
|
|
145
|
+
can then access ``e.seconds`` to know how long you should wait for
|
|
146
|
+
before calling the method again.
|
|
147
|
+
|
|
148
|
+
There's also a `success` property available in the takeout proxy
|
|
149
|
+
object, so from the `with` body you can set the boolean result that
|
|
150
|
+
will be sent back to SoroushPlus. But if it's left `None` as by
|
|
151
|
+
default, then the action is based on the `finalize` parameter. If
|
|
152
|
+
it's `True` then the takeout will be finished, and if no exception
|
|
153
|
+
occurred during it, then `True` will be considered as a result.
|
|
154
|
+
Otherwise, the takeout will not be finished and its ID will be
|
|
155
|
+
preserved for future usage as `client.session.takeout_id
|
|
156
|
+
<spluspy.sessions.abstract.Session.takeout_id>`.
|
|
157
|
+
|
|
158
|
+
Arguments
|
|
159
|
+
finalize (`bool`):
|
|
160
|
+
Whether the takeout session should be finalized upon
|
|
161
|
+
exit or not.
|
|
162
|
+
|
|
163
|
+
contacts (`bool`):
|
|
164
|
+
Set to `True` if you plan on downloading contacts.
|
|
165
|
+
|
|
166
|
+
users (`bool`):
|
|
167
|
+
Set to `True` if you plan on downloading information
|
|
168
|
+
from users and their private conversations with you.
|
|
169
|
+
|
|
170
|
+
chats (`bool`):
|
|
171
|
+
Set to `True` if you plan on downloading information
|
|
172
|
+
from small group chats, such as messages and media.
|
|
173
|
+
|
|
174
|
+
megagroups (`bool`):
|
|
175
|
+
Set to `True` if you plan on downloading information
|
|
176
|
+
from megagroups (channels), such as messages and media.
|
|
177
|
+
|
|
178
|
+
channels (`bool`):
|
|
179
|
+
Set to `True` if you plan on downloading information
|
|
180
|
+
from broadcast channels, such as messages and media.
|
|
181
|
+
|
|
182
|
+
files (`bool`):
|
|
183
|
+
Set to `True` if you plan on downloading media and
|
|
184
|
+
you don't only wish to export messages.
|
|
185
|
+
|
|
186
|
+
max_file_size (`int`):
|
|
187
|
+
The maximum file size, in bytes, that you plan
|
|
188
|
+
to download for each message with media.
|
|
189
|
+
|
|
190
|
+
Example
|
|
191
|
+
.. code-block:: python
|
|
192
|
+
|
|
193
|
+
from spluspy import errors
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
async with client.takeout() as takeout:
|
|
197
|
+
await client.get_messages('me') # normal call
|
|
198
|
+
await takeout.get_messages('me') # wrapped through takeout (less limits)
|
|
199
|
+
|
|
200
|
+
async for message in takeout.iter_messages(chat, wait_time=0):
|
|
201
|
+
... # Do something with the message
|
|
202
|
+
|
|
203
|
+
except errors.TakeoutInitDelayError as e:
|
|
204
|
+
print('Must wait', e.seconds, 'before takeout')
|
|
205
|
+
"""
|
|
206
|
+
request_kwargs = dict(
|
|
207
|
+
contacts=contacts,
|
|
208
|
+
message_users=users,
|
|
209
|
+
message_chats=chats,
|
|
210
|
+
message_megagroups=megagroups,
|
|
211
|
+
message_channels=channels,
|
|
212
|
+
files=files,
|
|
213
|
+
file_max_size=max_file_size
|
|
214
|
+
)
|
|
215
|
+
arg_specified = (arg is not None for arg in request_kwargs.values())
|
|
216
|
+
|
|
217
|
+
if self.session.takeout_id is None or any(arg_specified):
|
|
218
|
+
request = functions.account.InitTakeoutSessionRequest(
|
|
219
|
+
**request_kwargs)
|
|
220
|
+
else:
|
|
221
|
+
request = None
|
|
222
|
+
|
|
223
|
+
return _TakeoutClient(finalize, self, request)
|
|
224
|
+
|
|
225
|
+
async def end_takeout(self: 'SoroushClient', success: bool) -> bool:
|
|
226
|
+
"""
|
|
227
|
+
Finishes the current takeout session.
|
|
228
|
+
|
|
229
|
+
Arguments
|
|
230
|
+
success (`bool`):
|
|
231
|
+
Whether the takeout completed successfully or not.
|
|
232
|
+
|
|
233
|
+
Returns
|
|
234
|
+
`True` if the operation was successful, `False` otherwise.
|
|
235
|
+
|
|
236
|
+
Example
|
|
237
|
+
.. code-block:: python
|
|
238
|
+
|
|
239
|
+
await client.end_takeout(success=False)
|
|
240
|
+
"""
|
|
241
|
+
try:
|
|
242
|
+
async with _TakeoutClient(True, self, None) as takeout:
|
|
243
|
+
takeout.success = success
|
|
244
|
+
except ValueError as e:
|
|
245
|
+
_log.debug('Failed to end takeout: %s', e)
|
|
246
|
+
return False
|
|
247
|
+
return True
|