CliRemote 1.6.0__py3-none-any.whl → 1.6.1__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.
- {cliremote-1.6.0.dist-info → cliremote-1.6.1.dist-info}/METADATA +1 -1
- {cliremote-1.6.0.dist-info → cliremote-1.6.1.dist-info}/RECORD +7 -7
- remote/client_manager.py +16 -0
- remote/client_picker.py +26 -95
- {cliremote-1.6.0.dist-info → cliremote-1.6.1.dist-info}/WHEEL +0 -0
- {cliremote-1.6.0.dist-info → cliremote-1.6.1.dist-info}/licenses/LICENSE +0 -0
- {cliremote-1.6.0.dist-info → cliremote-1.6.1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
cliremote-1.6.
|
1
|
+
cliremote-1.6.1.dist-info/licenses/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
|
2
2
|
remote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
remote/account_manager.py,sha256=u8yqcyq7Vl8LZ1rNlrEfwlJEbJiBzoSAlL3z2hhTzyc,9829
|
4
4
|
remote/account_viewer.py,sha256=MQoH5lOz24651EjhlzVwi6O5hVUAT7Q5fFU6ZHjBlsM,4243
|
@@ -8,8 +8,8 @@ remote/batch_manager.py,sha256=jVGhYVwHMKJd7f7JxcWjKlwr03dq0RaGD1KdkyYdb00,1051
|
|
8
8
|
remote/block_manager.py,sha256=R7UaQigr-hTRtjxjG3OvJdKhvp0mDpLaESp3Of1AYhs,5692
|
9
9
|
remote/caption_manager.py,sha256=ekgcZ_D1q8C24WP18TXxlM5eWTknJmw-KNXDfqlsnEw,966
|
10
10
|
remote/cleaner.py,sha256=gvPtkosGsf7Eb3zmYyeC44xB4HtCxlzKH3e3qLuVos4,5742
|
11
|
-
remote/client_manager.py,sha256=
|
12
|
-
remote/client_picker.py,sha256=
|
11
|
+
remote/client_manager.py,sha256=lU4e7R_myESbk-uxpfXoro816BZ9TdQcbnuKeJ0rgn4,8908
|
12
|
+
remote/client_picker.py,sha256=DR-Q3Nt_7DoubqGKF0RfGiNtRUftNuvoXLO-MQtCSs0,1427
|
13
13
|
remote/config.py,sha256=VK0e96gEINRViKIq99CYYuYyaVZTLtlWlPKKkBd41Cg,2377
|
14
14
|
remote/device_manager.py,sha256=SUCONe1qa5jMHOMqqS27ATtv3CaqAT8cN9jNi7AI_Go,5813
|
15
15
|
remote/file_sender.py,sha256=5_3ptTkoFejhJhaSyzh-8y5l_k7frxFq9LS_WL5jsGc,3657
|
@@ -32,7 +32,7 @@ remote/stop_manager.py,sha256=UXzKJTblEyQqCjp7fenvQ51Q96Unx05WeOiuFMdj25M,1151
|
|
32
32
|
remote/text_manager.py,sha256=C2wNSXPSCDu8NSD3RsfbKmUQMWOYd1B5N4tzy-Jsriw,2195
|
33
33
|
remote/username_manager.py,sha256=nMNdke-2FIv86xR1Y6rR-43oUoQu_3Khw8wEo54noXI,3388
|
34
34
|
remote/utils/sqlite_utils.py,sha256=5i0oUXsBgKC_8qHZPJ-Gyhp9D1TwqKHVvuZRIhKpS6w,1260
|
35
|
-
cliremote-1.6.
|
36
|
-
cliremote-1.6.
|
37
|
-
cliremote-1.6.
|
38
|
-
cliremote-1.6.
|
35
|
+
cliremote-1.6.1.dist-info/METADATA,sha256=vdb8xaGfPGuE93R9w_LsiWLCoiE4e1H2518ojII1-X4,1202
|
36
|
+
cliremote-1.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
37
|
+
cliremote-1.6.1.dist-info/top_level.txt,sha256=yBZidJ6zCix_a2ubGlYaewvlzBFXWbckQt20dudxJ1E,7
|
38
|
+
cliremote-1.6.1.dist-info/RECORD,,
|
remote/client_manager.py
CHANGED
@@ -229,3 +229,19 @@ def accounts() -> List[str]:
|
|
229
229
|
|
230
230
|
def get_active_accounts() -> Set[str]:
|
231
231
|
return set(accounts())
|
232
|
+
|
233
|
+
|
234
|
+
def remove_client_from_pool(phone_number: str) -> None:
|
235
|
+
"""
|
236
|
+
کلاینت را از pool خارج و stop میکند (بهصورت غیرمسدودکننده).
|
237
|
+
"""
|
238
|
+
cli = client_pool.get(phone_number)
|
239
|
+
if cli is not None:
|
240
|
+
try:
|
241
|
+
asyncio.create_task(cli.stop())
|
242
|
+
logger.info("%s: scheduled stop()", phone_number)
|
243
|
+
except Exception as e:
|
244
|
+
logger.warning("%s: stop() scheduling error: %s: %s", phone_number, type(e).__name__, e)
|
245
|
+
client_pool.pop(phone_number, None)
|
246
|
+
client_locks.pop(phone_number, None)
|
247
|
+
logger.info("%s: removed from client_pool and client_locks", phone_number)
|
remote/client_picker.py
CHANGED
@@ -1,109 +1,40 @@
|
|
1
|
-
# remote/client_picker.py
|
2
1
|
import random
|
3
|
-
import asyncio
|
4
2
|
import logging
|
5
|
-
from typing import Optional
|
3
|
+
from typing import Optional
|
4
|
+
from .client_manager import client_pool, get_active_accounts, get_or_start_client
|
6
5
|
|
7
6
|
logger = logging.getLogger(__name__)
|
8
7
|
|
9
|
-
|
10
|
-
# تلاش میکنیم client_manager را حتماً داشته باشیم
|
11
|
-
from . import client_manager
|
12
|
-
|
13
|
-
# get_active() را بهصورت ایمن تعیین میکنیم:
|
14
|
-
def _resolve_get_active() -> Callable[[], Iterable[str]]:
|
8
|
+
async def get_any_client(message=None) -> Optional[object]:
|
15
9
|
"""
|
16
|
-
|
17
|
-
1)
|
18
|
-
2)
|
19
|
-
3) account_manager.accounts() (fallback)
|
20
|
-
4) client_manager.accounts() (fallback)
|
21
|
-
و در نهایت اگر هیچکدام نبود، یک فانکشنِ خالی برمیگرداند.
|
10
|
+
یک کلاینت آماده برمیگرداند:
|
11
|
+
1) اگر کلاینت متصل در pool هست، همان را برمیگرداند.
|
12
|
+
2) وگرنه از بین active_accounts یکی را استارت میکند.
|
22
13
|
"""
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
return account_manager.get_active_accounts
|
32
|
-
if hasattr(account_manager, "accounts"):
|
33
|
-
return lambda: set(account_manager.accounts())
|
34
|
-
except Exception:
|
35
|
-
pass
|
36
|
-
|
37
|
-
# 3) fallback به client_manager.accounts
|
38
|
-
if hasattr(client_manager, "accounts"):
|
39
|
-
return lambda: set(client_manager.accounts())
|
40
|
-
|
41
|
-
# 4) آخرین fallback: لیست خالی
|
42
|
-
return lambda: set()
|
43
|
-
|
44
|
-
_get_active_accounts = _resolve_get_active()
|
45
|
-
|
46
|
-
|
47
|
-
async def get_any_client(message=None, max_attempts: int = 3) -> Optional[object]:
|
48
|
-
"""
|
49
|
-
تلاش برای گرفتن یک کلاینت فعال از بین اکانتها.
|
50
|
-
- تا `max_attempts` بار با اکانتهای تصادفی امتحان میکند.
|
51
|
-
- اگر موفق نشد، پیام خطا (در صورت وجود message) ارسال میکند،
|
52
|
-
سپس stop_all_clients() فراخوانی میشود و در نهایت None برمیگرداند.
|
53
|
-
"""
|
54
|
-
try:
|
55
|
-
acc_iter = _get_active_accounts()
|
56
|
-
acc_list = list(acc_iter) if not isinstance(acc_iter, (list, set, tuple)) else list(acc_iter)
|
57
|
-
except Exception as e:
|
58
|
-
logger.error(f"❌ نتوانستم لیست اکانتها را بگیرم: {type(e).__name__} - {e}")
|
59
|
-
acc_list = []
|
14
|
+
# Use any connected client
|
15
|
+
for phone, cli in list(client_pool.items()):
|
16
|
+
try:
|
17
|
+
if getattr(cli, "is_connected", False):
|
18
|
+
logger.debug("get_any_client: using connected client %s", phone)
|
19
|
+
return cli
|
20
|
+
except Exception:
|
21
|
+
pass
|
60
22
|
|
61
|
-
if
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
except Exception:
|
66
|
-
pass
|
67
|
-
logger.warning("⚠️ هیچ اکانت فعالی در دسترس نیست.")
|
23
|
+
# Start one if needed
|
24
|
+
accs = list(get_active_accounts())
|
25
|
+
if not accs:
|
26
|
+
logger.warning("get_any_client: no active accounts")
|
68
27
|
return None
|
69
28
|
|
70
|
-
|
71
|
-
|
72
|
-
for attempt in range(1, max_attempts + 1):
|
73
|
-
if len(tried) == len(acc_list):
|
74
|
-
break
|
75
|
-
|
76
|
-
phone = random.choice([p for p in acc_list if p not in tried])
|
77
|
-
tried.add(phone)
|
78
|
-
logger.info(f"🔁 تلاش {attempt}/{max_attempts} برای اتصال با اکانت {phone}")
|
79
|
-
|
29
|
+
random.shuffle(accs)
|
30
|
+
for phone in accs:
|
80
31
|
try:
|
81
|
-
cli = await
|
82
|
-
if cli and getattr(cli, "is_connected",
|
83
|
-
logger.info(
|
32
|
+
cli = await get_or_start_client(phone)
|
33
|
+
if cli and getattr(cli, "is_connected", False):
|
34
|
+
logger.info("get_any_client: started %s", phone)
|
84
35
|
return cli
|
85
|
-
else:
|
86
|
-
logger.warning(f"⚠️ اکانت {phone} وصل نیست یا کلاینت معتبر برنگشته.")
|
87
36
|
except Exception as e:
|
88
|
-
logger.
|
89
|
-
try:
|
90
|
-
await asyncio.sleep(1)
|
91
|
-
except Exception:
|
92
|
-
pass
|
93
|
-
|
94
|
-
# شکست پس از تلاشها
|
95
|
-
error_msg = f"❌ هیچ کلاینت فعالی پس از {max_attempts} تلاش یافت نشد. در حال ریست کامل کلاینتها..."
|
96
|
-
if message:
|
97
|
-
try:
|
98
|
-
await message.reply(error_msg)
|
99
|
-
except Exception:
|
100
|
-
pass
|
101
|
-
logger.error(error_msg)
|
102
|
-
|
103
|
-
try:
|
104
|
-
await client_manager.stop_all_clients()
|
105
|
-
logger.warning("🔄 تمام کلاینتها ریست شدند (stop_all_clients فراخوانی شد).")
|
106
|
-
except Exception as e:
|
107
|
-
logger.error(f"⚠️ خطا در ریست کلاینتها: {type(e).__name__} - {e}")
|
37
|
+
logger.warning("get_any_client: failed start %s: %s: %s", phone, type(e).__name__, e)
|
108
38
|
|
109
|
-
|
39
|
+
logger.error("get_any_client: could not get any client")
|
40
|
+
return None
|
File without changes
|
File without changes
|
File without changes
|