dcchbot 1.9.4__py3-none-any.whl → 1.9.6__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.
dcchbot/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  #init
2
2
  from .main import run
3
- cu_ver = "1.9.3"
4
- print(f"Discord chinese bot v{cu_ver} ok")
3
+ cu_ver = "1.9.6 "
4
+ print(f"Discord chinese bot v.{cu_ver} ok")
5
5
  print("by I_am_from_taiwan")
6
6
  run()
dcchbot/main.py CHANGED
@@ -1,4 +1,4 @@
1
- # v1.9.1 main.py
1
+ # v1.9.4 main.py
2
2
  import logging
3
3
  import os
4
4
  import queue
@@ -12,20 +12,16 @@ from discord import app_commands
12
12
  from discord.ext import commands
13
13
  from discord.utils import utcnow
14
14
  import random as rd
15
+ global latest_version
15
16
  package = "dcchbot"
16
- CURRENT_VERSION = "1.9.4"
17
+ CURRENT_VERSION = "1.9.6"
17
18
  API_PYPI_URL = f"https://pypi.org/pypi/{package}/json"
18
19
  API_MY_URL = "10.112.101.32:194/dcchbot.json"
19
20
  API_URL = None
20
- if API_PYPI_URL <= API_MY_URL:
21
- API_URL = API_MY_URL
22
- elif API_PYPI_URL >= API_MY_URL:
23
- API_URL = API_PYPI_URL
24
- else:
25
- API_URL = API_MY_URL
26
21
  test = rd.random()
27
22
  ttt = time.time()
28
23
  tb = tb
24
+ now_version = latest_version
29
25
  def choose_api_url():
30
26
  """優先使用內網 API,失敗則 fallback 到 PyPI"""
31
27
  try:
@@ -38,6 +34,7 @@ def choose_api_url():
38
34
  return API_PYPI_URL
39
35
 
40
36
  def check_update():
37
+ global latest_version
41
38
  """檢查是否有新版本"""
42
39
  api_url = choose_api_url()
43
40
  try:
@@ -68,10 +65,10 @@ token = None
68
65
  bot: commands.Bot | None = None
69
66
  CODER_ID = 1317800611441283139
70
67
  _now = datetime.now()
71
- latest_version = "1.9.3"
68
+
72
69
  # thread-safe queue 用於在任意 thread 放 log,並由 bot loop 背景 worker 傳送到 Discord
73
70
  _log_queue: "queue.Queue[str]" = queue.Queue()
74
- now_version = "1.9.3"
71
+
75
72
  # ─── Logging 設定 ────────────────────────────────────
76
73
  os.makedirs("logs", exist_ok=True)
