understanding commited on
Commit
945e42d
·
verified ·
1 Parent(s): 288ea5d

Update bot/handlers.py

Browse files
Files changed (1) hide show
  1. bot/handlers.py +30 -57
bot/handlers.py CHANGED
@@ -1,5 +1,5 @@
1
  # PATH: bot/handlers.py
2
- import asyncio, json, re
3
  from typing import Dict
4
 
5
  from hydrogram import Client, filters
@@ -14,19 +14,21 @@ from bot.core.auth import is_owner_id, require_allowed
14
  from bot.core.progress import SpeedETA, human_bytes, human_eta
15
  from bot.core.tasks import create_task, set_task
16
 
17
- from bot.integrations.diag_extra import dns_check
18
  from bot.integrations.cf_worker1 import profile_add, profile_list, profile_set_default
19
  from bot.integrations.cf_worker2 import (
20
  allow_user, disallow_user, pick_profile, access_token, record_upload, stats_today
21
  )
22
 
23
  from bot.telegram.media import download_to_temp
24
- from bot.telegram.parse import extract_media_message, extract_title_description
25
  from bot.telegram.replies import safe_reply, safe_edit
26
  from bot.temp.files import cleanup_file
27
 
28
  from bot.youtube.uploader import upload_video
29
 
 
 
 
30
  # ---------- in-memory auth state (simple FSM) ----------
31
  # values: "json" | "ci"
32
  _AWAIT_AUTH: Dict[int, str] = {}
@@ -47,7 +49,7 @@ def setup_handlers(app: Client) -> None:
47
  uid = m.from_user.id if m.from_user else None
48
  await safe_reply(m, f"👤 Your ID: `{uid}`")
49
 
50
- # -------- OWNER allow/disallow via reply OR forward OR id --------
51
  @app.on_message(filters.command(["allow"]) & filters.private)
52
  async def allow_cmd(_: Client, m: Message):
53
  if not is_owner_id(m.from_user.id if m.from_user else None):
@@ -64,12 +66,7 @@ def setup_handlers(app: Client) -> None:
64
  target = int(parts[1])
65
 
66
  if not target:
67
- return await safe_reply(
68
- m,
69
- "Usage:\n"
70
- "• Reply/forward user msg then /allow\n"
71
- "• or /allow <user_id>"
72
- )
73
 
74
  j = await allow_user(target)
75
  await safe_reply(m, f"✅ allowed: `{target}`\n`{j}`")
@@ -82,7 +79,6 @@ def setup_handlers(app: Client) -> None:
82
  parts = (m.text or "").split()
83
  if len(parts) < 2 or not parts[1].isdigit():
84
  return await safe_reply(m, "Usage: /disallow <user_id>")
85
-
86
  target = int(parts[1])
87
  j = await disallow_user(target)
88
  await safe_reply(m, f"✅ disallowed: `{target}`\n`{j}`")
@@ -101,28 +97,19 @@ def setup_handlers(app: Client) -> None:
101
  return await safe_reply(m, texts.OWNER_ONLY)
102
 
103
  from bot.integrations.http import get_client
104
-
105
  c = get_client()
106
- headers = {"User-Agent": "hf-diag/1.0", "Accept": "*/*"}
107
 
108
- # HTTP checks
109
- if not Workers.WORKER1_URL:
110
- r1 = "ERR:missing_WORKER1_URL"
111
- else:
112
- try:
113
- res1 = await c.get(Workers.WORKER1_URL + "/", headers=headers)
114
- r1 = f"{res1.status_code}"
115
- except Exception as e:
116
- r1 = f"ERR:{type(e).__name__}:{e}"
117
 
118
- if not Workers.WORKER2_URL:
119
- r2 = "ERR:missing_WORKER2_URL"
120
- else:
121
- try:
122
- res2 = await c.get(Workers.WORKER2_URL + "/", headers=headers)
123
- r2 = f"{res2.status_code}"
124
- except Exception as e:
125
- r2 = f"ERR:{type(e).__name__}:{e}"
126
 
