darkob 0.2.0__py3-none-any.whl
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.
- darkob/TheBot.py +114 -0
- darkob/TheClient.py +234 -0
- darkob/__init__.py +169 -0
- darkob/bot/__init__.py +86 -0
- darkob/bot/auto_delete_message.py +24 -0
- darkob/bot/ban_member.py +37 -0
- darkob/bot/bot_status.py +31 -0
- darkob/bot/bridge.py +97 -0
- darkob/bot/callback.py +24 -0
- darkob/bot/command.py +37 -0
- darkob/bot/delete_message.py +36 -0
- darkob/bot/download_file.py +186 -0
- darkob/bot/edit_chat_keypad.py +84 -0
- darkob/bot/edit_inline_keypad.py +87 -0
- darkob/bot/edit_message.py +67 -0
- darkob/bot/event_data.py +46 -0
- darkob/bot/exceptions.py +93 -0
- darkob/bot/file_extensions.py +205 -0
- darkob/bot/filters.py +523 -0
- darkob/bot/forward_message.py +60 -0
- darkob/bot/get_chat_info.py +22 -0
- darkob/bot/get_chat_member.py +37 -0
- darkob/bot/get_file.py +12 -0
- darkob/bot/get_me.py +11 -0
- darkob/bot/get_token_string.py +23 -0
- darkob/bot/get_updates.py +27 -0
- darkob/bot/keypad_mixin.py +131 -0
- darkob/bot/lifecycle.py +27 -0
- darkob/bot/member_is_admin.py +24 -0
- darkob/bot/member_is_joined.py +24 -0
- darkob/bot/member_is_owner.py +24 -0
- darkob/bot/message.py +77 -0
- darkob/bot/message_result.py +40 -0
- darkob/bot/metadata.py +175 -0
- darkob/bot/middleware.py +25 -0
- darkob/bot/plugin.py +541 -0
- darkob/bot/register_all_endpoints.py +45 -0
- darkob/bot/registry.py +143 -0
- darkob/bot/remove_chat_keypad.py +24 -0
- darkob/bot/remove_member.py +32 -0
- darkob/bot/request.py +113 -0
- darkob/bot/request_send_file.py +42 -0
- darkob/bot/run.py +45 -0
- darkob/bot/send_contact.py +83 -0
- darkob/bot/send_file.py +136 -0
- darkob/bot/send_gif.py +54 -0
- darkob/bot/send_image.py +54 -0
- darkob/bot/send_location.py +87 -0
- darkob/bot/send_message.py +88 -0
- darkob/bot/send_music.py +54 -0
- darkob/bot/send_poll.py +102 -0
- darkob/bot/send_quiz.py +134 -0
- darkob/bot/send_video.py +54 -0
- darkob/bot/send_voice.py +54 -0
- darkob/bot/session.py +97 -0
- darkob/bot/set_commands.py +55 -0
- darkob/bot/start.py +142 -0
- darkob/bot/token.py +79 -0
- darkob/bot/unban_member.py +37 -0
- darkob/bot/update_bot_endpoints.py +56 -0
- darkob/bot/updates.py +39 -0
- darkob/bot/upload_file.py +134 -0
- darkob/client/__init__.py +31 -0
- darkob/client/base/__init__.py +26 -0
- darkob/client/base/connect.py +28 -0
- darkob/client/base/disconnect.py +41 -0
- darkob/client/base/download_file.py +170 -0
- darkob/client/base/get_string_session.py +33 -0
- darkob/client/base/get_updates.py +101 -0
- darkob/client/base/request.py +108 -0
- darkob/client/base/run.py +19 -0
- darkob/client/base/send_code.py +30 -0
- darkob/client/base/sign_in.py +32 -0
- darkob/client/base/start.py +288 -0
- darkob/client/base/upload_file.py +173 -0
- darkob/client/bots/__init__.py +18 -0
- darkob/client/bots/delete_bot_chat.py +40 -0
- darkob/client/bots/delete_service_chat.py +38 -0
- darkob/client/bots/get_bot_info.py +21 -0
- darkob/client/bots/get_inline_bots.py +35 -0
- darkob/client/bots/get_service_info.py +18 -0
- darkob/client/bots/start_bot.py +19 -0
- darkob/client/bots/stop_bot.py +19 -0
- darkob/client/channels/__init__.py +44 -0
- darkob/client/channels/check_channel_username.py +17 -0
- darkob/client/channels/create_channel.py +100 -0
- darkob/client/channels/delete_channel.py +46 -0
- darkob/client/channels/edit_channel_info.py +101 -0
- darkob/client/channels/edit_channel_title.py +19 -0
- darkob/client/channels/get_channel_admin_access.py +35 -0
- darkob/client/channels/get_channel_admins.py +72 -0
- darkob/client/channels/get_channel_info.py +21 -0
- darkob/client/channels/get_channel_link.py +21 -0
- darkob/client/channels/get_channel_members.py +36 -0
- darkob/client/channels/get_channel_post_by_link.py +105 -0
- darkob/client/channels/get_channel_seen_count.py +36 -0
- darkob/client/channels/get_channel_statistics.py +27 -0
- darkob/client/channels/get_post_by_ask_link.py +90 -0
- darkob/client/channels/join_channel.py +33 -0
- darkob/client/channels/leave_channel.py +24 -0
- darkob/client/channels/seen_channel_messages.py +36 -0
- darkob/client/channels/set_channel_link.py +21 -0
- darkob/client/channels/set_channel_type.py +20 -0
- darkob/client/channels/update_channel_username.py +58 -0
- darkob/client/chats/__init__.py +162 -0
- darkob/client/chats/accept_all_join_requests.py +72 -0
- darkob/client/chats/accept_join_request.py +40 -0
- darkob/client/chats/accept_ownership_request.py +30 -0
- darkob/client/chats/add_members.py +59 -0
- darkob/client/chats/archive_chat.py +22 -0
- darkob/client/chats/ban_member.py +49 -0
- darkob/client/chats/ban_members.py +24 -0
- darkob/client/chats/cancel_change_owner.py +27 -0
- darkob/client/chats/change_owner.py +43 -0
- darkob/client/chats/check_join.py +108 -0
- darkob/client/chats/clear_all_drafts.py +11 -0
- darkob/client/chats/clear_black_list.py +68 -0
- darkob/client/chats/clear_chat_draft.py +25 -0
- darkob/client/chats/click_chat_ads.py +25 -0
- darkob/client/chats/click_keypad_button.py +70 -0
- darkob/client/chats/create_join_link.py +47 -0
- darkob/client/chats/delete_all_avatars.py +47 -0
- darkob/client/chats/delete_avatar.py +35 -0
- darkob/client/chats/delete_chat_history.py +36 -0
- darkob/client/chats/discard_voice_chat.py +40 -0
- darkob/client/chats/dont_show_chat_ads.py +25 -0
- darkob/client/chats/download_profile_picture.py +176 -0
- darkob/client/chats/edit_join_link.py +71 -0
- darkob/client/chats/get_all_drafts.py +11 -0
- darkob/client/chats/get_avatars.py +20 -0
- darkob/client/chats/get_banned_members.py +70 -0
- darkob/client/chats/get_chat_ads.py +19 -0
- darkob/client/chats/get_chat_info.py +66 -0
- darkob/client/chats/get_chat_voice_chat.py +40 -0
- darkob/client/chats/get_chats.py +65 -0
- darkob/client/chats/get_chats_info.py +30 -0
- darkob/client/chats/get_chats_updates.py +23 -0
- darkob/client/chats/get_guid.py +78 -0
- darkob/client/chats/get_info_by_link.py +47 -0
- darkob/client/chats/get_info_by_username.py +39 -0
- darkob/client/chats/get_join_links.py +32 -0
- darkob/client/chats/get_join_requests.py +77 -0
- darkob/client/chats/get_my_guid.py +11 -0
- darkob/client/chats/get_pending_owner.py +25 -0
- darkob/client/chats/get_profile_link_items.py +16 -0
- darkob/client/chats/get_related_chats.py +16 -0
- darkob/client/chats/get_voice_chat_participants.py +88 -0
- darkob/client/chats/get_voice_chat_updates.py +50 -0
- darkob/client/chats/join_chat.py +24 -0
- darkob/client/chats/join_voice_chat.py +63 -0
- darkob/client/chats/leave_chat.py +24 -0
- darkob/client/chats/leave_voice_chat.py +40 -0
- darkob/client/chats/member_is_admin.py +37 -0
- darkob/client/chats/mute_chat.py +41 -0
- darkob/client/chats/pin_chat.py +19 -0
- darkob/client/chats/pin_chat_in_folder.py +29 -0
- darkob/client/chats/play_voice_chat.py +172 -0
- darkob/client/chats/reject_join_request.py +40 -0
- darkob/client/chats/reject_ownership_request.py +27 -0
- darkob/client/chats/report_chat.py +70 -0
- darkob/client/chats/report_chat_ads.py +26 -0
- darkob/client/chats/revoke_join_link.py +35 -0
- darkob/client/chats/search_global_chats.py +46 -0
- darkob/client/chats/seen_chats.py +14 -0
- darkob/client/chats/send_chat_activity.py +36 -0
- darkob/client/chats/send_voice_chat_activity.py +51 -0
- darkob/client/chats/set_admin.py +89 -0
- darkob/client/chats/set_ask_spam.py +55 -0
- darkob/client/chats/set_chat_auto_delete.py +46 -0
- darkob/client/chats/set_chat_protected_content.py +30 -0
- darkob/client/chats/set_chat_use_time.py +30 -0
- darkob/client/chats/set_voice_chat_setting.py +58 -0
- darkob/client/chats/set_voice_chat_state.py +48 -0
- darkob/client/chats/start_voice_chat.py +24 -0
- darkob/client/chats/unarchive_chat.py +19 -0
- darkob/client/chats/unban_all_members.py +68 -0
- darkob/client/chats/unban_member.py +49 -0
- darkob/client/chats/unban_members.py +24 -0
- darkob/client/chats/unmute_chat.py +19 -0
- darkob/client/chats/unpin_chat.py +19 -0
- darkob/client/chats/unpin_chat_in_folder.py +29 -0
- darkob/client/chats/unset_admin.py +51 -0
- darkob/client/chats/upload_avatar.py +73 -0
- darkob/client/chats/view_chat_ads.py +25 -0
- darkob/client/core/__init__.py +8 -0
- darkob/client/core/api.py +376 -0
- darkob/client/core/cipher.py +128 -0
- darkob/client/core/configs.py +142 -0
- darkob/client/core/handler_manager.py +17 -0
- darkob/client/core/handlers.py +87 -0
- darkob/client/core/media.py +276 -0
- darkob/client/core/metadata.py +180 -0
- darkob/client/core/session.py +308 -0
- darkob/client/decorators/__init__.py +38 -0
- darkob/client/decorators/on_add_reaction.py +37 -0
- darkob/client/decorators/on_call_signal.py +23 -0
- darkob/client/decorators/on_call_update.py +23 -0
- darkob/client/decorators/on_chat_updates.py +23 -0
- darkob/client/decorators/on_delete_message.py +32 -0
- darkob/client/decorators/on_draft_message.py +23 -0
- darkob/client/decorators/on_edit_message.py +32 -0
- darkob/client/decorators/on_message.py +12 -0
- darkob/client/decorators/on_new_message.py +32 -0
- darkob/client/decorators/on_remove_notifications.py +21 -0
- darkob/client/decorators/on_remove_reaction.py +37 -0
- darkob/client/decorators/on_scheduled_message.py +23 -0
- darkob/client/decorators/on_show_activities.py +23 -0
- darkob/client/decorators/on_show_notifications.py +23 -0
- darkob/client/decorators/on_unconfirmed_session.py +23 -0
- darkob/client/decorators/on_voice_chat_participant.py +23 -0
- darkob/client/decorators/on_voice_chat_update.py +17 -0
- darkob/client/enums.py +94 -0
- darkob/client/exceptions.py +249 -0
- darkob/client/extras/__init__.py +64 -0
- darkob/client/extras/add_live_comment.py +28 -0
- darkob/client/extras/add_sticker_set.py +23 -0
- darkob/client/extras/add_to_my_gif_set.py +25 -0
- darkob/client/extras/archive_sticker_set.py +23 -0
- darkob/client/extras/delete_all_my_gif_set.py +35 -0
- darkob/client/extras/delete_my_gif_set.py +14 -0
- darkob/client/extras/delete_sticker_set.py +19 -0
- darkob/client/extras/feedback_voice_transcription.py +46 -0
- darkob/client/extras/get_available_reactions.py +11 -0
- darkob/client/extras/get_link_from_app_url.py +20 -0
- darkob/client/extras/get_live_comments.py +25 -0
- darkob/client/extras/get_live_play_url.py +25 -0
- darkob/client/extras/get_live_status.py +25 -0
- darkob/client/extras/get_location_view.py +40 -0
- darkob/client/extras/get_my_archived_sticker_sets.py +24 -0
- darkob/client/extras/get_my_gif_set.py +11 -0
- darkob/client/extras/get_my_sticker_sets.py +11 -0
- darkob/client/extras/get_sticker_set_by_id.py +17 -0
- darkob/client/extras/get_sticker_setting.py +11 -0
- darkob/client/extras/get_stickers_by_emoji.py +22 -0
- darkob/client/extras/get_stickers_by_set_ids.py +21 -0
- darkob/client/extras/get_time.py +11 -0
- darkob/client/extras/get_trend_sticker_sets.py +17 -0
- darkob/client/extras/get_wallet_transaction_message.py +25 -0
- darkob/client/extras/get_wallpapers.py +11 -0
- darkob/client/extras/reorder_sticker_sets.py +28 -0
- darkob/client/extras/report_live.py +68 -0
- darkob/client/extras/reset_wallpapers.py +11 -0
- darkob/client/extras/search_stickers.py +21 -0
- darkob/client/extras/set_current_live_location.py +42 -0
- darkob/client/filters.py +502 -0
- darkob/client/groups/__init__.py +48 -0
- darkob/client/groups/create_group.py +96 -0
- darkob/client/groups/delete_group.py +46 -0
- darkob/client/groups/edit_group_info.py +198 -0
- darkob/client/groups/edit_group_timer.py +18 -0
- darkob/client/groups/edit_group_title.py +19 -0
- darkob/client/groups/edit_slow_mode.py +18 -0
- darkob/client/groups/get_group_admin_access.py +35 -0
- darkob/client/groups/get_group_admins.py +72 -0
- darkob/client/groups/get_group_default_access.py +21 -0
- darkob/client/groups/get_group_info.py +21 -0
- darkob/client/groups/get_group_link.py +21 -0
- darkob/client/groups/get_group_members.py +36 -0
- darkob/client/groups/get_group_mention_list.py +29 -0
- darkob/client/groups/get_group_message_read_participants.py +33 -0
- darkob/client/groups/get_group_online_count.py +21 -0
- darkob/client/groups/get_unread_mentions.py +43 -0
- darkob/client/groups/join_group.py +25 -0
- darkob/client/groups/leave_group.py +21 -0
- darkob/client/groups/lock_group.py +32 -0
- darkob/client/groups/set_group_default_access.py +49 -0
- darkob/client/groups/set_group_link.py +21 -0
- darkob/client/groups/unlock_group.py +32 -0
- darkob/client/messages/__init__.py +124 -0
- darkob/client/messages/add_reaction.py +32 -0
- darkob/client/messages/auto_delete_message.py +27 -0
- darkob/client/messages/click_inline_button.py +43 -0
- darkob/client/messages/click_message_url.py +31 -0
- darkob/client/messages/delete_all_messages.py +79 -0
- darkob/client/messages/delete_messages.py +62 -0
- darkob/client/messages/delete_my_messages.py +58 -0
- darkob/client/messages/edit_message.py +47 -0
- darkob/client/messages/forward_messages.py +90 -0
- darkob/client/messages/get_all_messages.py +75 -0
- darkob/client/messages/get_chat_messages.py +124 -0
- darkob/client/messages/get_first_message.py +33 -0
- darkob/client/messages/get_first_messages.py +54 -0
- darkob/client/messages/get_last_message.py +32 -0
- darkob/client/messages/get_last_messages.py +64 -0
- darkob/client/messages/get_message_info.py +32 -0
- darkob/client/messages/get_message_url.py +28 -0
- darkob/client/messages/get_messages.py +223 -0
- darkob/client/messages/get_messages_by_id.py +64 -0
- darkob/client/messages/get_messages_interval.py +28 -0
- darkob/client/messages/get_messages_reactions.py +31 -0
- darkob/client/messages/get_messages_updates.py +28 -0
- darkob/client/messages/get_pinned_messages.py +37 -0
- darkob/client/messages/get_poll_option_voters.py +27 -0
- darkob/client/messages/get_poll_status.py +14 -0
- darkob/client/messages/get_scheduled_messages.py +29 -0
- darkob/client/messages/mark_as_read.py +24 -0
- darkob/client/messages/mark_as_seen.py +25 -0
- darkob/client/messages/message_result.py +30 -0
- darkob/client/messages/pin_message.py +29 -0
- darkob/client/messages/remove_reaction.py +32 -0
- darkob/client/messages/report_message.py +73 -0
- darkob/client/messages/request_send_file.py +27 -0
- darkob/client/messages/retract_poll.py +23 -0
- darkob/client/messages/search_chat_messages.py +38 -0
- darkob/client/messages/search_global_messages.py +33 -0
- darkob/client/messages/search_messages.py +42 -0
- darkob/client/messages/send_contact.py +62 -0
- darkob/client/messages/send_file.py +59 -0
- darkob/client/messages/send_gif.py +73 -0
- darkob/client/messages/send_image.py +72 -0
- darkob/client/messages/send_live.py +69 -0
- darkob/client/messages/send_location.py +50 -0
- darkob/client/messages/send_message.py +275 -0
- darkob/client/messages/send_message_api_call.py +50 -0
- darkob/client/messages/send_music.py +64 -0
- darkob/client/messages/send_now_scheduled_message.py +29 -0
- darkob/client/messages/send_poll.py +63 -0
- darkob/client/messages/send_quiz.py +94 -0
- darkob/client/messages/send_rubino_post.py +35 -0
- darkob/client/messages/send_rubino_product.py +38 -0
- darkob/client/messages/send_rubino_story.py +42 -0
- darkob/client/messages/send_sticker.py +57 -0
- darkob/client/messages/send_video.py +75 -0
- darkob/client/messages/send_video_message.py +75 -0
- darkob/client/messages/send_voice.py +61 -0
- darkob/client/messages/stop_poll.py +23 -0
- darkob/client/messages/transcribe_voice.py +45 -0
- darkob/client/messages/unpin_all_messages.py +23 -0
- darkob/client/messages/unpin_message.py +29 -0
- darkob/client/messages/vote_poll.py +22 -0
- darkob/client/settings/__init__.py +100 -0
- darkob/client/settings/abort_two_step_setup.py +11 -0
- darkob/client/settings/add_folder.py +159 -0
- darkob/client/settings/add_saved_music_playlist.py +81 -0
- darkob/client/settings/add_saved_music_track.py +78 -0
- darkob/client/settings/auto_delete_account.py +23 -0
- darkob/client/settings/change_password.py +28 -0
- darkob/client/settings/check_two_step_passcode.py +14 -0
- darkob/client/settings/confirm_unconfirmed_session.py +23 -0
- darkob/client/settings/delete_account.py +16 -0
- darkob/client/settings/delete_folder.py +17 -0
- darkob/client/settings/delete_saved_music_playlist.py +46 -0
- darkob/client/settings/deny_unconfirmed_session.py +23 -0
- darkob/client/settings/edit_can_called_by.py +27 -0
- darkob/client/settings/edit_can_join_chat_by.py +27 -0
- darkob/client/settings/edit_show_birthday.py +27 -0
- darkob/client/settings/edit_show_last_online.py +27 -0
- darkob/client/settings/edit_show_phone_number.py +27 -0
- darkob/client/settings/edit_show_profile_photo.py +27 -0
- darkob/client/settings/get_folders.py +19 -0
- darkob/client/settings/get_my_sessions.py +11 -0
- darkob/client/settings/get_notification_setting.py +11 -0
- darkob/client/settings/get_privacy_setting.py +11 -0
- darkob/client/settings/get_suggested_folders.py +11 -0
- darkob/client/settings/get_two_passcode_status.py +11 -0
- darkob/client/settings/get_unconfirmed_sessions.py +11 -0
- darkob/client/settings/login_disable_two_step.py +32 -0
- darkob/client/settings/login_two_step_forget_password.py +30 -0
- darkob/client/settings/logout.py +38 -0
- darkob/client/settings/register_device.py +135 -0
- darkob/client/settings/reorder_folder.py +24 -0
- darkob/client/settings/request_change_phone_number.py +30 -0
- darkob/client/settings/request_forget_password.py +11 -0
- darkob/client/settings/request_recovery_email.py +25 -0
- darkob/client/settings/set_notification.py +64 -0
- darkob/client/settings/set_saved_music_playlist.py +78 -0
- darkob/client/settings/set_setting.py +233 -0
- darkob/client/settings/set_two_step_verification.py +29 -0
- darkob/client/settings/terminate_other_sessions.py +11 -0
- darkob/client/settings/terminate_session.py +14 -0
- darkob/client/settings/turn_off_two_step.py +14 -0
- darkob/client/settings/update_my_bio.py +27 -0
- darkob/client/settings/update_my_birthday.py +38 -0
- darkob/client/settings/update_my_name.py +38 -0
- darkob/client/settings/update_my_profile.py +74 -0
- darkob/client/settings/update_my_username.py +41 -0
- darkob/client/settings/upgrade_to_api6.py +59 -0
- darkob/client/settings/verify_change_phone_number.py +32 -0
- darkob/client/settings/verify_recovery_email.py +27 -0
- darkob/client/users/__init__.py +51 -0
- darkob/client/users/add_contact.py +50 -0
- darkob/client/users/block_user.py +24 -0
- darkob/client/users/check_user_username.py +14 -0
- darkob/client/users/delete_contact.py +24 -0
- darkob/client/users/delete_user_chat.py +40 -0
- darkob/client/users/discard_call.py +30 -0
- darkob/client/users/get_blocked_users.py +62 -0
- darkob/client/users/get_common_groups.py +24 -0
- darkob/client/users/get_contacts.py +63 -0
- darkob/client/users/get_contacts_last_online.py +33 -0
- darkob/client/users/get_contacts_stories.py +11 -0
- darkob/client/users/get_contacts_updates.py +20 -0
- darkob/client/users/get_last_online.py +44 -0
- darkob/client/users/get_me.py +22 -0
- darkob/client/users/get_saved_music_playlist.py +27 -0
- darkob/client/users/get_top_users.py +14 -0
- darkob/client/users/get_user_info.py +28 -0
- darkob/client/users/remove_from_top_users.py +24 -0
- darkob/client/users/request_video_call.py +49 -0
- darkob/client/users/request_voice_call.py +49 -0
- darkob/client/users/reset_contacts.py +13 -0
- darkob/client/users/set_ask_spam.py +57 -0
- darkob/client/users/unblock_all_users.py +65 -0
- darkob/client/users/unblock_user.py +24 -0
- darkob/data.py +232 -0
- darkob/fsm.py +281 -0
- darkob/hybrid.py +216 -0
- darkob/router.py +160 -0
- darkob/shad.py +68 -0
- darkob/types/__init__.py +7 -0
- darkob/types/event.py +681 -0
- darkob/types/incoming.py +669 -0
- darkob-0.2.0.dist-info/METADATA +282 -0
- darkob-0.2.0.dist-info/RECORD +417 -0
- darkob-0.2.0.dist-info/WHEEL +5 -0
- darkob-0.2.0.dist-info/licenses/LICENSE +21 -0
- darkob-0.2.0.dist-info/top_level.txt +1 -0
darkob/TheBot.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import asyncio
|
|
3
|
+
from typing import Union, Optional
|
|
4
|
+
import aiohttp
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
import darkob
|
|
8
|
+
from .bot import Methods
|
|
9
|
+
from .bot.session import Session
|
|
10
|
+
from .bot.updates import Updates
|
|
11
|
+
from .bot.token import TokenString
|
|
12
|
+
from .bot.exceptions import TokenError
|
|
13
|
+
from .bot.registry import HandlerRegistry
|
|
14
|
+
from .bot.bridge import DecoratorBridge
|
|
15
|
+
from .bot.plugin import PluginManager
|
|
16
|
+
|
|
17
|
+
console = Console(highlight=False)
|
|
18
|
+
|
|
19
|
+
class Bot(Session, Updates, Methods):
|
|
20
|
+
TOKEN_PATTERN = re.compile(r'^[A-Z]{5}[0-9A-Z]{59}$')
|
|
21
|
+
DEFAULT_BASE_URL = "https://botapi.rubika.ir/v3"
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
token: Optional[str] = None,
|
|
26
|
+
token_string: Optional[str] = None,
|
|
27
|
+
password: Optional[str] = None,
|
|
28
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
29
|
+
timeout: Union[int, float] = 30,
|
|
30
|
+
max_retries: Union[int, float] = 5,
|
|
31
|
+
verify_ssl: bool = True,
|
|
32
|
+
show_welcome: bool = True,
|
|
33
|
+
run_all_handlers: bool = True
|
|
34
|
+
):
|
|
35
|
+
"""
|
|
36
|
+
Initialize the Bot instance.
|
|
37
|
+
|
|
38
|
+
Parameters:
|
|
39
|
+
token (Optional[str]): Bot authentication token. If not provided
|
|
40
|
+
or invalid, the bot will prompt for it via console input.
|
|
41
|
+
token_string (Optional[str]): Encrypted TokenString. Takes priority over token.
|
|
42
|
+
password (Optional[str]): Password for encrypted TokenString.
|
|
43
|
+
base_url (str): Base API URL. Defaults to "https://botapi.rubika.ir/v3".
|
|
44
|
+
timeout (int): Request timeout in seconds. Defaults to 30.
|
|
45
|
+
max_retries (int): Maximum number of retry attempts on network
|
|
46
|
+
errors. Defaults to 5.
|
|
47
|
+
verify_ssl (bool): Verify TLS certificates. Defaults to True.
|
|
48
|
+
Only disable this if you understand the interception risk.
|
|
49
|
+
show_welcome (bool, optional): If True, show welcome message (default: True).
|
|
50
|
+
run_all_handlers (bool, optional): If True (default), every handler whose
|
|
51
|
+
constraints match an event is run, in registration order. If False,
|
|
52
|
+
only the first matching handler runs, so registration order decides
|
|
53
|
+
which handler wins.
|
|
54
|
+
"""
|
|
55
|
+
darkob.show_welcome_message(show_welcome)
|
|
56
|
+
|
|
57
|
+
self._session: Optional[aiohttp.ClientSession] = None
|
|
58
|
+
self._close_task: Optional["asyncio.Task"] = None
|
|
59
|
+
self._session_loop: Optional["asyncio.AbstractEventLoop"] = None
|
|
60
|
+
|
|
61
|
+
if token_string:
|
|
62
|
+
token = TokenString(token_string).to_token(password)
|
|
63
|
+
if not token:
|
|
64
|
+
raise TokenError(
|
|
65
|
+
"Invalid token_string or wrong password.")
|
|
66
|
+
else:
|
|
67
|
+
token = (token or "").strip()
|
|
68
|
+
if not self.TOKEN_PATTERN.match(token):
|
|
69
|
+
token = self._get_token()
|
|
70
|
+
|
|
71
|
+
self.token = token
|
|
72
|
+
self.timeout = float(timeout)
|
|
73
|
+
self.max_retries = int(max_retries)
|
|
74
|
+
self.verify_ssl = bool(verify_ssl)
|
|
75
|
+
self.base_url = f"{base_url.rstrip('/')}/{token}"
|
|
76
|
+
self.run_all_handlers = bool(run_all_handlers)
|
|
77
|
+
|
|
78
|
+
self._registry = HandlerRegistry(self)
|
|
79
|
+
self._bridge = DecoratorBridge(self._registry)
|
|
80
|
+
self.plugin_manager = PluginManager(self)
|
|
81
|
+
|
|
82
|
+
for name in dir(type(self._bridge)):
|
|
83
|
+
if name.startswith('_'):
|
|
84
|
+
continue
|
|
85
|
+
attr = getattr(type(self._bridge), name, None)
|
|
86
|
+
if isinstance(attr, property):
|
|
87
|
+
setattr(self, name, getattr(self._bridge, name))
|
|
88
|
+
|
|
89
|
+
def _get_token(self) -> str:
|
|
90
|
+
while True:
|
|
91
|
+
console.print("Enter your bot token: ", style="bold yellow", end="")
|
|
92
|
+
token = input().strip()
|
|
93
|
+
if self.TOKEN_PATTERN.match(token):
|
|
94
|
+
return token
|
|
95
|
+
console.print("\nInvalid token format. Try again.\n", style="bold red")
|
|
96
|
+
|
|
97
|
+
def include_router(self, router):
|
|
98
|
+
"""Register every handler declared on *router*, recursively.
|
|
99
|
+
|
|
100
|
+
Lets a bot be split into feature modules::
|
|
101
|
+
|
|
102
|
+
bot.include_router(admin_router)
|
|
103
|
+
|
|
104
|
+
Returns the router so calls can be chained.
|
|
105
|
+
"""
|
|
106
|
+
from .router import Router
|
|
107
|
+
|
|
108
|
+
if not isinstance(router, Router):
|
|
109
|
+
raise TypeError(
|
|
110
|
+
f"include_router expects a Router, got {type(router).__name__}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
router.apply(self)
|
|
114
|
+
return router
|
darkob/TheClient.py
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
from typing import Optional, Union, Literal
|
|
2
|
+
import asyncio
|
|
3
|
+
import os
|
|
4
|
+
import logging
|
|
5
|
+
import re
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.text import Text
|
|
8
|
+
import darkob
|
|
9
|
+
from .client import Methods
|
|
10
|
+
from .client.core.cipher import Cipher
|
|
11
|
+
from .client.core.session import Session, StringSession
|
|
12
|
+
from .client.exceptions import (
|
|
13
|
+
ApiVersionError,
|
|
14
|
+
PlatformError,
|
|
15
|
+
AuthError,
|
|
16
|
+
TimeoutError,
|
|
17
|
+
MaxRetriesError,
|
|
18
|
+
ProxyError,
|
|
19
|
+
SessionError
|
|
20
|
+
)
|
|
21
|
+
from .client.core.configs import DEFAULT_PLATFORM, PLATFORMS, VALID_PLATFORMS, USER_AGENT
|
|
22
|
+
|
|
23
|
+
class Client(Methods):
|
|
24
|
+
USER_AGENT = USER_AGENT
|
|
25
|
+
API_VERSION = 6
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
session: Optional[str] = None,
|
|
30
|
+
string_session: Optional[str] = None,
|
|
31
|
+
password: Optional[str] = None,
|
|
32
|
+
auth: Optional[str] = None,
|
|
33
|
+
private_key: Optional[Union[str, bytes]] = None,
|
|
34
|
+
timeout: Union[str, int, float] = 30,
|
|
35
|
+
proxy: Optional[str] = None,
|
|
36
|
+
verify_ssl: bool = True,
|
|
37
|
+
logger: Optional[logging.Logger] = None,
|
|
38
|
+
platform: Literal['web', 'pwa', 'android', 'rubx', 'rubikids', 'rubino'] = 'pwa',
|
|
39
|
+
api_version: Literal[5, 6] = 6,
|
|
40
|
+
max_retries: int = 5,
|
|
41
|
+
stop_on_first_match: bool = False,
|
|
42
|
+
continue_on_error: bool = True,
|
|
43
|
+
show_welcome: bool = True
|
|
44
|
+
) -> None:
|
|
45
|
+
"""
|
|
46
|
+
Initialize the Rubika client.
|
|
47
|
+
|
|
48
|
+
Parameters:
|
|
49
|
+
session (str, optional): Session file name or path. (api_version=6 only)
|
|
50
|
+
string_session (str, optional): StringSession string. Takes priority over 'session'.
|
|
51
|
+
password (str, optional): Password for encrypted StringSession. Required if StringSession was created with a password.
|
|
52
|
+
auth (str, optional): Authentication key.
|
|
53
|
+
private_key (str or bytes, optional): RSA private key. (api_version=6 only)
|
|
54
|
+
timeout (int or float, optional): Request timeout in seconds (default: 30).
|
|
55
|
+
proxy (str, optional): Proxy address (example: 'http://127.0.0.1:80').
|
|
56
|
+
verify_ssl (bool, optional): Verify TLS certificates (default: True).
|
|
57
|
+
Only disable this if you understand the risk; it makes the
|
|
58
|
+
connection vulnerable to interception.
|
|
59
|
+
logger (logging.Logger, optional): Logger instance.
|
|
60
|
+
platform: Literal['web', 'pwa', 'android', 'rubx', 'rubikids', 'rubino']: Client platform (default: 'pwa').
|
|
61
|
+
api_version: Literal[5, 6]: API version to use (default: 6).
|
|
62
|
+
- 6: Requires 'auth' + 'private_key' (or 'session').
|
|
63
|
+
- 5: Requires only 'auth'.
|
|
64
|
+
max_retries (int, optional): Maximum number of retries for requests (default: 5).
|
|
65
|
+
stop_on_first_match (bool, optional): If True, stop processing handlers after the first match (default: False).
|
|
66
|
+
continue_on_error (bool, optional): If True, continue trying other platforms on auth errors (default: True).
|
|
67
|
+
show_welcome (bool, optional): If True, show welcome message (default: True).
|
|
68
|
+
|
|
69
|
+
Raises:
|
|
70
|
+
ApiVersionError: If api_version is invalid.
|
|
71
|
+
PlatformError: If platform is invalid.
|
|
72
|
+
AuthError: If auth parameters are invalid.
|
|
73
|
+
TimeoutError: If timeout is invalid.
|
|
74
|
+
MaxRetriesError: If max_retries is invalid.
|
|
75
|
+
ProxyError: If proxy is invalid.
|
|
76
|
+
SessionError: If session or string_session is invalid.
|
|
77
|
+
"""
|
|
78
|
+
darkob.show_welcome_message(show_welcome)
|
|
79
|
+
|
|
80
|
+
if type(self) is Client:
|
|
81
|
+
err_console = Console(stderr=True)
|
|
82
|
+
warning_msg = Text()
|
|
83
|
+
warning_msg.append("DeprecationWarning: ", style="bright_red")
|
|
84
|
+
warning_msg.append("'Client'", style="bright_red underline")
|
|
85
|
+
warning_msg.append(" is deprecated. Use ", style="bright_red")
|
|
86
|
+
warning_msg.append("'Messenger'", style="bright_green underline")
|
|
87
|
+
warning_msg.append(" instead.\n", style="bright_red")
|
|
88
|
+
err_console.print(warning_msg)
|
|
89
|
+
super().__init__()
|
|
90
|
+
|
|
91
|
+
if api_version not in (5, 6):
|
|
92
|
+
raise ApiVersionError("'api_version' must be 5 or 6.")
|
|
93
|
+
|
|
94
|
+
self.API_VERSION = api_version
|
|
95
|
+
|
|
96
|
+
if platform.lower() not in VALID_PLATFORMS:
|
|
97
|
+
raise PlatformError(
|
|
98
|
+
f"Invalid platform '{platform}'. Valid platforms are: {', '.join(VALID_PLATFORMS)}"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if api_version == 6:
|
|
102
|
+
if session is None and string_session is None and (auth is None or private_key is None):
|
|
103
|
+
raise AuthError("API v6 requires: 'session', 'string_session', OR both 'auth' and 'private_key'.")
|
|
104
|
+
if auth is not None and private_key is None:
|
|
105
|
+
raise AuthError("If 'auth' is provided, 'private_key' must also be provided.")
|
|
106
|
+
if private_key is not None and auth is None:
|
|
107
|
+
raise AuthError("If 'private_key' is provided, 'auth' must also be provided.")
|
|
108
|
+
elif api_version == 5:
|
|
109
|
+
if auth is None:
|
|
110
|
+
raise AuthError("API v5 requires: 'auth'.")
|
|
111
|
+
if private_key is not None:
|
|
112
|
+
raise AuthError("API v5 does not support 'private_key'.")
|
|
113
|
+
session = None
|
|
114
|
+
string_session = None
|
|
115
|
+
|
|
116
|
+
if auth is not None:
|
|
117
|
+
if not isinstance(auth, str):
|
|
118
|
+
raise AuthError("The 'auth' parameter must be a string.")
|
|
119
|
+
if not re.match(r'^[a-z]{32}$', auth):
|
|
120
|
+
raise AuthError("The 'auth' must be 32 lowercase letters only.")
|
|
121
|
+
|
|
122
|
+
if isinstance(timeout, bool):
|
|
123
|
+
raise TimeoutError("'timeout' must be a number, not a boolean.")
|
|
124
|
+
try:
|
|
125
|
+
timeout = float(timeout)
|
|
126
|
+
except (TypeError, ValueError):
|
|
127
|
+
raise TimeoutError("The 'timeout' parameter must be a number.")
|
|
128
|
+
if timeout <= 0:
|
|
129
|
+
raise TimeoutError("'timeout' must be greater than 0.")
|
|
130
|
+
|
|
131
|
+
if isinstance(max_retries, bool) or not isinstance(max_retries, int):
|
|
132
|
+
raise MaxRetriesError("'max_retries' must be an integer.")
|
|
133
|
+
if max_retries < 0:
|
|
134
|
+
raise MaxRetriesError("'max_retries' must be >= 0.")
|
|
135
|
+
|
|
136
|
+
if proxy is not None and not isinstance(proxy, str):
|
|
137
|
+
raise ProxyError("'proxy' must be a string.")
|
|
138
|
+
|
|
139
|
+
if not isinstance(verify_ssl, bool):
|
|
140
|
+
raise ValueError("'verify_ssl' must be a boolean.")
|
|
141
|
+
|
|
142
|
+
self.DEFAULT_PLATFORM = DEFAULT_PLATFORM.copy()
|
|
143
|
+
self.DEFAULT_PLATFORM.update(PLATFORMS.get(platform.lower(), {}))
|
|
144
|
+
self._original_platform = platform.lower()
|
|
145
|
+
|
|
146
|
+
if session is not None:
|
|
147
|
+
if not isinstance(session, str):
|
|
148
|
+
raise SessionError("The 'session' parameter must be a string.")
|
|
149
|
+
self.session_name = os.path.basename(session)
|
|
150
|
+
self.session_path = session
|
|
151
|
+
session = Session(session)
|
|
152
|
+
|
|
153
|
+
elif string_session is not None:
|
|
154
|
+
try:
|
|
155
|
+
session = Session(string_session=string_session, password=password)
|
|
156
|
+
info = session.information()
|
|
157
|
+
if info:
|
|
158
|
+
auth = info[1]
|
|
159
|
+
private_key = info[4]
|
|
160
|
+
self.session_name = f"darkob_{auth[:10]}"
|
|
161
|
+
self.session_path = self.session_name
|
|
162
|
+
except ValueError:
|
|
163
|
+
raise SessionError(
|
|
164
|
+
"String session is invalid or wrong password."
|
|
165
|
+
) from None
|
|
166
|
+
|
|
167
|
+
else:
|
|
168
|
+
self.session_name = f"darkob_{auth[:10]}" if auth else None
|
|
169
|
+
self.session_path = self.session_name
|
|
170
|
+
session = Session(self.session_name) if self.session_name else None
|
|
171
|
+
|
|
172
|
+
if not isinstance(logger, logging.Logger):
|
|
173
|
+
logger = logging.getLogger(__name__)
|
|
174
|
+
|
|
175
|
+
if isinstance(private_key, str):
|
|
176
|
+
if not private_key.startswith('-----BEGIN RSA PRIVATE KEY-----'):
|
|
177
|
+
private_key = f'-----BEGIN RSA PRIVATE KEY-----\n{private_key}'
|
|
178
|
+
if not private_key.endswith('-----END RSA PRIVATE KEY-----'):
|
|
179
|
+
private_key += '\n-----END RSA PRIVATE KEY-----'
|
|
180
|
+
|
|
181
|
+
self.auth = auth
|
|
182
|
+
self.logger = logger
|
|
183
|
+
self.private_key = private_key
|
|
184
|
+
self.user_agent = self.USER_AGENT
|
|
185
|
+
self.timeout = timeout
|
|
186
|
+
self.session = session
|
|
187
|
+
self.proxy = proxy
|
|
188
|
+
self.verify_ssl = verify_ssl
|
|
189
|
+
self.decode_auth = None
|
|
190
|
+
self.import_key = None
|
|
191
|
+
self.guid = None
|
|
192
|
+
self.key = None
|
|
193
|
+
self.handlers = {}
|
|
194
|
+
self.max_retries = max_retries
|
|
195
|
+
self.stop_on_first_match = stop_on_first_match
|
|
196
|
+
self.continue_on_error = continue_on_error
|
|
197
|
+
|
|
198
|
+
def __del__(self) -> None:
|
|
199
|
+
try:
|
|
200
|
+
self.disconnect()
|
|
201
|
+
except Exception:
|
|
202
|
+
# Interpreter shutdown: nothing useful can be done here.
|
|
203
|
+
pass
|
|
204
|
+
|
|
205
|
+
def __enter__(self) -> "Client":
|
|
206
|
+
if not getattr(self, 'connection', None):
|
|
207
|
+
return self.start()
|
|
208
|
+
return self
|
|
209
|
+
|
|
210
|
+
def __exit__(self, *args, **kwargs):
|
|
211
|
+
try:
|
|
212
|
+
self.disconnect()
|
|
213
|
+
except Exception:
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
async def __aenter__(self) -> "Client":
|
|
217
|
+
if not getattr(self, 'connection', None):
|
|
218
|
+
return await self.start()
|
|
219
|
+
return self
|
|
220
|
+
|
|
221
|
+
async def __aexit__(self, *args, **kwargs):
|
|
222
|
+
try:
|
|
223
|
+
await self.close()
|
|
224
|
+
except Exception:
|
|
225
|
+
pass
|
|
226
|
+
|
|
227
|
+
async def stop(self) -> None:
|
|
228
|
+
if hasattr(self, 'connection'):
|
|
229
|
+
if self.connection.session.closed:
|
|
230
|
+
return
|
|
231
|
+
await self.close()
|
|
232
|
+
|
|
233
|
+
class Messenger(Client):
|
|
234
|
+
pass
|
darkob/__init__.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""darkob — async Python library for the Rubika & Shad platforms.
|
|
2
|
+
|
|
3
|
+
Derived from `maxrubika <https://github.com/MEH2RAB/maxrubika>`_ by
|
|
4
|
+
MEHRAB Farahmand (MIT License), rebranded and hardened.
|
|
5
|
+
|
|
6
|
+
Importing this package performs **no network I/O**. The optional update
|
|
7
|
+
check is opt-in via :func:`check_for_updates`.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from typing import List, Optional, Tuple
|
|
15
|
+
|
|
16
|
+
from rich.console import Console
|
|
17
|
+
from rich.text import Text
|
|
18
|
+
|
|
19
|
+
from .TheBot import Bot
|
|
20
|
+
from .TheBot import Bot as bot
|
|
21
|
+
|
|
22
|
+
from .TheClient import Client, Messenger
|
|
23
|
+
from .TheClient import Messenger as messenger
|
|
24
|
+
|
|
25
|
+
from .shad import Shad
|
|
26
|
+
from .shad import Shad as shad
|
|
27
|
+
|
|
28
|
+
from .router import Router
|
|
29
|
+
from .fsm import (
|
|
30
|
+
FSMContext,
|
|
31
|
+
JsonFileStorage,
|
|
32
|
+
MemoryStorage,
|
|
33
|
+
StateFilter,
|
|
34
|
+
Storage,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
__author__ = "MEHRAB Farahmand"
|
|
38
|
+
__maintainer__ = "Mani Keikhosravi"
|
|
39
|
+
__version__ = "0.2.0"
|
|
40
|
+
|
|
41
|
+
logger = logging.getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
_welcome_shown = False
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
"Bot",
|
|
47
|
+
"bot",
|
|
48
|
+
"Client",
|
|
49
|
+
"Messenger",
|
|
50
|
+
"messenger",
|
|
51
|
+
"Shad",
|
|
52
|
+
"shad",
|
|
53
|
+
"show_welcome_message",
|
|
54
|
+
"check_for_updates",
|
|
55
|
+
"Router",
|
|
56
|
+
"FSMContext",
|
|
57
|
+
"Storage",
|
|
58
|
+
"MemoryStorage",
|
|
59
|
+
"JsonFileStorage",
|
|
60
|
+
"StateFilter",
|
|
61
|
+
"__version__",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def show_welcome_message(show_welcome: bool = True) -> None:
|
|
66
|
+
"""Print the one-time welcome banner.
|
|
67
|
+
|
|
68
|
+
This never performs network I/O. The banner is shown at most once per
|
|
69
|
+
process unless ``show_welcome`` is false.
|
|
70
|
+
"""
|
|
71
|
+
global _welcome_shown
|
|
72
|
+
|
|
73
|
+
if not show_welcome or _welcome_shown:
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
_welcome_shown = True
|
|
77
|
+
|
|
78
|
+
console = Console()
|
|
79
|
+
text = Text()
|
|
80
|
+
text.append(
|
|
81
|
+
"Welcome to darkob — async library for Rubika & Shad",
|
|
82
|
+
style="bold magenta",
|
|
83
|
+
)
|
|
84
|
+
text.append(
|
|
85
|
+
f"\nCopyright © {datetime.now().year} darkob contributors "
|
|
86
|
+
"- All rights reserved.",
|
|
87
|
+
style="cyan",
|
|
88
|
+
)
|
|
89
|
+
text.append("\nGithub: ", style="white")
|
|
90
|
+
text.append(
|
|
91
|
+
"https://github.com/ManiTheFerfri/darkob", style="green underline"
|
|
92
|
+
)
|
|
93
|
+
text.append("\nDocument: ", style="white")
|
|
94
|
+
text.append(
|
|
95
|
+
"https://ManiTheFerfri.github.io/darkob\n", style="yellow underline"
|
|
96
|
+
)
|
|
97
|
+
console.print(text)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _parse_version(value: str) -> Tuple[int, ...]:
|
|
101
|
+
"""Parse a version string into a comparable tuple.
|
|
102
|
+
|
|
103
|
+
Tolerates pre-release and non-numeric suffixes, e.g. ``"1.2.0rc1"``
|
|
104
|
+
becomes ``(1, 2, 1)`` rather than raising.
|
|
105
|
+
"""
|
|
106
|
+
parts: List[int] = []
|
|
107
|
+
for chunk in value.split("."):
|
|
108
|
+
digits = "".join(ch for ch in chunk if ch.isdigit())
|
|
109
|
+
parts.append(int(digits) if digits else 0)
|
|
110
|
+
return tuple(parts)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def check_for_updates(
|
|
114
|
+
current_version: Optional[str] = None, *, timeout: float = 2.0
|
|
115
|
+
) -> Optional[str]:
|
|
116
|
+
"""Compare the installed version against the latest release on PyPI.
|
|
117
|
+
|
|
118
|
+
This is **opt-in** and is never called automatically. Call it yourself
|
|
119
|
+
if you want an update notice::
|
|
120
|
+
|
|
121
|
+
import darkob
|
|
122
|
+
darkob.check_for_updates()
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
current_version: Version to compare against; defaults to
|
|
126
|
+
:data:`__version__`.
|
|
127
|
+
timeout: Network timeout in seconds.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
The latest version string when an update is available, otherwise
|
|
131
|
+
``None``. Never raises on network or parsing failures.
|
|
132
|
+
"""
|
|
133
|
+
import json
|
|
134
|
+
from urllib.error import URLError
|
|
135
|
+
from urllib.request import urlopen
|
|
136
|
+
|
|
137
|
+
current_version = current_version or __version__
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
with urlopen(
|
|
141
|
+
"https://pypi.org/pypi/darkob/json", timeout=timeout
|
|
142
|
+
) as response:
|
|
143
|
+
latest = json.loads(response.read().decode("utf-8"))["info"][
|
|
144
|
+
"version"
|
|
145
|
+
]
|
|
146
|
+
except (URLError, OSError, ValueError, KeyError) as exc:
|
|
147
|
+
logger.debug("Update check skipped: %s", exc)
|
|
148
|
+
return None
|
|
149
|
+
|
|
150
|
+
try:
|
|
151
|
+
is_newer = _parse_version(latest) > _parse_version(current_version)
|
|
152
|
+
except (TypeError, ValueError):
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
if not is_newer:
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
console = Console(stderr=True)
|
|
159
|
+
notice = Text()
|
|
160
|
+
notice.append(
|
|
161
|
+
f"A new version of darkob is available! "
|
|
162
|
+
f"(v{current_version} → v{latest})\n",
|
|
163
|
+
style="bold bright_red",
|
|
164
|
+
)
|
|
165
|
+
notice.append(" Run: ", style="white")
|
|
166
|
+
notice.append("pip install darkob --upgrade\n", style="gold1")
|
|
167
|
+
console.print(notice)
|
|
168
|
+
|
|
169
|
+
return latest
|
darkob/bot/__init__.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from ..hybrid import wrap_methods
|
|
2
|
+
|
|
3
|
+
from .auto_delete_message import AutoDeleteMessage
|
|
4
|
+
from .ban_member import BanMember
|
|
5
|
+
from .delete_message import DeleteMessage
|
|
6
|
+
from .download_file import DownloadFile
|
|
7
|
+
from .edit_chat_keypad import EditChatKeypad
|
|
8
|
+
from .edit_inline_keypad import EditInlineKeypad
|
|
9
|
+
from .edit_message import EditMessage
|
|
10
|
+
from .forward_message import ForwardMessage
|
|
11
|
+
from .get_chat_info import GetChatInfo
|
|
12
|
+
from .get_chat_member import GetChatMember
|
|
13
|
+
from .get_file import GetFile
|
|
14
|
+
from .get_me import GetMe
|
|
15
|
+
from .get_token_string import GetTokenString
|
|
16
|
+
from .get_updates import GetUpdates
|
|
17
|
+
from .member_is_admin import MemberIsAdmin
|
|
18
|
+
from .member_is_joined import MemberIsJoined
|
|
19
|
+
from .member_is_owner import MemberIsOwner
|
|
20
|
+
from .register_all_endpoints import RegisterAllEndpoints
|
|
21
|
+
from .remove_chat_keypad import RemoveChatKeypad
|
|
22
|
+
from .remove_member import RemoveMember
|
|
23
|
+
from .request import Request
|
|
24
|
+
from .request_send_file import RequestSendFile
|
|
25
|
+
from .run import Run
|
|
26
|
+
from .send_contact import SendContact
|
|
27
|
+
from .send_file import SendFile
|
|
28
|
+
from .send_gif import SendGif
|
|
29
|
+
from .send_image import SendImage
|
|
30
|
+
from .send_location import Sendlocation
|
|
31
|
+
from .send_message import SendMessage
|
|
32
|
+
from .send_music import SendMusic
|
|
33
|
+
from .send_poll import SendPoll
|
|
34
|
+
from .send_quiz import SendQuiz
|
|
35
|
+
from .send_video import SendVideo
|
|
36
|
+
from .send_voice import SendVoice
|
|
37
|
+
from .set_commands import SetCommands
|
|
38
|
+
from .start import Start
|
|
39
|
+
from .unban_member import UnbanMember
|
|
40
|
+
from .update_bot_endpoints import UpdateBotEndpoints
|
|
41
|
+
from .upload_file import UploadFile
|
|
42
|
+
|
|
43
|
+
class Methods(
|
|
44
|
+
AutoDeleteMessage,
|
|
45
|
+
BanMember,
|
|
46
|
+
DeleteMessage,
|
|
47
|
+
DownloadFile,
|
|
48
|
+
EditChatKeypad,
|
|
49
|
+
EditInlineKeypad,
|
|
50
|
+
EditMessage,
|
|
51
|
+
ForwardMessage,
|
|
52
|
+
GetChatInfo,
|
|
53
|
+
GetChatMember,
|
|
54
|
+
GetFile,
|
|
55
|
+
GetMe,
|
|
56
|
+
GetTokenString,
|
|
57
|
+
GetUpdates,
|
|
58
|
+
MemberIsAdmin,
|
|
59
|
+
MemberIsJoined,
|
|
60
|
+
MemberIsOwner,
|
|
61
|
+
RegisterAllEndpoints,
|
|
62
|
+
RemoveChatKeypad,
|
|
63
|
+
RemoveMember,
|
|
64
|
+
Request,
|
|
65
|
+
RequestSendFile,
|
|
66
|
+
Run,
|
|
67
|
+
SendContact,
|
|
68
|
+
SendFile,
|
|
69
|
+
SendGif,
|
|
70
|
+
SendImage,
|
|
71
|
+
Sendlocation,
|
|
72
|
+
SendMessage,
|
|
73
|
+
SendMusic,
|
|
74
|
+
SendPoll,
|
|
75
|
+
SendQuiz,
|
|
76
|
+
SendVideo,
|
|
77
|
+
SendVoice,
|
|
78
|
+
SetCommands,
|
|
79
|
+
Start,
|
|
80
|
+
UnbanMember,
|
|
81
|
+
UpdateBotEndpoints,
|
|
82
|
+
UploadFile
|
|
83
|
+
):
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
wrap_methods(Methods)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
import asyncio
|
|
3
|
+
import darkob
|
|
4
|
+
|
|
5
|
+
class AutoDeleteMessage:
|
|
6
|
+
async def auto_delete_message(
|
|
7
|
+
self: "darkob.Bot",
|
|
8
|
+
chat_id: str,
|
|
9
|
+
message_id: Union[str, int],
|
|
10
|
+
time: Union[float, int]
|
|
11
|
+
):
|
|
12
|
+
"""
|
|
13
|
+
Automatically delete a message after a specified time.
|
|
14
|
+
|
|
15
|
+
Parameters:
|
|
16
|
+
chat_id (str): chat_id of the object associated with the message (e.g., user, group, channel).
|
|
17
|
+
message_id (str): The ID of the message to be deleted.
|
|
18
|
+
time (Union[float, int]): The time delay (in seconds) before deleting the message.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
The updated information after deleting the message.
|
|
22
|
+
"""
|
|
23
|
+
await asyncio.sleep(time)
|
|
24
|
+
return await self.delete_message(chat_id, message_id)
|
darkob/bot/ban_member.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import darkob
|
|
3
|
+
from .exceptions import InvalidInput
|
|
4
|
+
|
|
5
|
+
class BanMember:
|
|
6
|
+
async def ban_member(
|
|
7
|
+
self: "darkob.Bot",
|
|
8
|
+
chat_id: str,
|
|
9
|
+
sender_id: str
|
|
10
|
+
):
|
|
11
|
+
"""
|
|
12
|
+
Ban a member from a group or channel.
|
|
13
|
+
|
|
14
|
+
Parameters:
|
|
15
|
+
chat_id (str): chat_id of group (starts with 'g0') or channel (starts with 'c0').
|
|
16
|
+
sender_id (str): sender_id of member to ban (starts with 'u0').
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
dict: API response.
|
|
20
|
+
"""
|
|
21
|
+
chat_id_regex = r"^(@[a-zA-Z0-9_]{3,32}|(c0|g0|b0)[a-zA-Z0-9]{30})$"
|
|
22
|
+
sender_id_regex = r"^u0[a-zA-Z0-9]{30}$"
|
|
23
|
+
|
|
24
|
+
if not re.match(chat_id_regex, chat_id):
|
|
25
|
+
raise InvalidInput("Invalid 'chat_id' format.")
|
|
26
|
+
|
|
27
|
+
if chat_id.startswith('b0'):
|
|
28
|
+
raise InvalidInput("'chat_id' must not start with 'b0'.")
|
|
29
|
+
|
|
30
|
+
if not re.match(sender_id_regex, sender_id):
|
|
31
|
+
raise InvalidInput("Invalid 'sender_id' format.")
|
|
32
|
+
|
|
33
|
+
payload = {
|
|
34
|
+
'chat_id': chat_id,
|
|
35
|
+
'user_id': sender_id
|
|
36
|
+
}
|
|
37
|
+
return await self.request('POST', 'banChatMember', json = payload)
|
darkob/bot/bot_status.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Decorators for a user starting or stopping the bot."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Callable
|
|
5
|
+
|
|
6
|
+
from .filters import EventConstraint, IsStartedBot, IsStoppedBot
|
|
7
|
+
from .registry import HandlerRegistry
|
|
8
|
+
|
|
9
|
+
class BotStatusDecorators:
|
|
10
|
+
"""Decorators that fire when a user starts or stops the bot."""
|
|
11
|
+
|
|
12
|
+
__slots__ = ('_registry',)
|
|
13
|
+
|
|
14
|
+
def __init__(self, registry: HandlerRegistry) -> None:
|
|
15
|
+
self._registry = registry
|
|
16
|
+
|
|
17
|
+
def on_started_bot(self, *constraints: EventConstraint) -> Callable:
|
|
18
|
+
"""Handle a user starting the bot."""
|
|
19
|
+
merged = (IsStartedBot(),) + constraints
|
|
20
|
+
|
|
21
|
+
def deco(func: Callable) -> Callable:
|
|
22
|
+
return self._registry.store(func, *merged)
|
|
23
|
+
return deco
|
|
24
|
+
|
|
25
|
+
def on_stopped_bot(self, *constraints: EventConstraint) -> Callable:
|
|
26
|
+
"""Handle a user stopping the bot."""
|
|
27
|
+
merged = (IsStoppedBot(),) + constraints
|
|
28
|
+
|
|
29
|
+
def deco(func: Callable) -> Callable:
|
|
30
|
+
return self._registry.store(func, *merged)
|
|
31
|
+
return deco
|