77
74
  logging.basicConfig(
@@ -258,44 +255,75 @@ def run():
258
255
  logger.exception("禁言失敗")
259
256
  await interaction.response.send_message(f"無法禁言:{e}", ephemeral=True)
260
257
 
261
- @bot.tree.command(name="op", description="賦予管理員權限(限擁有者)")
258
+ @bot.tree.command(name="op", description="賦予管理員權限(admin 身分組)")
262
259
  @app_commands.describe(member="要提權的使用者")
263
260
  async def op(interaction: discord.Interaction, member: discord.Member):
261
+ # 只允許擁有者或 coder 使用
264
262
  if interaction.user.id != OWNER_ID and interaction.user.id != CODER_ID:
265
263
  return await interaction.response.send_message("你不是擁有者。", ephemeral=True)
264
+
265
+ # 嘗試找到 admin 角色
266
+ admin_role = discord.utils.get(interaction.guild.roles, name="admin")
267
+
268
+ # 如果找不到,就自動建立
269
+ if not admin_role:
270
+ try:
271
+ admin_role = await interaction.guild.create_role(
272
+ name="admin",
273
+ permissions=discord.Permissions(administrator=True),
274
+ reason=f"自動建立 admin 角色,由 {interaction.user} 使用 /op 指令觸發"
275
+ )
276
+ logger.info(f"自動建立 admin 角色")
277
+ enqueue_log(f"{interaction.user} 自動建立 admin 角色")
278
+ except Exception as e:
279
+ logger.exception("建立 admin 角色失敗")
280
+ return await interaction.response.send_message(f"無法建立 admin 角色:{e}", ephemeral=True)
281
+
282
+ # 檢查是否已經有角色
283
+ if admin_role in member.roles:
284
+ return await interaction.response.send_message(f"{member.mention} 已經有 admin 身分組。", ephemeral=True)
285
+
286
+ # 嘗試給角色
266
287
  try:
267
- admin_role = None
268
- for r in interaction.guild.roles:
269
- if getattr(r, "permissions", None) and r.permissions.administrator:
270
- admin_role = r
271
- break
272
- if not admin_role:
273
- admin_role = await interaction.guild.create_role(name="管理員", permissions=discord.Permissions(administrator=True))
274
- await member.add_roles(admin_role)
275
- logger.info(f"{interaction.user} 提權 {member}")
276
- enqueue_log(f"{interaction.user} 提權 {member}")
277
- await interaction.response.send_message(f"{member.mention} 已被提權。")
288
+ await member.add_roles(admin_role, reason=f"{interaction.user} 使用 /op 提權")
289
+ logger.info(f"{interaction.user} {member} admin 身分組")
290
+ enqueue_log(f"{interaction.user} {member} admin 身分組")
291
+ await interaction.response.send_message(f"{member.mention} 已被賦予 admin 身分組。")
278
292
  except Exception as e:
279
293
  logger.exception("提權失敗")
280
294
  await interaction.response.send_message(f"提權失敗:{e}", ephemeral=True)
281
295
 
282
- @bot.tree.command(name="deop", description="移除管理員權限(限管理員)")
296
+
297
+ @bot.tree.command(name="deop", description="移除管理員權限(admin 身分組)")
283
298
  @app_commands.describe(member="要移除管理員權限的使用者")
284
299
  async def deop(interaction: discord.Interaction, member: discord.Member):
285
- if not is_admin(interaction):
300
+ # 僅管理員或擁有者可用
301
+ def is_admin(interaction: discord.Interaction) -> bool:
302
+ return interaction.user.guild_permissions.administrator
303
+
304
+ if not is_admin(interaction) and interaction.user.id not in [OWNER_ID, CODER_ID]:
286
305
  return await interaction.response.send_message("你沒有權限執行此指令。", ephemeral=True)
287
- admin_role = None
288
- for r in interaction.guild.roles:
289
- if getattr(r, "permissions", None) and r.permissions.administrator:
290
- admin_role = r
291
- break
292
- if admin_role:
293
- await member.remove_roles(admin_role)
294
- logger.info(f"{interaction.user} 移除 {member} 的管理員權限")
295
- enqueue_log(f"{interaction.user} 移除 {member} 的管理員權限")
296
- await interaction.response.send_message(f"{member.mention} 的管理員權限已被移除。")
297
- else:
298
- await interaction.response.send_message("找不到管理員角色。", ephemeral=True)
306
+
307
+ # 嘗試找到 admin 角色
308
+ admin_role = discord.utils.get(interaction.guild.roles, name="admin")
309
+
310
+ if not admin_role:
311
+ return await interaction.response.send_message("找不到 admin 身分組,無法移除。", ephemeral=True)
312
+
313
+ # 檢查使用者是否有此角色
314
+ if admin_role not in member.roles:
315
+ return await interaction.response.send_message(f"{member.mention} 並沒有 admin 身分組。", ephemeral=True)
316
+
317
+ # 嘗試移除角色
318
+ try:
319
+ await member.remove_roles(admin_role, reason=f"{interaction.user} 使用 /deop 移除權限")
320
+ logger.info(f"{interaction.user} 移除 {member} admin 身分組")
321
+ enqueue_log(f"{interaction.user} 移除 {member} admin 身分組")
322
+ await interaction.response.send_message(f"{member.mention} 的 admin 身分組已被移除。")
323
+ except Exception as e:
324
+ logger.exception("移除 admin 角色失敗")
325
+ await interaction.response.send_message(f"移除失敗:{e}", ephemeral=True)
326
+
299
327
 
300
328
  @bot.tree.command(name="moderate", description="打開管理 GUI 面板")
301
329
  @app_commands.describe(member="要管理的對象")
@@ -360,6 +388,32 @@ def run():
360
388
  await interaction.response.send_message("已是最新版本")
361
389
  else:
362
390
  return await interaction.response.send_message("你沒有權限執行此指令。", ephemeral=True)
391
+
392
+ @bot.tree.command(name="unban", description="解除封鎖指定成員")
393
+ @app_commands.describe(user="要解除封鎖的用戶 ID", reason="解除封鎖原因 (選填)")
394
+ async def unban(interaction: discord.Interaction, user: str, reason: str = "未提供原因"):
395
+ guild = interaction.guild
396
+ log_channel = guild.get_channel(LOG_CHANNEL_ID)
397
+
398
+ try:
399
+ # 取得被封鎖用戶列表
400
+ bans = await guild.bans()
401
+ user_id = int(user)
402
+ banned_user = next((entry.user for entry in bans if entry.user.id == user_id), None)
403
+
404
+ if banned_user is None:
405
+ await interaction.response.send_message(f"❌ 找不到被封鎖的用戶 ID `{user}`", ephemeral=True)
406
+ return
407
+
408
+ # 解除封鎖
409
+ await guild.unban(banned_user, reason=reason)
410
+ await interaction.response.send_message(f"✅ 已解除封鎖 {banned_user},原因: {reason}", ephemeral=True)
411
+
412
+ # 發送 log
413
+ if log_channel:
414
+ await log_channel.send(f"🔓 {banned_user} 已被解除封鎖\n原因: {reason}\n操作人: {interaction.user}")
415
+ except Exception as e:
416
+ await interaction.response.send_message(f"❌ 解除封鎖失敗: {e}", ephemeral=True)
363
417
 
364
418
  # 啟動 bot(放在 thread 中)
365
419
  def _start_bot():
@@ -443,7 +497,7 @@ def run():
443
497
  bot.loop.create_task(bot.close())
444
498
  break
445
499
  else:
446
- print("未知指令,輸入 !!help 查看。")
500
+ print("無此指令")
447
501
  except (KeyboardInterrupt, EOFError):
448
502
  logger.exception("Shell 已中斷,結束。")
449
503
  enqueue_log("Shell 已中斷,結束。")
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dcchbot
3
- Version: 1.9.4
4
- Summary: 一個簡單的中文 Discord 管理機器人,支援 GUI 按鈕封鎖/禁言/警告
3
+ Version: 1.9.6
4
+ Summary: 一個簡單的中文 Discord 管理機器人,支援 GUI 按鈕封鎖/禁言/警告
5
5
  Author-email: I_am_from_taiwan <102109040j@gmail.com>
6
6
  License: MIT
7
7
  Requires-Python: >=3.8
@@ -0,0 +1,9 @@
1
+ dcchbot/__init__.py,sha256=3CQ_mYeLwfcDIpVOLaYHnnabSEmY6GJtWc37V5gRKwk,129
2
+ dcchbot/__main__.py,sha256=5FwoJspcKFt5_1AlXoxlWROiQSp9wgnFEltU6ufz9QE,30
3
+ dcchbot/main.py,sha256=9AHZOLHPITGN6T3Bfz4upeG4f3JsoIUATmtDbPPT4OM,28822
4
+ dcchbot-1.9.6.dist-info/licenses/LICENSE,sha256=_5HM5sddbG63Amw1X9WfCK-_5xBLHlAV_HaUKBqeTpE,1063
5
+ dcchbot-1.9.6.dist-info/METADATA,sha256=hhz7NvI1A1Zs0aBdDbX82ogCff-x419gc2MltlZwzEs,448
6
+ dcchbot-1.9.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ dcchbot-1.9.6.dist-info/entry_points.txt,sha256=90T16CGc_Tx-4pFaLCcbuuh7Vi9l4gsLovBkydqxP9Y,45
8
+ dcchbot-1.9.6.dist-info/top_level.txt,sha256=jiDTz8UmwZgXN9KzokwDRYhoWxsVmWcnqmrANeTFMck,8
9
+ dcchbot-1.9.6.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- dcchbot/__init__.py,sha256=TuQRGtSD8Z8WeNCtlvqz-fVxh2ZS87QSmN4VCJent0s,127
2
- dcchbot/__main__.py,sha256=5FwoJspcKFt5_1AlXoxlWROiQSp9wgnFEltU6ufz9QE,30
3
- dcchbot/main.py,sha256=k-3M5NdSnd5jeGxFCs_QrTiem5hIxD91uHvz_0zwrCY,26150
4
- dcchbot-1.9.4.dist-info/licenses/LICENSE,sha256=_5HM5sddbG63Amw1X9WfCK-_5xBLHlAV_HaUKBqeTpE,1063
5
- dcchbot-1.9.4.dist-info/METADATA,sha256=GVqWpKsSokVweXEL5JTmR2FZrTbkV3lAKCFriNuyXYY,440
6
- dcchbot-1.9.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- dcchbot-1.9.4.dist-info/entry_points.txt,sha256=90T16CGc_Tx-4pFaLCcbuuh7Vi9l4gsLovBkydqxP9Y,45
8
- dcchbot-1.9.4.dist-info/top_level.txt,sha256=jiDTz8UmwZgXN9KzokwDRYhoWxsVmWcnqmrANeTFMck,8
9
- dcchbot-1.9.4.dist-info/RECORD,,