127
  await safe_reply(
128
  m,
@@ -141,12 +128,13 @@ def setup_handlers(app: Client) -> None:
141
  ok = await require_allowed(uid)
142
  if not ok:
143
  return await safe_reply(m, texts.NOT_ALLOWED)
 
144
  _AWAIT_AUTH.pop(uid, None)
145
  await safe_reply(m, texts.AUTH_MENU, reply_markup=auth_menu_keyboard())
146
 
147
  @app.on_message(filters.command(["cancel"]) & filters.private)
148
  async def cancel_cmd(_: Client, m: Message):
149
- _AWAIT_AUTH.pop(m.from_user.id if m.from_user else 0, None)
150
  await safe_reply(m, texts.CANCELLED)
151
 
152
  @app.on_callback_query()
@@ -157,20 +145,17 @@ def setup_handlers(app: Client) -> None:
157
  if action in (AUTH_JSON, AUTH_CI, CANCEL):
158
  if action == CANCEL:
159
  _AWAIT_AUTH.pop(uid, None)
160
- await q.answer("Cancelled")
161
- return
162
  if action == AUTH_JSON:
163
  _AWAIT_AUTH[uid] = "json"
164
  await q.message.edit_text(texts.ASK_JSON)
165
- await q.answer("Paste JSON")
166
- return
167
  if action == AUTH_CI:
168
  _AWAIT_AUTH[uid] = "ci"
169
  await q.message.edit_text(texts.ASK_ID_SECRET)
170
- await q.answer("Send ID & Secret")
171
- return
172
 
173
- # set default profile callback
174
  if action == "setdef" and value:
175
  if not await require_allowed(uid):
176
  return await q.answer("Not allowed", show_alert=True)
@@ -188,17 +173,13 @@ def setup_handlers(app: Client) -> None:
188
 
189
  await q.answer("OK")
190
 
191
- # -------- auth message sink --------
192
- @app.on_message(
193
- filters.private
194
- & filters.text
195
- & ~filters.command(["start", "ping", "me", "auth", "cancel", "profiles", "stats", "allow", "disallow", "diag"])
196
- )
197
  async def auth_sink(_: Client, m: Message):
198
  uid = m.from_user.id if m.from_user else 0
199
  mode = _AWAIT_AUTH.get(uid)
200
  if not mode:
201
- return # not in auth flow
202
 
203
  try:
204
  if mode == "json":
@@ -209,7 +190,7 @@ def setup_handlers(app: Client) -> None:
209
  if not client_id or not client_secret:
210
  return await safe_reply(m, texts.PARSE_FAIL)
211
  else:
212
- txt = (m.text or "").strip()
213
  parts = [p.strip() for p in re.split(r"[|\n]+", txt) if p.strip()]
214
  if len(parts) < 2:
215
  return await safe_reply(m, texts.PARSE_FAIL)
@@ -239,10 +220,7 @@ def setup_handlers(app: Client) -> None:
239
  profiles = j.get("profiles") or []
240
  txt = f"Default: `{j.get('default_profile_id')}`\n\n"
241
  for p in profiles:
242
- txt += (
243
- f"- `{p['profile_id']}` | {p.get('label')} | "
244
- f"refresh={p.get('has_refresh')} | ch={p.get('channel_title')}\n"
245
- )
246
 
247
  kb = profiles_keyboard(profiles)
248
  await safe_reply(m, txt, reply_markup=kb)
@@ -266,7 +244,6 @@ def setup_handlers(app: Client) -> None:
266
  default_id = pl.get("default_profile_id")
267
  profiles = pl.get("profiles") or []
268
  dp = next((p for p in profiles if p.get("profile_id") == default_id), None)
269
-
270
  if not dp or not dp.get("has_refresh"):
271
  return await safe_reply(m, texts.NEED_AUTH)
272
 
@@ -277,13 +254,11 @@ def setup_handlers(app: Client) -> None:
277
  pick = await pick_profile(uid, channel_id)
278
  if not pick.get("ok"):
279
  return await safe_reply(m, texts.PICK_FAIL.format(pick))
280
-
281
  use_profile_id = pick["profile_id"]
282
 
283
  tok = await access_token(uid, use_profile_id)
284
  if not tok.get("ok"):
285
  return await safe_reply(m, texts.TOKEN_FAIL.format(tok))
286
-
287
  access_tok = tok["access_token"]
288
 
289
  status = await safe_reply(m, texts.UPLOAD_START)
@@ -295,7 +270,6 @@ def setup_handlers(app: Client) -> None:
295
  file_path = ""
296
  try:
297
  file_path, file_size, file_name = await download_to_temp(app_, m)
298
-
299
  title, desc = extract_title_description(m, file_name)
300
 
301
  se = SpeedETA()
@@ -304,7 +278,6 @@ def setup_handlers(app: Client) -> None:
304
  async def prog(done: int, total: int):
305
  nonlocal last_edit
306
  snap = se.update(done, total)
307
- import time
308
  if time.time() - last_edit < 2.0 and done < total:
309
  return
310
  last_edit = time.time()
@@ -316,13 +289,14 @@ def setup_handlers(app: Client) -> None:
316
  await safe_edit(status, txt)
317
 
318
  set_task(task_id, "uploading", "")
 
319
  yt_url = await upload_video(
320
  access_tok,
321
  file_path,
322
  title,
323
  desc,
324
  privacy="private",
325
- progress_cb=prog
326
  )
327
 
328
  await record_upload(uid, use_profile_id)
@@ -333,7 +307,6 @@ def setup_handlers(app: Client) -> None:
333
  except Exception as e:
334
  set_task(task_id, "error", str(e))
335
  await safe_reply(m, f"❌ Upload failed: `{type(e).__name__}: {e}`")
336
-
337
  finally:
338
  if file_path:
339
  cleanup_file(file_path)
 
1
  # PATH: bot/handlers.py
2
+ import asyncio, json, re, time
3
  from typing import Dict
4
 
5
  from hydrogram import Client, filters
 
14
  from bot.core.progress import SpeedETA, human_bytes, human_eta
15
  from bot.core.tasks import create_task, set_task
16
 
 
17
  from bot.integrations.cf_worker1 import profile_add, profile_list, profile_set_default
18
  from bot.integrations.cf_worker2 import (
19
  allow_user, disallow_user, pick_profile, access_token, record_upload, stats_today
20
  )
21
 
22
  from bot.telegram.media import download_to_temp
23
+ from bot.telegram.parse import extract_title_description
24
  from bot.telegram.replies import safe_reply, safe_edit
25
  from bot.temp.files import cleanup_file
26
 
27
  from bot.youtube.uploader import upload_video
28
 
29
+ # ✅ NEW: extra dns helper for /diag
30
+ from bot.integrations.diag_extra import dns_check
31
+
32
  # ---------- in-memory auth state (simple FSM) ----------
33
  # values: "json" | "ci"
34
  _AWAIT_AUTH: Dict[int, str] = {}
 
49
  uid = m.from_user.id if m.from_user else None
50
  await safe_reply(m, f"👤 Your ID: `{uid}`")
51
 
52
+ # -------- OWNER allow/disallow via forward OR id --------
53
  @app.on_message(filters.command(["allow"]) & filters.private)
54
  async def allow_cmd(_: Client, m: Message):
55
  if not is_owner_id(m.from_user.id if m.from_user else None):
 
66
  target = int(parts[1])
67
 
68
  if not target:
69
+ return await safe_reply(m, "Usage:\n• Reply/forward user msg then /allow\n• or /allow <user_id>")
 
 
 
 
 
70
 
71
  j = await allow_user(target)
72
  await safe_reply(m, f"✅ allowed: `{target}`\n`{j}`")
 
79
  parts = (m.text or "").split()
80
  if len(parts) < 2 or not parts[1].isdigit():
81
  return await safe_reply(m, "Usage: /disallow <user_id>")
 
82
  target = int(parts[1])
83
  j = await disallow_user(target)
84
  await safe_reply(m, f"✅ disallowed: `{target}`\n`{j}`")
 
97
  return await safe_reply(m, texts.OWNER_ONLY)
98
 
99
  from bot.integrations.http import get_client
 
100
  c = get_client()
 
101
 
102
+ try:
103
+ r = await c.get((Workers.WORKER1_URL or "") + "/")
104
+ r1 = f"{r.status_code}"
105
+ except Exception as e:
106
+ r1 = f"ERR:{type(e).__name__}:{e}"
 
 
 
 
107
 
108
+ try:
109
+ r = await c.get((Workers.WORKER2_URL or "") + "/")
110
+ r2 = f"{r.status_code}"
111
+ except Exception as e:
112
+ r2 = f"ERR:{type(e).__name__}:{e}"
 
 
 
113
 
114
  await safe_reply(
115
  m,
 
128
  ok = await require_allowed(uid)
129
  if not ok:
130
  return await safe_reply(m, texts.NOT_ALLOWED)
131
+
132
  _AWAIT_AUTH.pop(uid, None)
133
  await safe_reply(m, texts.AUTH_MENU, reply_markup=auth_menu_keyboard())
134
 
135
  @app.on_message(filters.command(["cancel"]) & filters.private)
136
  async def cancel_cmd(_: Client, m: Message):
137
+ _AWAIT_AUTH.pop(m.from_user.id, None)
138
  await safe_reply(m, texts.CANCELLED)
139
 
140
  @app.on_callback_query()
 
145
  if action in (AUTH_JSON, AUTH_CI, CANCEL):
146
  if action == CANCEL:
147
  _AWAIT_AUTH.pop(uid, None)
148
+ return await q.answer("Cancelled")
 
149
  if action == AUTH_JSON:
150
  _AWAIT_AUTH[uid] = "json"
151
  await q.message.edit_text(texts.ASK_JSON)
152
+ return await q.answer("Paste JSON")
 
153
  if action == AUTH_CI:
154
  _AWAIT_AUTH[uid] = "ci"
155
  await q.message.edit_text(texts.ASK_ID_SECRET)
156
+ return await q.answer("Send ID & Secret")
157
+ return
158
 
 
159
  if action == "setdef" and value:
160
  if not await require_allowed(uid):
161
  return await q.answer("Not allowed", show_alert=True)
 
173
 
174
  await q.answer("OK")
175
 
176
+ # message sink for auth states
177
+ @app.on_message(filters.private & filters.text & ~filters.command(["start","ping","me","auth","cancel","profiles","stats","allow","disallow","diag"]))
 
 
 
 
178
  async def auth_sink(_: Client, m: Message):
179
  uid = m.from_user.id if m.from_user else 0
180
  mode = _AWAIT_AUTH.get(uid)
181
  if not mode:
182
+ return
183
 
184
  try:
185
  if mode == "json":
 
190
  if not client_id or not client_secret:
191
  return await safe_reply(m, texts.PARSE_FAIL)
192
  else:
193
+ txt = m.text.strip()
194
  parts = [p.strip() for p in re.split(r"[|\n]+", txt) if p.strip()]
195
  if len(parts) < 2:
196
  return await safe_reply(m, texts.PARSE_FAIL)
 
220
  profiles = j.get("profiles") or []
221
  txt = f"Default: `{j.get('default_profile_id')}`\n\n"
222
  for p in profiles:
223
+ txt += f"- `{p['profile_id']}` | {p.get('label')} | refresh={p.get('has_refresh')} | ch={p.get('channel_title')}\n"
 
 
 
224
 
225
  kb = profiles_keyboard(profiles)
226
  await safe_reply(m, txt, reply_markup=kb)
 
244
  default_id = pl.get("default_profile_id")
245
  profiles = pl.get("profiles") or []
246
  dp = next((p for p in profiles if p.get("profile_id") == default_id), None)
 
247
  if not dp or not dp.get("has_refresh"):
248
  return await safe_reply(m, texts.NEED_AUTH)
249
 
 
254
  pick = await pick_profile(uid, channel_id)
255
  if not pick.get("ok"):
256
  return await safe_reply(m, texts.PICK_FAIL.format(pick))
 
257
  use_profile_id = pick["profile_id"]
258
 
259
  tok = await access_token(uid, use_profile_id)
260
  if not tok.get("ok"):
261
  return await safe_reply(m, texts.TOKEN_FAIL.format(tok))
 
262
  access_tok = tok["access_token"]
263
 
264
  status = await safe_reply(m, texts.UPLOAD_START)
 
270
  file_path = ""
271
  try:
272
  file_path, file_size, file_name = await download_to_temp(app_, m)
 
273
  title, desc = extract_title_description(m, file_name)
274
 
275
  se = SpeedETA()
 
278
  async def prog(done: int, total: int):
279
  nonlocal last_edit
280
  snap = se.update(done, total)
 
281
  if time.time() - last_edit < 2.0 and done < total:
282
  return
283
  last_edit = time.time()
 
289
  await safe_edit(status, txt)
290
 
291
  set_task(task_id, "uploading", "")
292
+
293
  yt_url = await upload_video(
294
  access_tok,
295
  file_path,
296
  title,
297
  desc,
298
  privacy="private",
299
+ progress_cb=prog,
300
  )
301
 
302
  await record_upload(uid, use_profile_id)
 
307
  except Exception as e:
308
  set_task(task_id, "error", str(e))
309
  await safe_reply(m, f"❌ Upload failed: `{type(e).__name__}: {e}`")
 
310
  finally:
311
  if file_path:
312
  cleanup_file(file_path)