CliRemote 1.7.1__py3-none-any.whl → 1.7.3__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.7.1.dist-info → cliremote-1.7.3.dist-info}/METADATA +1 -1
- {cliremote-1.7.1.dist-info → cliremote-1.7.3.dist-info}/RECORD +7 -7
- remote/account_manager.py +134 -133
- remote/client_manager.py +10 -1
- {cliremote-1.7.1.dist-info → cliremote-1.7.3.dist-info}/WHEEL +0 -0
- {cliremote-1.7.1.dist-info → cliremote-1.7.3.dist-info}/licenses/LICENSE +0 -0
- {cliremote-1.7.1.dist-info → cliremote-1.7.3.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
cliremote-1.7.
|
1
|
+
cliremote-1.7.3.dist-info/licenses/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
|
2
2
|
remote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
remote/account_manager.py,sha256=
|
3
|
+
remote/account_manager.py,sha256=TepnGIoE2hU-j_NmU5ByoS-JrboE0w3A1bYmQoQX5h8,15176
|
4
4
|
remote/account_viewer.py,sha256=MQoH5lOz24651EjhlzVwi6O5hVUAT7Q5fFU6ZHjBlsM,4243
|
5
5
|
remote/admin_manager.py,sha256=WiUUVmSs5JTUdXeSry8PkK_3TRemAdSZjm0G1ilAA-A,3532
|
6
6
|
remote/analytics_manager.py,sha256=6jPvwt_ELA4RMbQdD8W_ltfAoaSgILnEkOAp6HZAqsU,7382
|
@@ -8,7 +8,7 @@ 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=
|
11
|
+
remote/client_manager.py,sha256=KlioRqudGOgrwkY9buLXku2NfSib_aSWdLcquqM0VsI,10617
|
12
12
|
remote/client_picker.py,sha256=6WDIabYhcXSwcCAuRUfJfh6V1ZXP2EiFdAnutK2qLTk,139
|
13
13
|
remote/config.py,sha256=VK0e96gEINRViKIq99CYYuYyaVZTLtlWlPKKkBd41Cg,2377
|
14
14
|
remote/device_manager.py,sha256=SUCONe1qa5jMHOMqqS27ATtv3CaqAT8cN9jNi7AI_Go,5813
|
@@ -33,7 +33,7 @@ remote/text_manager.py,sha256=C2wNSXPSCDu8NSD3RsfbKmUQMWOYd1B5N4tzy-Jsriw,2195
|
|
33
33
|
remote/username_manager.py,sha256=nMNdke-2FIv86xR1Y6rR-43oUoQu_3Khw8wEo54noXI,3388
|
34
34
|
remote/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
35
|
remote/utils/sqlite_utils.py,sha256=5i0oUXsBgKC_8qHZPJ-Gyhp9D1TwqKHVvuZRIhKpS6w,1260
|
36
|
-
cliremote-1.7.
|
37
|
-
cliremote-1.7.
|
38
|
-
cliremote-1.7.
|
39
|
-
cliremote-1.7.
|
36
|
+
cliremote-1.7.3.dist-info/METADATA,sha256=Eg6FmuyJfEq7dKMB4353tFqg_7tB1uQAH-OX5DJ2FoQ,1202
|
37
|
+
cliremote-1.7.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
38
|
+
cliremote-1.7.3.dist-info/top_level.txt,sha256=yBZidJ6zCix_a2ubGlYaewvlzBFXWbckQt20dudxJ1E,7
|
39
|
+
cliremote-1.7.3.dist-info/RECORD,,
|
remote/account_manager.py
CHANGED
@@ -245,149 +245,150 @@ def accounts() -> List[str]:
|
|
245
245
|
def get_active_accounts() -> Set[str]:
|
246
246
|
return set(accounts())
|
247
247
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
"""
|
248
|
+
|
249
|
+
login = {}
|
250
|
+
|
251
|
+
# ==========================
|
252
|
+
# افزودن اکانت جدید
|
253
|
+
# ==========================
|
254
|
+
async def add_account_cmd(message, get_app_info):
|
256
255
|
try:
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
await message.reply_text("⚠️ لطفاً شماره تلفن اکانت را وارد کنید:\n`/del 989123456789`")
|
256
|
+
parts = message.text.split(' ', 1)
|
257
|
+
if len(parts) < 2:
|
258
|
+
await message.reply('مثال: `add +989123456789`')
|
261
259
|
return
|
262
260
|
|
263
|
-
phone_number =
|
264
|
-
|
265
|
-
|
266
|
-
if
|
267
|
-
await message.
|
261
|
+
phone_number = parts[1].strip()
|
262
|
+
session_file = os.path.join(ACCOUNTS_FOLDER, f'{phone_number}.session')
|
263
|
+
|
264
|
+
if os.path.exists(session_file):
|
265
|
+
await message.reply('این اکانت وجود دارد!')
|
268
266
|
return
|
269
267
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
except Exception as e:
|
299
|
-
logger.error(f"{phone_number}: ⚠️ Error deleting session file {session_file} - {e}")
|
300
|
-
|
301
|
-
# حذف فایل دادههای اکانت
|
302
|
-
data_file = os.path.join(ACCOUNTS_DATA_FOLDER, f"{phone_number}.json")
|
303
|
-
if os.path.exists(data_file):
|
304
|
-
try:
|
305
|
-
os.remove(data_file)
|
306
|
-
data_deleted = True
|
307
|
-
logger.info(f"{phone_number}: 🗑️ Account data deleted → {data_file}")
|
308
|
-
except Exception as e:
|
309
|
-
logger.error(f"{phone_number}: ⚠️ Error deleting account data {data_file} - {e}")
|
310
|
-
|
311
|
-
# ارسال نتیجه به کاربر
|
312
|
-
if session_deleted or data_deleted:
|
313
|
-
await message.reply_text(f"✅ اکانت `{phone_number}` با موفقیت حذف شد.\n"
|
314
|
-
f"• فایل session: {'✅' if session_deleted else '❌'}\n"
|
315
|
-
f"• فایل داده: {'✅' if data_deleted else '❌'}")
|
316
|
-
logger.info(f"{phone_number}: ✅ Account deletion completed.")
|
317
|
-
else:
|
318
|
-
await message.reply_text(f"⚠️ هیچ فایلی برای اکانت `{phone_number}` یافت نشد.")
|
319
|
-
|
268
|
+
global login
|
269
|
+
api = get_app_info()
|
270
|
+
if not api or len(api) < 2:
|
271
|
+
await message.reply('مشکل در API!')
|
272
|
+
return
|
273
|
+
|
274
|
+
login['id'] = int(api[1])
|
275
|
+
login['hash'] = api[0]
|
276
|
+
login['number'] = phone_number
|
277
|
+
login['api_data'] = {
|
278
|
+
'api_id': api[1],
|
279
|
+
'api_hash': api[0],
|
280
|
+
'phone_number': phone_number,
|
281
|
+
'session': phone_number,
|
282
|
+
'2fa_password': None
|
283
|
+
}
|
284
|
+
|
285
|
+
try:
|
286
|
+
login['client'] = Client(name=session_file.replace('.session', ''), api_id=login['id'], api_hash=login['hash'])
|
287
|
+
await login['client'].connect()
|
288
|
+
login['response'] = await login['client'].send_code(phone_number)
|
289
|
+
await message.reply(f'✅ کد تأیید به {phone_number} ارسال شد.\n`code 12345`')
|
290
|
+
except errors.BadRequest as e:
|
291
|
+
await message.reply(f'Bad request: {str(e)}')
|
292
|
+
except errors.FloodWait as e:
|
293
|
+
await message.reply(f'Flood wait: {e.value} sec')
|
294
|
+
except Exception as e:
|
295
|
+
await message.reply(f'Connection error: {str(e)}')
|
320
296
|
except Exception as e:
|
321
|
-
|
322
|
-
logger.error(f"delete_account_cmd error: {traceback.format_exc()}")
|
323
|
-
await message.reply_text(error_msg)
|
297
|
+
await message.reply(f'خطا: {str(e)}')
|
324
298
|
|
325
299
|
|
326
|
-
#
|
327
|
-
#
|
328
|
-
#
|
329
|
-
async def
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
300
|
+
# ==========================
|
301
|
+
# تأیید کد ورود
|
302
|
+
# ==========================
|
303
|
+
async def set_code_cmd(message):
|
304
|
+
global login
|
305
|
+
parts = message.text.split(' ', 1)
|
306
|
+
if len(parts) < 2:
|
307
|
+
await message.reply('`code 12345`')
|
308
|
+
return
|
309
|
+
code = parts[1].strip()
|
310
|
+
|
334
311
|
try:
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
312
|
+
await login['client'].sign_in(login['number'], login['response'].phone_code_hash, code)
|
313
|
+
await login['client'].disconnect()
|
314
|
+
save_account_data(login['number'], login['api_data'])
|
315
|
+
await message.reply(f"✅ اکانت اضافه شد!\n├ شماره: {login['number']}")
|
316
|
+
login = {}
|
317
|
+
except errors.SessionPasswordNeeded:
|
318
|
+
await message.reply('🔒 لطفا رمز را با `pass your_password` بدهید')
|
319
|
+
except errors.BadRequest:
|
320
|
+
await message.reply('ورود با مشکل مواجه شد')
|
321
|
+
except Exception as e:
|
322
|
+
await message.reply(f'⚠️ خطا در ورود: {e}')
|
344
323
|
|
345
|
-
# توقف تمام کلاینتها
|
346
|
-
await stop_all_clients()
|
347
324
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
file_path = os.path.join(ACCOUNTS_DATA_FOLDER, filename)
|
371
|
-
os.remove(file_path)
|
372
|
-
deleted_data_files += 1
|
373
|
-
logger.info(f"🗑️ Account data deleted → {filename}")
|
374
|
-
except Exception as e:
|
375
|
-
logger.error(f"⚠️ Error deleting account data {filename} - {e}")
|
376
|
-
|
377
|
-
# پاک کردن کش داخلی
|
378
|
-
client_pool.clear()
|
379
|
-
client_locks.clear()
|
380
|
-
|
381
|
-
# ارسال نتیجه به کاربر
|
382
|
-
result_msg = (f"✅ **حذف کامل اکانتها انجام شد**\n\n"
|
383
|
-
f"• تعداد فایلهای session حذف شده: `{deleted_sessions}`\n"
|
384
|
-
f"• تعداد فایلهای داده حذف شده: `{deleted_data_files}`\n"
|
385
|
-
f"• تعداد اکانتهای شناسایی شده: `{len(all_accounts)}`")
|
386
|
-
|
387
|
-
await message.reply_text(result_msg)
|
388
|
-
logger.info(f"🎯 All accounts deletion completed: {deleted_sessions} sessions, {deleted_data_files} data files")
|
325
|
+
# ==========================
|
326
|
+
# افزودن رمز دومرحلهای
|
327
|
+
# ==========================
|
328
|
+
async def set_2fa_cmd(message):
|
329
|
+
global login
|
330
|
+
parts = message.text.split(' ', 1)
|
331
|
+
if len(parts) < 2:
|
332
|
+
await message.reply('`pass my_password`')
|
333
|
+
return
|
334
|
+
password = parts[1].strip()
|
335
|
+
try:
|
336
|
+
await login['client'].check_password(password)
|
337
|
+
login['api_data']['2fa_password'] = password
|
338
|
+
save_account_data(login['number'], login['api_data'])
|
339
|
+
await message.reply(f"✅ اکانت با موفقیت اضافه شد!\n├ شماره: {login['number']}")
|
340
|
+
await login['client'].disconnect()
|
341
|
+
login = {}
|
342
|
+
except errors.BadRequest:
|
343
|
+
await message.reply('رمز اشتباه است!')
|
344
|
+
except Exception as e:
|
345
|
+
await message.reply(f'⚠️ خطا در ثبت پسورد: {e}')
|
346
|
+
|
389
347
|
|
348
|
+
# ==========================
|
349
|
+
# حذف یک اکانت خاص
|
350
|
+
# ==========================
|
351
|
+
def remove_client_from_pool(phone_number: str):
|
352
|
+
cli = client_pool.get(phone_number)
|
353
|
+
if cli:
|
354
|
+
try:
|
355
|
+
asyncio.create_task(cli.stop())
|
356
|
+
except:
|
357
|
+
pass
|
358
|
+
client_pool.pop(phone_number, None)
|
359
|
+
client_locks.pop(phone_number, None)
|
360
|
+
|
361
|
+
|
362
|
+
async def delete_account_cmd(message):
|
363
|
+
try:
|
364
|
+
phone_number = message.text.split()[1]
|
365
|
+
main_path = f'{ACCOUNTS_FOLDER}/{phone_number}.session'
|
366
|
+
remove_client_from_pool(phone_number)
|
367
|
+
if os.path.isfile(main_path):
|
368
|
+
os.unlink(main_path)
|
369
|
+
await message.reply('<b>Account deleted successfully.</b>')
|
370
|
+
else:
|
371
|
+
await message.reply('<b>Account not found in database.</b>')
|
372
|
+
except IndexError:
|
373
|
+
await message.reply('Please enter phone number')
|
374
|
+
except Exception as e:
|
375
|
+
await message.reply(f'<b>Error deleting account: {str(e)}</b>')
|
376
|
+
|
377
|
+
|
378
|
+
# ==========================
|
379
|
+
# حذف تمام اکانتها
|
380
|
+
# ==========================
|
381
|
+
async def delete_all_accounts_cmd(message):
|
382
|
+
try:
|
383
|
+
accountss = accounts()
|
384
|
+
count = len(accountss)
|
385
|
+
await stop_all_clients()
|
386
|
+
for session in accountss:
|
387
|
+
main_path = f'{ACCOUNTS_FOLDER}/{session}.session'
|
388
|
+
try:
|
389
|
+
os.unlink(main_path)
|
390
|
+
except Exception:
|
391
|
+
pass
|
392
|
+
await message.reply(f'<b>{count} accounts deleted.</b>')
|
390
393
|
except Exception as e:
|
391
|
-
|
392
|
-
logger.error(f"delete_all_accounts_cmd error: {traceback.format_exc()}")
|
393
|
-
await message.reply_text(error_msg)
|
394
|
+
await message.reply(f'<b>Error deleting all accounts: {str(e)}</b>')
|
remote/client_manager.py
CHANGED
@@ -278,4 +278,13 @@ async def get_any_client(message=None) -> Optional[object]:
|
|
278
278
|
logger.warning("get_any_client: failed start %s: %s: %s", phone, type(e).__name__, e)
|
279
279
|
|
280
280
|
logger.error("get_any_client: could not get any client")
|
281
|
-
return None
|
281
|
+
return None
|
282
|
+
|
283
|
+
def get_app_info() -> List[str]:
|
284
|
+
try:
|
285
|
+
apis = {1: ['debac98afc137d3a82df5454f345bf02', 23523087], 2: ['b86bbf4b700b4e922fff2c05b3b8985f', 17221354], 3: ['2345124333c84e4f72441606a08e882c', 21831682], 4: ['1ebc2808ef58a95bc796590151c3e0d5', 14742007], 5: ['b8eff20a7e8adcdaa3daa3bc789a5b41', 12176206]}
|
286
|
+
return apis[random.randint(1, 5)]
|
287
|
+
except Exception as e:
|
288
|
+
logger.error(f'Error reading app info: {e}')
|
289
|
+
return []
|
290
|
+
|
File without changes
|
File without changes
|
File without changes
|