Skip to content

Commit f5987c6

Browse files
committed
chore: Always import modules; drop "from" imports
Always import modules instead of variables, functions, classes. Bug: #49 Change-Id: I2b529abbd849ec13c71282b3268e5b4bbee6b5a4
1 parent 18deeed commit f5987c6

34 files changed

Lines changed: 585 additions & 564 deletions

app.py

Lines changed: 122 additions & 133 deletions
Large diffs are not rendered by default.

build/build.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@
33
"""
44

55
# Third-party imports
6-
from discord import Bot
7-
from discord.ext.commands import Cog
6+
import discord
7+
import discord.ext.commands
88

99

10-
class Build(Cog):
10+
class Build(discord.ext.commands.Cog):
1111
"""
1212
Attributes:
13-
bot (Bot): Instance of discord.Bot.
13+
bot (discord.Bot): Instance of discord.Bot.
1414
"""
1515

16-
bot: Bot
16+
bot: discord.Bot
1717
"""
18-
bot (Bot): Instance of discord.Bot.
18+
bot (discord.Bot): Instance of discord.Bot.
1919
"""
2020

21-
def __init__(self, bot: Bot) -> None:
21+
def __init__(self, bot: discord.Bot) -> None:
2222
"""
2323
Constructor function.
2424
2525
Parameters:
26-
bot (Bot): Instance of discord.Bot.
26+
bot (discord.Bot): Instance of discord.Bot.
2727
"""
2828
self.bot = bot

channel_check.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
import asyncio
33
import json
44
import os
5-
from random import choice
5+
import random
66

77
# Third-party imports
88
import discord
99

1010
# Local imports
11-
from cog.core.sql import link_sql
12-
from cog.core.sql import end
11+
import cog.core.sql
1312

1413

1514
def open_json():
@@ -23,10 +22,10 @@ def open_json():
2322

2423

2524
def get_total_points():
26-
connection, cursor = link_sql()
25+
connection, cursor = cog.core.sql.link_sql()
2726
cursor.execute("SELECT SUM(point) FROM `user`")
2827
points = cursor.fetchone()[0]
29-
end(connection, cursor)
28+
cog.core.sql.end(connection, cursor)
3029
return points
3130

3231

@@ -68,6 +67,6 @@ async def change_status(bot):
6867
"debug",
6968
]
7069
while not bot.is_closed():
71-
status = choice(announcements)
70+
status = random.choice(announcements)
7271
await bot.change_presence(activity=discord.Game(name=status))
7372
await asyncio.sleep(10)

cog/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
def setup(bot):
1+
# Third-party imports
2+
import discord
3+
4+
5+
def setup(bot: discord.Bot):
26
pass

cog/admin.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
# Standard imports
2-
# import csv
3-
# from datetime import datetime, timedelta
4-
# import json
5-
# import os
6-
71
# Third-party imports
82
import discord
9-
from build.build import Build
103

114
# Local imports
5+
import build.build
126

137

14-
class ManagerCommand(Build):
8+
class ManagerCommand(build.build.Build):
159
@discord.slash_command(name="reload", description="你是管理員才讓你用")
1610
async def reload(self, ctx, package):
1711
if not ctx.author.guild_permissions.administrator:
@@ -24,14 +18,14 @@ async def reload(self, ctx, package):
2418
async def announce(
2519
self,
2620
ctx,
27-
channel: discord.Option(
21+
channel: discord.abc.GuildChannel = discord.Option(
2822
discord.abc.GuildChannel,
2923
"要發布到的頻道",
3024
# 一般文字頻道與公告頻道都可以選
3125
channel_types=[discord.ChannelType.text, discord.ChannelType.news],
3226
),
33-
content: discord.Option(str, "公告內容,輸入 \\n 可換行"),
34-
ping: discord.Option(
27+
content: str = discord.Option(str, "公告內容,輸入 \\n 可換行"),
28+
ping: str = discord.Option(
3529
str,
3630
"要不要標註大家",
3731
choices=["不標註", "@here", "@everyone"],
@@ -69,5 +63,5 @@ async def announce(
6963
await ctx.respond(f"公告已發布到 {channel.mention}!", ephemeral=True)
7064

7165

72-
def setup(bot):
66+
def setup(bot: discord.Bot):
7367
bot.add_cog(ManagerCommand(bot))

cog/admin_gift.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
# Standard imports
2-
from datetime import datetime
2+
import datetime
33
import traceback
44

55
# Third-party imports
66
import discord
7-
from discord.ext import commands
7+
import discord.ext.commands
88

99
# Local imports
10-
from build.build import Build
11-
from cog.core.sql import link_sql, read, write, end
12-
from cog.core.sendgift import send_gift_button
10+
import build.build
11+
import cog.core.sendgift
12+
import cog.core.sql
1313

1414

15-
class SendGift(Build):
16-
@commands.Cog.listener()
15+
class SendGift(build.build.Build):
16+
@discord.ext.commands.Cog.listener()
1717
async def on_ready(self) -> None:
1818
self.bot.add_view(self.Gift())
1919

@@ -27,24 +27,26 @@ def __init__(self):
2727
# 發送獎勵
2828
@staticmethod
2929
def __reward(uid: int, username: str, bonus_type: str, bonus: int) -> None:
30-
connection, cursor = link_sql()
31-
current_point = read(uid, bonus_type, cursor)
32-
write(uid, bonus_type, current_point + bonus, cursor)
33-
end(connection, cursor)
34-
print(f"{uid} {username} get {bonus} {bonus_type} by Gift {datetime.now()}")
30+
connection, cursor = cog.core.sql.link_sql()
31+
current_point = cog.core.sql.read(uid, bonus_type, cursor)
32+
cog.core.sql.write(uid, bonus_type, current_point + bonus, cursor)
33+
cog.core.sql.end(connection, cursor)
34+
print(
35+
f"{uid} {username} get {bonus} {bonus_type} by Gift {datetime.datetime.now()}"
36+
)
3537

3638
# 存資料庫存取按鈕屬性(包括獎勵類型、數量)
3739
def __get_btn_attr(self, btn_id: int):
3840
try:
39-
connection, cursor = link_sql()
41+
connection, cursor = cog.core.sql.link_sql()
4042
cursor.execute(
4143
f"SELECT type, count FROM `gift` WHERE `btnID`={btn_id} and `received`=0"
4244
)
4345
ret = cursor.fetchall()
4446
if len(ret) == 0:
4547
return None, None
4648
cursor.execute(f"UPDATE `gift` SET `received`=1 WHERE `btnID`={btn_id}")
47-
end(connection, cursor)
49+
cog.core.sql.end(connection, cursor)
4850
return ret[0][0], ret[0][1] # type, count
4951
except Exception as e:
5052
print(e)
@@ -64,7 +66,7 @@ async def get_gift(self, button: discord.ui.Button, ctx) -> None:
6466
await ctx.response.edit_message(view=self)
6567
button.disabled = True # 關閉按鈕,避免重複點擊
6668
print(
67-
f"{ctx.user.id},{ctx.user} throw error by get_gift {datetime.now()}"
69+
f"{ctx.user.id},{ctx.user} throw error by get_gift {datetime.datetime.now()}"
6870
)
6971
return await ctx.respond(
7072
"好像出了點問題,你可能已經領過或伺服器內部錯誤。若有異議請在收到此訊息兩天內截圖此畫面提交客服單回報",
@@ -85,11 +87,11 @@ def cache_users_by_name(self):
8587
async def send_dm_gift(
8688
self,
8789
ctx,
88-
target_str: discord.Option(
90+
target_str: str = discord.Option(
8991
str, "發送對象(用半形逗號分隔多個使用者名稱)", required=True
9092
),
91-
gift_type: discord.Option(str, "送禮內容", choices=["電電點", "抽獎券"]),
92-
count: discord.Option(int, "數量"),
93+
gift_type: str = discord.Option(str, "送禮內容", choices=["電電點", "抽獎券"]),
94+
count: int = discord.Option(int, "數量"),
9395
) -> None:
9496
if not ctx.author.guild_permissions.administrator:
9597
await ctx.respond("你沒有權限使用這個指令!", ephemeral=True)
@@ -126,7 +128,7 @@ async def fetch_user_by_name(name):
126128
return
127129
# DM 一個 Embed 和領取按鈕
128130
for target_user in target_users:
129-
await send_gift_button(
131+
await cog.core.sendgift.send_gift_button(
130132
self, target_user, gift_type, count, manager.name
131133
)
132134
# 管理者介面提示
@@ -138,5 +140,5 @@ async def fetch_user_by_name(name):
138140
await ctx.respond(f"伺服器內部出現錯誤:{e}", ephemeral=True)
139141

140142

141-
def setup(bot):
143+
def setup(bot: discord.Bot):
142144
bot.add_cog(SendGift(bot))

cog/api/api.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# Standard imports
2-
# import json
3-
41
# Third-party imports
52
import requests
63

cog/chat.py

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,22 @@
77
"""
88

