CliRemote 1.7.12__py3-none-any.whl → 1.7.13__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CliRemote
3
- Version: 1.7.12
3
+ Version: 1.7.13
4
4
  Summary: Remote client framework for Telegram automation using Pyrogram
5
5
  Home-page: https://github.com/MohammadAhmadi-R/CliRemote
6
6
  Author: MrAhmadiRad
@@ -1,8 +1,8 @@
1
- cliremote-1.7.12.dist-info/licenses/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
1
+ cliremote-1.7.13.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=TepnGIoE2hU-j_NmU5ByoS-JrboE0w3A1bYmQoQX5h8,15176
4
4
  remote/account_viewer.py,sha256=j46KSjbgrBmBi7UxFeJ5tCwHIe0QvCvphkirGIbB2oo,5192
5
- remote/admin_manager.py,sha256=WiUUVmSs5JTUdXeSry8PkK_3TRemAdSZjm0G1ilAA-A,3532
5
+ remote/admin_manager.py,sha256=JXxZ6dEF5xXUcNmLmxuFAAUE7EyHDf0sLutTQYnTlHY,7392
6
6
  remote/analytics_manager.py,sha256=6jPvwt_ELA4RMbQdD8W_ltfAoaSgILnEkOAp6HZAqsU,7382
7
7
  remote/batch_manager.py,sha256=jVGhYVwHMKJd7f7JxcWjKlwr03dq0RaGD1KdkyYdb00,1051
8
8
  remote/block_manager.py,sha256=R7UaQigr-hTRtjxjG3OvJdKhvp0mDpLaESp3Of1AYhs,5692
@@ -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.12.dist-info/METADATA,sha256=5veF0j81-22RdkS8kXAivQFqYCdzKf4uY8Io9WaZchc,1203
37
- cliremote-1.7.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
- cliremote-1.7.12.dist-info/top_level.txt,sha256=yBZidJ6zCix_a2ubGlYaewvlzBFXWbckQt20dudxJ1E,7
39
- cliremote-1.7.12.dist-info/RECORD,,
36
+ cliremote-1.7.13.dist-info/METADATA,sha256=AGkWN4uIhUNz55bPpKmv6t31CJvf53AS2l3uuMsjlJg,1203
37
+ cliremote-1.7.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
+ cliremote-1.7.13.dist-info/top_level.txt,sha256=yBZidJ6zCix_a2ubGlYaewvlzBFXWbckQt20dudxJ1E,7
39
+ cliremote-1.7.13.dist-info/RECORD,,
remote/admin_manager.py CHANGED
@@ -1,32 +1,79 @@
1
1
  # remote/admin_manager.py
2
- import json, os, logging
2
+ import json
3
+ import os
4
+ import sys
5
+ import logging
6
+ from pathlib import Path
3
7
  from pyrogram import filters
4
8
  from .config import OWNER_ID
5
9
 
6
- logger = logging.getLogger(__name__)
10
+ # =============================
11
+ # تنظیم logger فایل
12
+ # =============================
7
13
 
8
- ADMINS_FILE = "admins.json"
14
+ def _project_root() -> Path:
15
+ """ریشه پروژه = پوشه‌ای که main.py داخلش اجرا شده. در صورت عدم دسترسی، از cwd استفاده می‌شود."""
16
+ try:
17
+ main_file = Path(sys.modules["__main__"].__file__).resolve()
18
+ return main_file.parent
19
+ except Exception:
20
+ return Path(os.getcwd()).resolve()
21
+
22
+ _PROJECT_ROOT = _project_root()
23
+ _LOG_DIR = _PROJECT_ROOT / "logs"
24
+ _LOG_DIR.mkdir(parents=True, exist_ok=True)
25
+ _LOG_PATH = _LOG_DIR / "admins_log.txt"
26
+
27
+ # logger اختصاصی این ماژول
28
+ logger = logging.getLogger("remote.admin_manager")
29
+ logger.setLevel(logging.DEBUG)
30
+
31
+ # جلوگیری از افزودن چندباره‌ی هندلر هنگام ریلود
32
+ if not any(isinstance(h, logging.FileHandler) and getattr(h, "_admin_log", False) for h in logger.handlers):
33
+ fh = logging.FileHandler(_LOG_PATH, encoding="utf-8")
34
+ fh._admin_log = True # پرچم داخلی برای تشخیص
35
+ fh.setLevel(logging.DEBUG)
36
+ fmt = logging.Formatter(
37
+ fmt="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
38
+ datefmt="%Y-%m-%d %H:%M:%S"
39
+ )
40
+ fh.setFormatter(fmt)
41
+ logger.addHandler(fh)
42
+
43
+ logger.debug(f"Admin manager initialized. Log path: {_LOG_PATH}")
44
+
45
+ # =============================
46
+ # تنظیمات فایل ادمین‌ها
47
+ # =============================
9
48
 
