baremotet 2.11__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.
- baremotet-2.11.dist-info/METADATA +32 -0
- baremotet-2.11.dist-info/RECORD +80 -0
- baremotet-2.11.dist-info/WHEEL +5 -0
- baremotet-2.11.dist-info/licenses/LICENSE +21 -0
- baremotet-2.11.dist-info/top_level.txt +2 -0
- handlers/__init__.py +0 -0
- handlers/core_handler.py +207 -0
- moudels/__init__.py +0 -0
- moudels/account/__init__.py +0 -0
- moudels/account/account_manager.py +295 -0
- moudels/account/account_viewer.py +135 -0
- moudels/account/cleaner.py +195 -0
- moudels/account/client/__init__.py +0 -0
- moudels/account/client/client_manager.py +466 -0
- moudels/account/client/flood_guard.py +245 -0
- moudels/account/client/online_client.py +6 -0
- moudels/account/client/status_report.py +36 -0
- moudels/account/client/test.py +42 -0
- moudels/account/device/__init__.py +0 -0
- moudels/account/device/device_manager.py +155 -0
- moudels/account/profile/__init__.py +0 -0
- moudels/account/profile/profile_info.py +53 -0
- moudels/account/profile/profile_media.py +89 -0
- moudels/account/profile/profile_privacy.py +63 -0
- moudels/account/profile/username_manager.py +107 -0
- moudels/admin/__init__.py +0 -0
- moudels/admin/admin_manager.py +187 -0
- moudels/analytics/__init__.py +0 -0
- moudels/analytics/analytics_manager.py +199 -0
- moudels/batch/__init__.py +0 -0
- moudels/batch/batch_manager.py +108 -0
- moudels/batch/batch_scheduler.py +107 -0
- moudels/batch/message_shift.py +266 -0
- moudels/batch/shift_scheduler.py +128 -0
- moudels/core/__init__.py +0 -0
- moudels/core/config.py +349 -0
- moudels/core/getcode_controller.py +50 -0
- moudels/core/help_menu.py +83 -0
- moudels/core/human_behavior.py +38 -0
- moudels/core/menu_state.py +87 -0
- moudels/core/precise_engine.py +37 -0
- moudels/core/response_manager.py +276 -0
- moudels/core/restart_module.py +109 -0
- moudels/core/status_panel.py +202 -0
- moudels/core/typing_indicator.py +143 -0
- moudels/db/__init__.py +0 -0
- moudels/db/db_monitor.py +203 -0
- moudels/db/sqlite_utils.py +215 -0
- moudels/forward/__init__.py +0 -0
- moudels/forward/forward_commands.py +261 -0
- moudels/forward/forwarder.py +627 -0
- moudels/forward/speed_for_manager.py +31 -0
- moudels/forward/stop_manager.py +32 -0
- moudels/group/__init__.py +0 -0
- moudels/group/join_controller.py +35 -0
- moudels/group/joiner.py +196 -0
- moudels/group/leave_controller.py +35 -0
- moudels/group/lefter.py +155 -0
- moudels/menu/__init__.py +0 -0
- moudels/menu/actions.py +376 -0
- moudels/menu/backup_legacy_inline/button_actions.py +424 -0
- moudels/menu/backup_legacy_inline/keyboards.py +259 -0
- moudels/menu/callback_router.py +328 -0
- moudels/menu/keyboards.py +294 -0
- moudels/menu/output_view.py +86 -0
- moudels/menu/proxy_message.py +109 -0
- moudels/menu/register.py +49 -0
- moudels/menu/schema.py +27 -0
- moudels/menu/state_catchers.py +356 -0
- moudels/menu/state_manager.py +41 -0
- moudels/text/__init__.py +0 -0
- moudels/text/caption_manager.py +27 -0
- moudels/text/finaly_text.py +233 -0
- moudels/text/mention_manager.py +286 -0
- moudels/text/text_manager.py +27 -0
- moudels/utils/__init__.py +0 -0
- moudels/utils/block_manager.py +156 -0
- moudels/utils/file_sender.py +137 -0
- moudels/utils/health.py +31 -0
- moudels/utils/humanize.py +75 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: baremotet
|
|
3
|
+
Version: 2.11
|
|
4
|
+
Summary: Remote client framework for Telegram automation using Pyrogram
|
|
5
|
+
Home-page: https://github.com/MohammadAhmadi-R/ravisremote
|
|
6
|
+
Author: MrAhmadiRad
|
|
7
|
+
Author-email: MohammadAhmadiRad <mohammadahmadirad69@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/MohammadAhmadi-R/ravisremote
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Framework :: AsyncIO
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: pyrogram>=2.0.106
|
|
23
|
+
Requires-Dist: httpx>=0.27.0
|
|
24
|
+
Requires-Dist: pytz>=2023.3
|
|
25
|
+
Dynamic: author
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: requires-python
|
|
29
|
+
|
|
30
|
+
# Remote
|
|
31
|
+
Core Telegram Remote client engine (MrAhmadiRad)
|
|
32
|
+
[GitHub-flavored Markdown](https://github.com/MohammadAhmadi-R/CliRemote)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
baremotet-2.11.dist-info/licenses/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
|
|
2
|
+
handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
handlers/core_handler.py,sha256=MHkUYcRNAFSLoYFqf2TqmJuEQBRO4NDcm4fIDBT3HJY,9724
|
|
4
|
+
moudels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
moudels/account/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
moudels/account/account_manager.py,sha256=08J-nWM8y75mv8faO_MpSr9nCarD6cL-ZP5Hjm24E_I,12216
|
|
7
|
+
moudels/account/account_viewer.py,sha256=2_cd6v4WlBj4aLurYeNujjiQ1N2RyQGNHdmgmHvU6KQ,5931
|
|
8
|
+
moudels/account/cleaner.py,sha256=-MdHYBrkqH1jUoShiAysz5mA5a24P5OzPQ4LcgzBGvA,9537
|
|
9
|
+
moudels/account/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
moudels/account/client/client_manager.py,sha256=TK2GB_tZ84M-ITiN0CNe0UlIAP55nWdt7Gmz7wuxhCc,18759
|
|
11
|
+
moudels/account/client/flood_guard.py,sha256=VDMo2npIDcbHQbS3pTKzPRz-7k6M37wAzOaB1X4dItY,10943
|
|
12
|
+
moudels/account/client/online_client.py,sha256=ARvTnMBlMeXu2hSjJskqDjX3SMwaxbqTBdyJgVXMVaQ,195
|
|
13
|
+
moudels/account/client/status_report.py,sha256=BBf99UjQRIW3HCWJH1xiDz11DC6Ra_m7jmkz74od-BE,2359
|
|
14
|
+
moudels/account/client/test.py,sha256=zaQ-cxBdZVdsZNKumZAQCYyjDqaO7bSn1iaqrREnIFU,3398
|
|
15
|
+
moudels/account/device/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
moudels/account/device/device_manager.py,sha256=pdFuB4zYLCEy-U5yVCfUBSrch5iNdfWjGy-HEyD7_RQ,6506
|
|
17
|
+
moudels/account/profile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
moudels/account/profile/profile_info.py,sha256=gLted_G98xLIGXYKPpiRi8ehv3Q2syNY6rzZMQSBsi0,2000
|
|
19
|
+
moudels/account/profile/profile_media.py,sha256=m_CL9xUlF-WFaKjI7AFT3tDeXmgMvgf4-t-H6TuCldo,3692
|
|
20
|
+
moudels/account/profile/profile_privacy.py,sha256=bbIZ9ZYxXu9X1CL1oGIlRLKcQsegfXyLACfkN5LmCYI,2351
|
|
21
|
+
moudels/account/profile/username_manager.py,sha256=zxoNiTu10AM-hIoq7XaZTCJnH11_LiBxjT461AT--qg,4357
|
|
22
|
+
moudels/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
moudels/admin/admin_manager.py,sha256=UqStAfTBxVqiJYqdJye-QEW5V4XYEd1iaJ-AAkzXdpc,7427
|
|
24
|
+
moudels/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
moudels/analytics/analytics_manager.py,sha256=6jPvwt_ELA4RMbQdD8W_ltfAoaSgILnEkOAp6HZAqsU,7382
|
|
26
|
+
moudels/batch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
moudels/batch/batch_manager.py,sha256=YuNhDRjZxjK3rjIc-clcfHr7kr0SBxRqBBRCVKPgsYg,3703
|
|
28
|
+
moudels/batch/batch_scheduler.py,sha256=GmPz4ZSuDDFJR9IlLP02r8qHZQyb-Ye4iTf1bziMC6Q,4185
|
|
29
|
+
moudels/batch/message_shift.py,sha256=oskOVWsMAy3vhRhymAFk4Km3_eICvjxdujBv7lDeXbA,10095
|
|
30
|
+
moudels/batch/shift_scheduler.py,sha256=lu2U3ofE9kKoJxxFq55m9-vD_1qIyQG0b549GX610Ug,4855
|
|
31
|
+
moudels/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
moudels/core/config.py,sha256=txIvAFvK0Ef4KDavktQCvxuJhXIDXU393gg8wOunRvY,11625
|
|
33
|
+
moudels/core/getcode_controller.py,sha256=X9dJqgyuhtUdZ8PKM0yrP9ad3wXS7eERGiXuGJBfPbs,2240
|
|
34
|
+
moudels/core/help_menu.py,sha256=2IbgauP8XCLgEnFJWuTh0fxePaUa9Y0LJSO1EGt6y1Q,3449
|
|
35
|
+
moudels/core/human_behavior.py,sha256=pE48KwpeoCiPlPaQFTS0_YyOTbrCe2bB3j_3ihWCS-4,1626
|
|
36
|
+
moudels/core/menu_state.py,sha256=uggpInU5w6qa9-iBo9ynW3n4BmVMJ1l58SLsKYo7R_o,3597
|
|
37
|
+
moudels/core/precise_engine.py,sha256=hR5qAA1OhT16BfeS_y5y10Zv38N0Fx36KLDsDo2GA0Y,1607
|
|
38
|
+
moudels/core/response_manager.py,sha256=E2OCiW_t-DEpYzi-noQmpM9n2ZXRffdpf0_LrTVe-Gw,12000
|
|
39
|
+
moudels/core/restart_module.py,sha256=KUgXxNYzfIpzLhbAIHgLI2mYFBmoSO2VM-JH_rVcUBw,2914
|
|
40
|
+
moudels/core/status_panel.py,sha256=SI86BgeV3UibFnVfIYdG2IHWo7tqBNOJNvNywjqneEs,7856
|
|
41
|
+
moudels/core/typing_indicator.py,sha256=0yRrGOcNrLBJTdRl_0hgJ7qfdfyM44rdtCipOl4DYmY,5301
|
|
42
|
+
moudels/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
+
moudels/db/db_monitor.py,sha256=YLe4FDTw0ICp1RLWq2akWLNmTiLa6iwv08lzei8DWzE,8119
|
|
44
|
+
moudels/db/sqlite_utils.py,sha256=9RaOoxJbX2jRhApgcAvgyViKV3tygPX2ATLaPQNd6xk,8360
|
|
45
|
+
moudels/forward/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
moudels/forward/forward_commands.py,sha256=qV8lRTk9cmxaQHFiz--1eDg7z9u5viK2lJrLKeW9ZYg,10336
|
|
47
|
+
moudels/forward/forwarder.py,sha256=QgaAoaDy42g2Wdm07cTSevcGLA54pxTjrA1R6OMaWYs,25990
|
|
48
|
+
moudels/forward/speed_for_manager.py,sha256=UjviQ-DCmlER26fHTonEzi7F1T9F7NqVkjprurx2M7M,1046
|
|
49
|
+
moudels/forward/stop_manager.py,sha256=BSdIT_JOn_vF85HWtUEJUvY305NPJLMn66dt-7lZ174,1335
|
|
50
|
+
moudels/group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
+
moudels/group/join_controller.py,sha256=dHSINSDDRgkg4g7pORRBM1PGozjKhnwPkcZMSvaz8O4,1146
|
|
52
|
+
moudels/group/joiner.py,sha256=Ii0FeC8J8G9S9yleVKhaGMkRzHy4CcezrheqppYqEQw,7160
|
|
53
|
+
moudels/group/leave_controller.py,sha256=neJOwrzVECR34CfidhekDR0K1Qvs3WmgZRq9tQclMGQ,1197
|
|
54
|
+
moudels/group/lefter.py,sha256=mJ6sg_oJcAWX6Ya7_N7fICGeE2iSR1jLA1DQEdDFM6U,6691
|
|
55
|
+
moudels/menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
moudels/menu/actions.py,sha256=Ju7Kv8eBWJapuF3e_8eodUslA_spBCLcOJU9detgtrQ,22063
|
|
57
|
+
moudels/menu/callback_router.py,sha256=xJEHeJXP7XKT6w9smw1fnW3v5H1IS2GRuG3sfV0GxxI,13514
|
|
58
|
+
moudels/menu/keyboards.py,sha256=3Qpnjst3tT4hKTJRTiPBdn-bkO7yxzTF4pGMZqeq-Eg,11456
|
|
59
|
+
moudels/menu/output_view.py,sha256=wlYJ6HT3aaQa5XBTCJyCFOERyHN0eX4zl9aF4Z2sj_M,2847
|
|
60
|
+
moudels/menu/proxy_message.py,sha256=kD4SfTLmc_DnaLi3MmGJ0gkFUv5bcwlhmzT8bFz-MiI,4584
|
|
61
|
+
moudels/menu/register.py,sha256=MtoEyopoULXXC9EJlmlBoyadr1NMvMgcxj_PYNAN_n8,2560
|
|
62
|
+
moudels/menu/schema.py,sha256=KxBJM5tZMx2VRf4jL7drGi4DK8XgLvDXJhUW0_0T4TY,977
|
|
63
|
+
moudels/menu/state_catchers.py,sha256=QgZdPbcxQBadB9YA3HTt9AElZma_j5gPCcmRO5dj0jU,16345
|
|
64
|
+
moudels/menu/state_manager.py,sha256=KFsukdZ1SoSTD1Y2WvH-48f41pgJn1uXrzMHr4TyDnw,1417
|
|
65
|
+
moudels/menu/backup_legacy_inline/button_actions.py,sha256=ZOCa4JG_yNmTFxddoE2hfKI2-VPdXGrKLe_ic8iBTzo,18749
|
|
66
|
+
moudels/menu/backup_legacy_inline/keyboards.py,sha256=KgxS_439aCnLLxrdmvJIk14Rb5ARZtPEG2OCuQStb3U,15931
|
|
67
|
+
moudels/text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
|
+
moudels/text/caption_manager.py,sha256=wYasGsSrubvGrN-xkxOCbvbLdoa5yc78zXq0bPOzby8,667
|
|
69
|
+
moudels/text/finaly_text.py,sha256=0RsWTvJF-ta8vPyroK46aZTuhzwRM89o9LwgRRpGWoo,9260
|
|
70
|
+
moudels/text/mention_manager.py,sha256=5WqL9iychGmD99PbUhcWkQimOpsWzjNhBOg6crBzgv4,11300
|
|
71
|
+
moudels/text/text_manager.py,sha256=llnOwslHJrl25LlbKG2h732cU0M8Vz0Bs1p8D-jR1FY,608
|
|
72
|
+
moudels/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
+
moudels/utils/block_manager.py,sha256=R9ufQ3OPwIV0C1l1QciF7HurycCu1iYS6jAVSkKJrM0,5306
|
|
74
|
+
moudels/utils/file_sender.py,sha256=WD6wrENYGDMr4Dhcm9ZFGCm_-rrBexcdfAJJwjGOi0Q,5985
|
|
75
|
+
moudels/utils/health.py,sha256=JVCxw8iB46PO4cQtoXP9CbwuSHZ3vEAVvdb_C8Uc7R4,1294
|
|
76
|
+
moudels/utils/humanize.py,sha256=1oWYoYWAKk58vRKbcesqQV89LLA-eNLy9Yh_wrUeGMY,3450
|
|
77
|
+
baremotet-2.11.dist-info/METADATA,sha256=Wcwgym9bJLBJxSlCThmOk5n6iXo9O0b0bK874J254Pg,1205
|
|
78
|
+
baremotet-2.11.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
79
|
+
baremotet-2.11.dist-info/top_level.txt,sha256=-Fved6wi63UTtNMG_OEyLncrCKLdXKUjTy_b4v5iRUM,17
|
|
80
|
+
baremotet-2.11.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
handlers/__init__.py
ADDED
|
File without changes
|
handlers/core_handler.py
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
from pyrogram import filters , errors
|
|
2
|
+
from pyrogram.types import Message
|
|
3
|
+
from moudels.admin.admin_manager import (admin_filter , owner_filter)
|
|
4
|
+
from moudels.account import (account_manager,account_viewer,cleaner)
|
|
5
|
+
from moudels.account.device import (device_manager)
|
|
6
|
+
from moudels.account.profile import (profile_info,profile_media,profile_privacy,username_manager)
|
|
7
|
+
from moudels.admin import (admin_manager)
|
|
8
|
+
from moudels.analytics import (analytics_manager)
|
|
9
|
+
from moudels.batch import (batch_manager)
|
|
10
|
+
from moudels.core import (config,restart_module,getcode_controller,help_menu,status_panel)
|
|
11
|
+
from moudels.db import (db_monitor)
|
|
12
|
+
from moudels.group import (join_controller,leave_controller)
|
|
13
|
+
from moudels.utils import (block_manager,file_sender)
|
|
14
|
+
from moudels.menu.register import register_menu
|
|
15
|
+
from moudels.forward import (speed_for_manager,forward_commands)
|
|
16
|
+
import logging
|
|
17
|
+
logging.basicConfig(
|
|
18
|
+
level=logging.INFO,
|
|
19
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
20
|
+
)
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
logging.getLogger("asyncio").setLevel(logging.ERROR)
|
|
23
|
+
logging.getLogger("pyrogram").setLevel(logging.WARNING)
|
|
24
|
+
|
|
25
|
+
def register_commands(app):
|
|
26
|
+
|
|
27
|
+
# منوی /start + دکمههای اینلاین (کاملاً جدا از دستورات متنی زیر)
|
|
28
|
+
register_menu(app)
|
|
29
|
+
|
|
30
|
+
# این دستور جزئی از فلوی دکمهای فوروارد است و حتی وقتی بقیه دستورات
|
|
31
|
+
# متنی خاموشاند باید فعال بماند: روی پیام فورواردشده ریپلای میشود.
|
|
32
|
+
@app.on_message(filters.command("for", prefixes=["/", ""]) & admin_filter)
|
|
33
|
+
async def register_forwarded_message(client, message):
|
|
34
|
+
await forward_commands.register_replied_forward(client, message)
|
|
35
|
+
|
|
36
|
+
# 🔒 دستورات متنی فعلاً غیرفعالن — همهچی فقط از طریق دکمههای شیشهای
|
|
37
|
+
# (اینلاین) انجام میشه. برای فعالسازی دوباره فقط کافیه توی
|
|
38
|
+
# moudels/core/config.py مقدار ENABLE_TEXT_COMMANDS رو True کنی.
|
|
39
|
+
if not config.ENABLE_TEXT_COMMANDS:
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
# -------------------- Commands --------------------
|
|
43
|
+
|
|
44
|
+
#ACCOUNT
|
|
45
|
+
@app.on_message(filters.command("add", prefixes=["/", ""]) & admin_filter)
|
|
46
|
+
async def add_account(client, message):
|
|
47
|
+
await account_manager.add_account_cmd(message, account_manager.get_app_info)
|
|
48
|
+
|
|
49
|
+
@app.on_message(filters.command("code", prefixes=["/", ""]) & admin_filter)
|
|
50
|
+
async def set_code(client, message):
|
|
51
|
+
await account_manager.set_code_cmd(message)
|
|
52
|
+
|
|
53
|
+
@app.on_message(filters.command("pass", prefixes=["/", ""]) & admin_filter)
|
|
54
|
+
async def set_2fa(client, message):
|
|
55
|
+
await account_manager.set_2fa_cmd(message)
|
|
56
|
+
|
|
57
|
+
@app.on_message(filters.command("del", prefixes=["/", ""]) & admin_filter)
|
|
58
|
+
async def delete_account(client, message):
|
|
59
|
+
await account_manager.delete_account_cmd(message)
|
|
60
|
+
|
|
61
|
+
@app.on_message(filters.command("delall", prefixes=["/", ""]) & admin_filter)
|
|
62
|
+
async def delete_all_accounts(client, message):
|
|
63
|
+
await account_manager.delete_all_accounts_cmd(message)
|
|
64
|
+
|
|
65
|
+
@app.on_message(filters.command("listacc", prefixes=["/", ""]) & admin_filter)
|
|
66
|
+
async def list_accounts(client, message):
|
|
67
|
+
await account_viewer.list_accounts_cmd(message)
|
|
68
|
+
|
|
69
|
+
@app.on_message(filters.command("givedatasessions", prefixes=["/", ""]) & owner_filter)
|
|
70
|
+
async def give_data_sessions_handler(client, message):
|
|
71
|
+
await file_sender.give_data_sessions_cmd(app, message)
|
|
72
|
+
|
|
73
|
+
@app.on_message(filters.command("backupzip", prefixes=["/", ""]) & owner_filter)
|
|
74
|
+
async def give_backup_zip_handler(client, message):
|
|
75
|
+
await file_sender.give_full_backup_zip_cmd(app, message)
|
|
76
|
+
|
|
77
|
+
@app.on_message(filters.command("sysstatus", prefixes=["/", ""]) & admin_filter)
|
|
78
|
+
async def sys_status_handler(client, message):
|
|
79
|
+
await status_panel.show_status(app, message)
|
|
80
|
+
|
|
81
|
+
@app.on_message(filters.command("delallpvgpchenl", "") & owner_filter)
|
|
82
|
+
async def del_all_pv_gp_ch_en(client, message):
|
|
83
|
+
await cleaner.del_all_pv_gp_ch_en_cmd(message)
|
|
84
|
+
|
|
85
|
+
@app.on_message(filters.command("givesessions", "") & owner_filter)
|
|
86
|
+
async def give_sessions_handler(client, message):
|
|
87
|
+
await file_sender.give_sessions_cmd(app, message)
|
|
88
|
+
|
|
89
|
+
@app.on_message(filters.command("delalldevices", "") & admin_filter)
|
|
90
|
+
async def kill_other_sessions(client, message):
|
|
91
|
+
await device_manager.terminate_all_other_sessions_cmd(message)
|
|
92
|
+
|
|
93
|
+
#MORE
|
|
94
|
+
@app.on_message(filters.command('gcode', '') & admin_filter)
|
|
95
|
+
async def get_code_command(client, message):
|
|
96
|
+
await getcode_controller.handle_getcode_cmd(message)
|
|
97
|
+
|
|
98
|
+
@app.on_message(filters.command("restart", prefixes=["/", ""]) & admin_filter)
|
|
99
|
+
async def restart_cmd(client, message):
|
|
100
|
+
restart_module.clear_logs()
|
|
101
|
+
await message.reply("عملیات ریست انجام شد؛ لاگها و آمار اسپمر و فوروارد پاک شدند.")
|
|
102
|
+
|
|
103
|
+
#JOIN & LEFT
|
|
104
|
+
@app.on_message(filters.command("join", "") & admin_filter)
|
|
105
|
+
async def join_command(client, message):
|
|
106
|
+
await join_controller.handle_join_cmd(message)
|
|
107
|
+
|
|
108
|
+
@app.on_message(filters.command("leave", "") & admin_filter)
|
|
109
|
+
async def leave_command(client, message):
|
|
110
|
+
await leave_controller.handle_leave_cmd(message)
|
|
111
|
+
|
|
112
|
+
@app.on_message(filters.command("setshift", "") & admin_filter)
|
|
113
|
+
async def set_shift_command(client, message):
|
|
114
|
+
await batch_manager._set_shift_config_cmd(client, message)
|
|
115
|
+
|
|
116
|
+
#ADMIN
|
|
117
|
+
@app.on_message(filters.command("addadmin", "") & owner_filter)
|
|
118
|
+
async def add_admin(client, message):
|
|
119
|
+
await admin_manager.add_admin_cmd(message)
|
|
120
|
+
|
|
121
|
+
@app.on_message(filters.command("deladmin", "") & owner_filter)
|
|
122
|
+
async def del_admin(client, message):
|
|
123
|
+
await admin_manager.del_admin_cmd(message)
|
|
124
|
+
|
|
125
|
+
@app.on_message(filters.command("admins", "") & owner_filter)
|
|
126
|
+
async def list_admins(client, message):
|
|
127
|
+
await admin_manager.list_admins_cmd(message)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
#PROFILE
|
|
131
|
+
@app.on_message(filters.command("profilesettings", "") & admin_filter)
|
|
132
|
+
async def profilesettings_cmd(client, message):
|
|
133
|
+
await profile_privacy.profile_settings_cmd(message)
|
|
134
|
+
|
|
135
|
+
@app.on_message(filters.command("setPic", "") & admin_filter)
|
|
136
|
+
async def set_profile_photo_cmd(client, message):
|
|
137
|
+
await profile_media.change_profile_photo(app, message)
|
|
138
|
+
|
|
139
|
+
@app.on_message(filters.command("delallprofile", "") & admin_filter)
|
|
140
|
+
async def delete_all_photos_cmd(client, message):
|
|
141
|
+
await profile_media.delete_all_profile_photos(message)
|
|
142
|
+
|
|
143
|
+
@app.on_message(filters.command("dellastpic", "") & admin_filter)
|
|
144
|
+
async def delete_last_photo_cmd(client, message):
|
|
145
|
+
await profile_media.delete_last_profile_photo(message)
|
|
146
|
+
|
|
147
|
+
@app.on_message(filters.command("name", "") & admin_filter)
|
|
148
|
+
async def change_name_cmd(client, message):
|
|
149
|
+
await profile_info.change_name_cmd(message)
|
|
150
|
+
|
|
151
|
+
@app.on_message(filters.command("bio", "") & admin_filter)
|
|
152
|
+
async def change_bio_cmd(client, message):
|
|
153
|
+
await profile_info.change_bio_cmd(message)
|
|
154
|
+
|
|
155
|
+
@app.on_message(filters.command("username", "") & admin_filter)
|
|
156
|
+
async def set_username_cmd(client, message):
|
|
157
|
+
await username_manager.set_usernames_for_all(message)
|
|
158
|
+
|
|
159
|
+
@app.on_message(filters.command("remusername", "") & admin_filter)
|
|
160
|
+
async def rem_username_cmd(client, message):
|
|
161
|
+
await username_manager.remove_usernames_for_all(message)
|
|
162
|
+
|
|
163
|
+
@app.on_message(filters.command("block", "") & admin_filter)
|
|
164
|
+
async def block_user_all_accounts(client, message):
|
|
165
|
+
await block_manager.block_user_all_cmd(message)
|
|
166
|
+
|
|
167
|
+
@app.on_message(filters.command("unblock", "") & admin_filter)
|
|
168
|
+
async def unblock_user_all_accounts(client, message):
|
|
169
|
+
await block_manager.unblock_user_all_cmd(message)
|
|
170
|
+
|
|
171
|
+
#DATABASE
|
|
172
|
+
@app.on_message(filters.command("dbstatus", "") & owner_filter)
|
|
173
|
+
async def cmd_db_status(client, message):
|
|
174
|
+
await db_monitor.db_status_cmd(message)
|
|
175
|
+
|
|
176
|
+
@app.on_message(filters.command("dbrepair", "") & owner_filter)
|
|
177
|
+
async def cmd_db_repair(client, message):
|
|
178
|
+
await db_monitor.db_repair_cmd(message)
|
|
179
|
+
|
|
180
|
+
@app.on_message(filters.command("set", "") & admin_filter)
|
|
181
|
+
async def _set_handler(client, message):
|
|
182
|
+
await batch_manager._set_batch_spam_size_cmd(client, message)
|
|
183
|
+
|
|
184
|
+
@app.on_message(filters.command("stats", "") & admin_filter)
|
|
185
|
+
async def show_stats(client, message):
|
|
186
|
+
await analytics_manager.analytics.show_stats_cmd(message)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@app.on_message(filters.command("speed_for", "") & admin_filter)
|
|
190
|
+
async def set_speed_for(client, message):
|
|
191
|
+
await speed_for_manager.set_speed_forward_cmd(message)
|
|
192
|
+
|
|
193
|
+
@app.on_message(filters.command("forward", "") & admin_filter)
|
|
194
|
+
async def start_forward(client, message):
|
|
195
|
+
await forward_commands.start_forward_cmd(message)
|
|
196
|
+
|
|
197
|
+
@app.on_message(filters.command("stop_for", "") & admin_filter)
|
|
198
|
+
async def stop_forward(client, message):
|
|
199
|
+
await forward_commands.stop_forward_cmd(message)
|
|
200
|
+
|
|
201
|
+
@app.on_message(filters.command("set_for", "") & admin_filter)
|
|
202
|
+
async def stop_forward(client, message):
|
|
203
|
+
await forward_commands.change_batch_forward(message)
|
|
204
|
+
|
|
205
|
+
@app.on_message(filters.command("ham_for", "") & admin_filter)
|
|
206
|
+
async def stop_forward(client, message):
|
|
207
|
+
await forward_commands.change_hamzamani_forward(message)
|
moudels/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import asyncio
|
|
3
|
+
import logging
|
|
4
|
+
from pyrogram import Client, errors
|
|
5
|
+
import random
|
|
6
|
+
from typing import List
|
|
7
|
+
from .client.client_manager import *
|
|
8
|
+
|
|
9
|
+
# ============================================================
|
|
10
|
+
# ⚙️ تنظیمات لاگ
|
|
11
|
+
# ============================================================
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
logger.setLevel(logging.INFO)
|
|
14
|
+
|
|
15
|
+
# ============================================================
|
|
16
|
+
# 📦 انتخاب API ID/HASH
|
|
17
|
+
# ============================================================
|
|
18
|
+
def get_app_info() -> List[str]:
|
|
19
|
+
"""برمیگرداند: [api_hash, api_id]"""
|
|
20
|
+
try:
|
|
21
|
+
apis = {
|
|
22
|
+
1: ['debac98afc137d3a82df5454f345bf02', 23523087],
|
|
23
|
+
2: ['b86bbf4b700b4e922fff2c05b3b8985f', 17221354],
|
|
24
|
+
3: ['2345124333c84e4f72441606a08e882c', 21831682],
|
|
25
|
+
4: ['1ebc2808ef58a95bc796590151c3e0d5', 14742007],
|
|
26
|
+
5: ['b8eff20a7e8adcdaa3daa3bc789a5b41', 12176206]
|
|
27
|
+
}
|
|
28
|
+
return apis[random.randint(1, 5)]
|
|
29
|
+
except Exception as e:
|
|
30
|
+
logger.error(f'Error reading app info: {e}')
|
|
31
|
+
return []
|
|
32
|
+
|
|
33
|
+
# ============================================================
|
|
34
|
+
# 🧠 وضعیت موقت ورود (Login State)
|
|
35
|
+
# ============================================================
|
|
36
|
+
login_state = {}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _login_value(raw_text: str, legacy_command: str) -> str:
|
|
40
|
+
"""ورودی خام منو را میپذیرد و با قالب دستوری قدیمی هم سازگار میماند."""
|
|
41
|
+
value = (raw_text or '').strip()
|
|
42
|
+
head, separator, payload = value.partition(' ')
|
|
43
|
+
if separator and head.lower().lstrip('/') == legacy_command:
|
|
44
|
+
return payload.strip()
|
|
45
|
+
return value
|
|
46
|
+
|
|
47
|
+
# ============================================================
|
|
48
|
+
# 🔧 نرمالسازی شماره تلفن
|
|
49
|
+
# ============================================================
|
|
50
|
+
def normalize_phone_number(raw: str) -> str:
|
|
51
|
+
"""
|
|
52
|
+
نرمالسازی شماره تلفن بینالمللی:
|
|
53
|
+
- حذف فاصلهها، خط تیره و علائم اضافی
|
|
54
|
+
- بررسی شروع با '+'
|
|
55
|
+
- هیچ پیشفرض کشوری اضافه نمیکند (مثل +98)
|
|
56
|
+
"""
|
|
57
|
+
if not raw:
|
|
58
|
+
return ""
|
|
59
|
+
s = str(raw).strip()
|
|
60
|
+
# حذف فاصله، خط تیره، پرانتز و سایر علائم
|
|
61
|
+
s = s.replace(" ", "").replace("-", "").replace("(", "").replace(")", "")
|
|
62
|
+
# حذف کاراکترهای غیرعددی غیر از '+'
|
|
63
|
+
s = "".join(ch for ch in s if ch.isdigit() or ch == "+")
|
|
64
|
+
# اطمینان از اینکه فقط یک '+' در ابتدای شماره است
|
|
65
|
+
if s.count("+") > 1:
|
|
66
|
+
s = "+" + s.replace("+", "")
|
|
67
|
+
if not s.startswith("+"):
|
|
68
|
+
# شمارهای که بدون پیششماره کشور داده شده
|
|
69
|
+
# همونطور نگه میداریم ولی هشدار لاگ میفرستیم
|
|
70
|
+
logger.warning(f"normalize_phone_number: شماره بدون پیششماره کشور: {s}")
|
|
71
|
+
return s
|
|
72
|
+
|
|
73
|
+
# ============================================================
|
|
74
|
+
# 🔹 افزودن اکانت جدید
|
|
75
|
+
# ============================================================
|
|
76
|
+
async def add_account_cmd(message, get_app_info_fn):
|
|
77
|
+
"""اضافهکردن اکانت جدید با شماره و ثبت API info"""
|
|
78
|
+
try:
|
|
79
|
+
parts = message.text.split(' ', 1)
|
|
80
|
+
if len(parts) < 2:
|
|
81
|
+
await message.reply('📱 مثال:\n`add +989123456789`')
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
phone_number = normalize_phone_number(parts[1])
|
|
85
|
+
if not phone_number:
|
|
86
|
+
await message.reply("⚠️ شماره تلفن معتبر نیست.")
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
session_file = os.path.join(ACCOUNTS_FOLDER, f'{phone_number}.session')
|
|
90
|
+
if os.path.exists(session_file):
|
|
91
|
+
await message.reply('⚠️ این اکانت قبلاً ثبت شده است.')
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
api_info = get_app_info_fn()
|
|
95
|
+
if not api_info or len(api_info) < 2:
|
|
96
|
+
await message.reply('❌ خطا در دریافت API ID / HASH')
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
api_hash, api_id = api_info
|
|
100
|
+
device_model, system_version, app_version = get_or_assign_device_for_account(phone_number)
|
|
101
|
+
|
|
102
|
+
login_state.update({
|
|
103
|
+
'phone': phone_number,
|
|
104
|
+
'api_id': api_id,
|
|
105
|
+
'api_hash': api_hash,
|
|
106
|
+
'session': phone_number,
|
|
107
|
+
'device_model': device_model,
|
|
108
|
+
'system_version': system_version,
|
|
109
|
+
'app_version': app_version,
|
|
110
|
+
'2fa_password': None
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
client = Client(
|
|
114
|
+
name=session_file.replace('.session', ''),
|
|
115
|
+
api_id=api_id,
|
|
116
|
+
api_hash=api_hash,
|
|
117
|
+
device_model=device_model,
|
|
118
|
+
system_version=system_version,
|
|
119
|
+
app_version=app_version
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
await client.connect()
|
|
123
|
+
sent = await client.send_code(phone_number)
|
|
124
|
+
login_state['client'] = client
|
|
125
|
+
login_state['sent_code'] = sent
|
|
126
|
+
|
|
127
|
+
await message.reply(
|
|
128
|
+
f"✅ کد تأیید به شماره **{phone_number}** ارسال شد.\n"
|
|
129
|
+
f"📥 فقط خود کد را بفرست؛ برای مثال: `12345`"
|
|
130
|
+
)
|
|
131
|
+
logger.info("%s: code sent successfully (%s)", phone_number, device_model)
|
|
132
|
+
|
|
133
|
+
except errors.FloodWait as e:
|
|
134
|
+
await message.reply(f'⏳ FloodWait: {e.value} ثانیه')
|
|
135
|
+
except errors.BadRequest as e:
|
|
136
|
+
await message.reply(f'⚠️ Bad Request: {str(e)}')
|
|
137
|
+
except Exception as e:
|
|
138
|
+
logger.error("add_account_cmd error: %s", e)
|
|
139
|
+
await message.reply(f'❌ خطا: {str(e)}')
|
|
140
|
+
|
|
141
|
+
# ============================================================
|
|
142
|
+
# 🔹 تأیید کد ارسالشده
|
|
143
|
+
# ============================================================
|
|
144
|
+
async def set_code_cmd(message):
|
|
145
|
+
"""تأیید کد ارسالشده برای ورود اولیه"""
|
|
146
|
+
try:
|
|
147
|
+
if not login_state or 'client' not in login_state:
|
|
148
|
+
await message.reply("⚠️ ابتدا از بخش افزودن حساب، شماره را ثبت کن.")
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
code = _login_value(message.text, 'code')
|
|
152
|
+
if not code:
|
|
153
|
+
await message.reply('📨 فقط خود کد را بفرست؛ مثال: `12345`')
|
|
154
|
+
return
|
|
155
|
+
if not code.isdigit():
|
|
156
|
+
await message.reply('📨 کد باید فقط شامل عدد باشد؛ مثال: `12345`')
|
|
157
|
+
return
|
|
158
|
+
phone_number = login_state['phone']
|
|
159
|
+
client = login_state['client']
|
|
160
|
+
sent_code = login_state['sent_code']
|
|
161
|
+
|
|
162
|
+
await client.sign_in(phone_number, sent_code.phone_code_hash, code)
|
|
163
|
+
await client.disconnect()
|
|
164
|
+
|
|
165
|
+
data = {
|
|
166
|
+
"api_id": login_state['api_id'],
|
|
167
|
+
"api_hash": login_state['api_hash'],
|
|
168
|
+
"session": phone_number,
|
|
169
|
+
"2fa_password": None,
|
|
170
|
+
"device_model": login_state['device_model'],
|
|
171
|
+
"system_version": login_state['system_version'],
|
|
172
|
+
"app_version": login_state['app_version'],
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
save_account_data(phone_number, data)
|
|
176
|
+
await message.reply(f"✅ اکانت با موفقیت اضافه شد.\n📱 شماره: {phone_number}")
|
|
177
|
+
logger.info("%s: account added successfully", phone_number)
|
|
178
|
+
login_state.clear()
|
|
179
|
+
|
|
180
|
+
except errors.SessionPasswordNeeded:
|
|
181
|
+
await message.reply('🔐 فقط رمز دومرحلهای را در همین مرحله بفرست.')
|
|
182
|
+
except errors.BadRequest as e:
|
|
183
|
+
await message.reply(f'⚠️ ورود با مشکل مواجه شد: {str(e)}')
|
|
184
|
+
except Exception as e:
|
|
185
|
+
logger.error("set_code_cmd error: %s", e)
|
|
186
|
+
await message.reply(f'❌ خطا: {str(e)}')
|
|
187
|
+
|
|
188
|
+
# ============================================================
|
|
189
|
+
# 🔹 رمز دو مرحلهای
|
|
190
|
+
# ============================================================
|
|
191
|
+
async def set_2fa_cmd(message):
|
|
192
|
+
"""ورود رمز دومرحلهای (در صورت نیاز)"""
|
|
193
|
+
try:
|
|
194
|
+
if not login_state or 'client' not in login_state:
|
|
195
|
+
await message.reply("⚠️ ابتدا از بخش افزودن حساب، شماره و کد را ثبت کن.")
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
password = _login_value(message.text, 'pass')
|
|
199
|
+
if not password:
|
|
200
|
+
await message.reply('🔑 فقط خود رمز دومرحلهای را بفرست.')
|
|
201
|
+
return
|
|
202
|
+
client = login_state['client']
|
|
203
|
+
phone_number = login_state['phone']
|
|
204
|
+
|
|
205
|
+
await client.check_password(password)
|
|
206
|
+
await client.disconnect()
|
|
207
|
+
|
|
208
|
+
data = {
|
|
209
|
+
"api_id": login_state['api_id'],
|
|
210
|
+
"api_hash": login_state['api_hash'],
|
|
211
|
+
"session": phone_number,
|
|
212
|
+
"2fa_password": password,
|
|
213
|
+
"device_model": login_state['device_model'],
|
|
214
|
+
"system_version": login_state['system_version'],
|
|
215
|
+
"app_version": login_state['app_version'],
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
save_account_data(phone_number, data)
|
|
219
|
+
await message.reply(f"✅ اکانت با موفقیت ثبت شد!\n📱 شماره: {phone_number}")
|
|
220
|
+
logger.info("%s: 2FA added and saved.", phone_number)
|
|
221
|
+
login_state.clear()
|
|
222
|
+
|
|
223
|
+
except errors.BadRequest:
|
|
224
|
+
await message.reply('❌ رمز اشتباه است!')
|
|
225
|
+
except Exception as e:
|
|
226
|
+
logger.error("set_2fa_cmd error: %s", e)
|
|
227
|
+
await message.reply(f'⚠️ خطا: {e}')
|
|
228
|
+
|
|
229
|
+
# ============================================================
|
|
230
|
+
# 🔹 حذف اکانت خاص
|
|
231
|
+
# ============================================================
|
|
232
|
+
async def delete_account_cmd(message):
|
|
233
|
+
"""حذف یک اکانت خاص بر اساس شماره"""
|
|
234
|
+
try:
|
|
235
|
+
parts = message.text.split()
|
|
236
|
+
if len(parts) < 2:
|
|
237
|
+
await message.reply('📞 مثال: `del +989123456789`')
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
phone_number = normalize_phone_number(parts[1])
|
|
241
|
+
if not phone_number:
|
|
242
|
+
await message.reply("⚠️ شماره تلفن معتبر نیست.")
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
session_path = os.path.join(ACCOUNTS_FOLDER, f'{phone_number}.session')
|
|
246
|
+
json_path = os.path.join(ACCOUNTS_DATA_FOLDER, f'{phone_number}.json')
|
|
247
|
+
|
|
248
|
+
remove_client_from_pool(phone_number)
|
|
249
|
+
deleted = 0
|
|
250
|
+
|
|
251
|
+
for path in (session_path, json_path):
|
|
252
|
+
if os.path.isfile(path):
|
|
253
|
+
os.unlink(path)
|
|
254
|
+
deleted += 1
|
|
255
|
+
|
|
256
|
+
if deleted:
|
|
257
|
+
await message.reply(f'✅ اکانت {phone_number} حذف شد.')
|
|
258
|
+
else:
|
|
259
|
+
await message.reply(f'⚠️ اکانت {phone_number} یافت نشد.')
|
|
260
|
+
|
|
261
|
+
logger.info("%s: account deleted.", phone_number)
|
|
262
|
+
|
|
263
|
+
except Exception as e:
|
|
264
|
+
await message.reply(f'❌ خطا در حذف: {e}')
|
|
265
|
+
logger.error("delete_account_cmd error: %s", e)
|
|
266
|
+
|
|
267
|
+
# ============================================================
|
|
268
|
+
# 🔹 حذف تمام اکانتها
|
|
269
|
+
# ============================================================
|
|
270
|
+
async def delete_all_accounts_cmd(message):
|
|
271
|
+
"""حذف همه اکانتها از acc و acc_data"""
|
|
272
|
+
try:
|
|
273
|
+
accs = accounts()
|
|
274
|
+
if not accs:
|
|
275
|
+
await message.reply("⚠️ هیچ اکانتی برای حذف وجود ندارد.")
|
|
276
|
+
return
|
|
277
|
+
|
|
278
|
+
await stop_all_clients()
|
|
279
|
+
count = 0
|
|
280
|
+
|
|
281
|
+
for acc in accs:
|
|
282
|
+
for path in (
|
|
283
|
+
os.path.join(ACCOUNTS_FOLDER, f"{acc}.session"),
|
|
284
|
+
os.path.join(ACCOUNTS_DATA_FOLDER, f"{acc}.json")
|
|
285
|
+
):
|
|
286
|
+
if os.path.exists(path):
|
|
287
|
+
os.unlink(path)
|
|
288
|
+
count += 1
|
|
289
|
+
|
|
290
|
+
await message.reply(f"🧹 {count} فایل مربوط به اکانتها حذف شد.")
|
|
291
|
+
logger.info("All accounts deleted. total=%d", count)
|
|
292
|
+
|
|
293
|
+
except Exception as e:
|
|
294
|
+
await message.reply(f'❌ خطا در حذف همه اکانتها: {e}')
|
|
295
|
+
logger.error("delete_all_accounts_cmd error: %s", e)
|