99
# Standard imports
10+
import collections
1011
import os
1112
import time
12-
from collections import defaultdict
13-
from collections import deque
1413

1514
# Third-party imports
16-
from discord.ext import commands
17-
from dotenv import load_dotenv
18-
from google import genai
19-
from google.genai import errors
20-
from google.genai import types
15+
import discord.ext.commands
16+
import dotenv
17+
import google.genai
18+
import google.genai.errors
19+
import google.genai.types
2120
import openai
2221

2322
# Local imports
24-
from cog.core.sql import end
25-
from cog.core.sql import link_sql
23+
import cog.core.sql
2624

27-
load_dotenv(f"{os.getcwd()}/.env")
25+
dotenv.load_dotenv(f"{os.getcwd()}/.env")
2826

2927
# 免費額度內每日請求數最多、付費也最便宜的模型
3028
# 額度與定價見 https://ai.google.dev/pricing
@@ -81,16 +79,16 @@ def load_knowledge():
8179
if KNOWLEDGE:
8280
SYSTEM_PROMPT += "\n\n以下是你知道的事實,回答相關問題時以此為準:\n" + KNOWLEDGE
8381

84-
GENERATE_CONFIG = types.GenerateContentConfig(
82+
GENERATE_CONFIG = google.genai.types.GenerateContentConfig(
8583
system_instruction=SYSTEM_PROMPT,
8684
max_output_tokens=MAX_REPLY_TOKENS,
8785
# 關閉 thinking 以節省 token(flash 系列適用;
8886
# 若改用 gemini-2.5-pro 需移除這行)
89-
thinking_config=types.ThinkingConfig(thinking_budget=0),
87+
thinking_config=google.genai.types.ThinkingConfig(thinking_budget=0),
9088
)
9189

9290

93-
class Chat(commands.Cog):
91+
class Chat(discord.ext.commands.Cog):
9492
"""
9593
@中電喵 聊天功能。
9694
@@ -104,17 +102,21 @@ class Chat(commands.Cog):
104102

105103
def __init__(self, bot):
106104
self.bot = bot
107-
self.client = genai.Client(api_key=GEMINI_API_KEY) if GEMINI_API_KEY else None
105+
self.client = (
106+
google.genai.Client(api_key=GEMINI_API_KEY) if GEMINI_API_KEY else None
107+
)
108108
self.groq = (
109109
openai.AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=GROQ_API_KEY)
110110
if GROQ_API_KEY
111111
else None
112112
)
113113
# 每個頻道各自保留一小段對話歷史,超過上限自動丟棄最舊的
114-
self.history = defaultdict(lambda: deque(maxlen=HISTORY_LIMIT))
114+
self.history = collections.defaultdict(
115+
lambda: collections.deque(maxlen=HISTORY_LIMIT)
116+
)
115117
self.last_used = {}
116118

117-
@commands.Cog.listener()
119+
@discord.ext.commands.Cog.listener()
118120
async def on_message(self, message):
119121
# 機器人發言不可當成觸發條件,必須排除
120122
if message.author.bot:
@@ -204,10 +206,10 @@ def get_chat_nick(user_id):
204206
"""
205207

206208
try:
207-
connection, cursor = link_sql()
209+
connection, cursor = cog.core.sql.link_sql()
208210
cursor.execute("SELECT nickname FROM chat_nick WHERE uid = %s", (user_id,))
209211
ret = cursor.fetchall()
210-
end(connection, cursor)
212+
cog.core.sql.end(connection, cursor)
211213
if ret and ret[0][0]:
212214
return ret[0][0]
213215
# 資料庫掛掉不該讓聊天功能跟著掛
@@ -291,7 +293,7 @@ async def generate(self, contents):
291293

292294
try:
293295
return await self._generate_gemini(CHAT_MODEL, contents)
294-
except errors.APIError as exception:
296+
except google.genai.errors.APIError as exception:
295297
if exception.code not in (429, 500, 503) or FALLBACK_MODEL == CHAT_MODEL:
296298
raise
297299
print(
@@ -301,7 +303,7 @@ async def generate(self, contents):
301303

302304
try:
303305
return await self._generate_gemini(FALLBACK_MODEL, contents)
304-
except errors.APIError as exception:
306+
except google.genai.errors.APIError as exception:
305307
if self.groq is None or exception.code not in (429, 500, 503):
306308
raise
307309
print(
@@ -330,10 +332,10 @@ async def chat(self, message, content):
330332
display_name = (
331333
self.get_chat_nick(message.author.id) or message.author.display_name
332334
)
333-
user_content = types.Content(
335+
user_content = google.genai.types.Content(
334336
role="user",
335337
parts=[
336-
types.Part(text=f"{display_name}{content}"),
338+
google.genai.types.Part(text=f"{display_name}{content}"),
337339
],
338340
)
339341

@@ -342,7 +344,7 @@ async def chat(self, message, content):
342344
reply_text, model_used, tokens_in, tokens_out = await self.generate(
343345
list(channel_history) + [user_content]
344346
)
345-
except errors.APIError as exception:
347+
except google.genai.errors.APIError as exception:
346348
if exception.code == 429:
347349
# 免費額度的每分鐘上限滿了,約一分鐘後就會恢復
348350
await message.reply(
@@ -371,7 +373,9 @@ async def chat(self, message, content):
371373
# 對話成立才寫入歷史,讓後續對話有前後文
372374
channel_history.append(user_content)
373375
channel_history.append(
374-
types.Content(role="model", parts=[types.Part(text=reply_text)])
376+
google.genai.types.Content(
377+
role="model", parts=[google.genai.types.Part(text=reply_text)]
378+
)
375379
)
376380

377381
# 紀錄 token 用量,方便追蹤免費額度
@@ -384,5 +388,5 @@ async def chat(self, message, content):
384388
await message.reply(reply_text[:2000], mention_author=False)
385389

386390

387-
def setup(bot):
391+
def setup(bot: discord.Bot):
388392
bot.add_cog(Chat(bot))

0 commit comments

Comments
 (0)