49
+ ADMINS_FILE = "admins.json" # اگر می‌خواهی کنار main.py باشد: ( _PROJECT_ROOT / "admins.json" ).as_posix()
10
50
 
11
51
  def load_admins() -> list[int]:
12
52
  """
13
53
  بارگذاری لیست ادمین‌ها از فایل.
14
54
  همیشه OWNER_ID را هم به لیست اضافه می‌کند.
15
55
  """
56
+ logger.debug(f"Loading admins from file: {ADMINS_FILE} | OWNER_ID: {OWNER_ID}")
16
57
  s = set(OWNER_ID)
17
58
  try:
18
59
  if os.path.exists(ADMINS_FILE):
19
60
  with open(ADMINS_FILE, "r", encoding="utf-8") as f:
20
61
  data = json.load(f)
62
+ logger.info(f"admins.json loaded. Raw: {data!r}")
21
63
  if isinstance(data, list):
22
64
  for v in data:
23
65
  try:
24
66
  s.add(int(v))
25
- except:
26
- pass
67
+ except Exception as conv_err:
68
+ logger.warning(f"Skip invalid admin id in file: {v!r} | err={conv_err}")
69
+ else:
70
+ logger.info(f"admins.json not found at: {os.path.abspath(ADMINS_FILE)}")
27
71
  except Exception as e:
28
- logger.warning(f"Error loading admins: {e}")
29
- return list(s)
72
+ logger.warning(f"Error loading admins: {e}", exc_info=True)
73
+
74
+ result = sorted(s)
75
+ logger.debug(f"Effective ADMINS after merge with OWNER_ID: {result}")
76
+ return result
30
77
 
31
78
 
32
79
  def save_admins():
@@ -34,78 +81,107 @@ def save_admins():
34
81
  ذخیره‌ی ادمین‌ها در فایل.
35
82
  """
36
83
  try:
84
+ # نکته: در این طراحی، ADMINS شامل OWNER_ID هم می‌تواند باشد؛ مشکلی نیست
85
+ logger.debug(f"Saving ADMINS to file: {ADMINS_FILE} | Data: {ADMINS}")
37
86
  with open(ADMINS_FILE, "w", encoding="utf-8") as f:
38
87
  json.dump(list(ADMINS), f, ensure_ascii=False, indent=2)
88
+ logger.info(f"Admins saved to {os.path.abspath(ADMINS_FILE)}")
39
89
  except Exception as e:
40
- logger.error(f"Error saving admins: {e}")
90
+ logger.error(f"Error saving admins: {e}", exc_info=True)
41
91
 
42
92
 
43
93
  ADMINS = load_admins()
94
+ logger.info(f"Loaded admins at import time: {ADMINS}")
44
95
 
45
96
  # فیلترهای دسترسی برای Pyrogram
46
97
  admin_filter = filters.create(
47
- lambda _, __, m: bool(getattr(m, "from_user", None))
48
- and int(m.from_user.id) in ADMINS
98
+ lambda _, __, m: bool(getattr(m, "from_user", None)) and int(m.from_user.id) in ADMINS
49
99
  )
50
100
  owner_filter = filters.create(
51
- lambda _, __, m: bool(getattr(m, "from_user", None))
52
- and int(m.from_user.id) in OWNER_ID
101
+ lambda _, __, m: bool(getattr(m, "from_user", None)) and int(m.from_user.id) in OWNER_ID
53
102
  )
54
103
 
55
-
56
104
  # =============================
57
105
  # فرمان‌های مدیریتی
58
106
  # =============================
59
107
 
60
108
  async def add_admin_cmd(message):
61
109
  try:
62
- parts = message.text.split()
110
+ uid_display = getattr(getattr(message, "from_user", None), "id", None)
111
+ logger.debug(f"add_admin_cmd triggered by user_id={uid_display} | text={message.text!r}")
112
+
113
+ parts = (message.text or "").split()
63
114
  if len(parts) < 2:
115
+ logger.debug("add_admin_cmd: missing argument")
64
116
  await message.reply("مثال: addadmin 123456789")
65
117
  return
118
+
66
119
  uid = int(parts[1])
120
+ logger.debug(f"add_admin_cmd: parsed target uid={uid}")
121
+
67
122
  if uid in OWNER_ID:
123
+ logger.info(f"add_admin_cmd: uid={uid} is OWNER; skip append")
68
124
  await message.reply("ادمین اصلی از قبل وجود دارد")
69
125
  return
126
+
70
127
  if uid not in ADMINS:
71
128
  ADMINS.append(uid)
129
+ logger.info(f"Admin appended: {uid} | New ADMINS={sorted(ADMINS)}")
72
130
  save_admins()
73
131
  await message.reply(f"ادمین جدید اضافه شد: {uid}")
74
132
  else:
133
+ logger.info(f"add_admin_cmd: uid={uid} already in ADMINS")
75
134
  await message.reply("قبلاً ادمین بود")
76
135
  except Exception as e:
77
- logger.error(f"add_admin_cmd error: {e}")
136
+ logger.error(f"add_admin_cmd error: {e}", exc_info=True)
78
137
  await message.reply(f"خطا: {e}")
79
138
 
80
139
 
81
140
  async def del_admin_cmd(message):
82
141
  try:
83
- parts = message.text.split()
142
+ uid_display = getattr(getattr(message, "from_user", None), "id", None)
143
+ logger.debug(f"del_admin_cmd triggered by user_id={uid_display} | text={message.text!r}")
144
+
145
+ parts = (message.text or "").split()
84
146
  if len(parts) < 2:
147
+ logger.debug("del_admin_cmd: missing argument")
85
148
  await message.reply("مثال: deladmin 123456789")
86
149
  return
150
+
87
151
  uid = int(parts[1])
152
+ logger.debug(f"del_admin_cmd: parsed target uid={uid}")
153
+
88
154
  if uid in OWNER_ID:
155
+ logger.info(f"del_admin_cmd: attempt to remove OWNER uid={uid} blocked")
89
156
  await message.reply("❌ امکان حذف ادمین اصلی وجود ندارد")
90
157
  return
158
+
91
159
  if uid in ADMINS:
92
160
  ADMINS.remove(uid)
161
+ logger.info(f"Admin removed: {uid} | New ADMINS={sorted(ADMINS)}")
93
162
  save_admins()
94
163
  await message.reply(f"ادمین حذف شد: {uid}")
95
164
  else:
165
+ logger.info(f"del_admin_cmd: uid={uid} not in ADMINS")
96
166
  await message.reply("کاربر ادمین نیست")
97
167
  except Exception as e:
98
- logger.error(f"del_admin_cmd error: {e}")
168
+ logger.error(f"del_admin_cmd error: {e}", exc_info=True)
99
169
  await message.reply(f"خطا: {e}")
100
170
 
101
171
 
102
172
  async def list_admins_cmd(message):
103
173
  try:
174
+ uid_display = getattr(getattr(message, "from_user", None), "id", None)
175
+ logger.debug(f"list_admins_cmd triggered by user_id={uid_display}")
176
+
104
177
  if not ADMINS:
178
+ logger.info("list_admins_cmd: ADMINS is empty")
105
179
  await message.reply("لیست ادمین‌ها خالی است.")
106
180
  return
107
- text = "👑 <b>ADMINS:</b>\n" + "\n".join([str(x) for x in ADMINS])
181
+
182
+ text = "👑 <b>ADMINS:</b>\n" + "\n".join([str(x) for x in sorted(ADMINS)])
183
+ logger.debug(f"list_admins_cmd: respond with {len(ADMINS)} admins")
108
184
  await message.reply(text)
109
185
  except Exception as e:
110
- logger.error(f"list_admins_cmd error: {e}")
186
+ logger.error(f"list_admins_cmd error: {e}", exc_info=True)
111
187
  await message.reply(f"خطا: {e}")