1- from typing import Optional , Dict , Any
1+ from typing import Optional , Dict , Any , Tuple
22import logging
33
44from sqlalchemy .ext .asyncio import AsyncSession
1313from src .utils import get_category
1414from src .utils import ctf_api
1515from src .utils import embed_creator
16- from src .bot import get_bot
16+ from src .bot import get_guild
1717from src import crud
1818
1919# channel_op = "event_op"
2020
2121# logging
2222logger = logging .getLogger ("uvicorn" )
2323
24+ # utils
25+ async def read_event_one_wrapper (session :AsyncSession , event_db_id :int ) -> Tuple [model .Event , str ]:
26+ try :
27+ event_db , lock_owner_token = await crud .read_event_one (
28+ session = session ,
29+ lock = True , duration = 120 ,
30+ archived = False , # ensoure the Event isn't archived
31+ id = event_db_id
32+ )
33+ except crud .NotFoundError :
34+ raise HTTPException (404 , f"Event (id={ event_db_id } ) not found (archived, or invalid id)" )
35+ except crud .LockedError :
36+ raise HTTPException (423 , F"Event (id={ event_db_id } ) was locked. Try again later." )
37+ except Exception as e :
38+ logger .error (f"Can't get and lock Event (id={ event_db_id } ): { str (e )} " )
39+ raise HTTPException (500 , f"Can't get and lock Event (id={ event_db_id } )" )
40+
41+ return event_db , lock_owner_token
42+
43+
2444# functions
25- async def _create_channel (session :AsyncSession , member :discord .Member , event_db_id : int , lock_owner_token :str ):
45+ async def _create_channel (session :AsyncSession , member :discord .Member , event_db : model . Event , lock_owner_token :str ) -> model . Event :
2646 # 在這個 function 有 exception 就直接 raise 出來
2747 channel :Optional [discord .TextChannel ] = None
2848 event_api :Optional [Dict [str , Any ]] = None
@@ -31,10 +51,7 @@ async def _create_channel(session:AsyncSession, member:discord.Member, event_db_
3151 log_msg :str = ""
3252
3353 # get guild
34- bot = await get_bot ()
35- if (guild := bot .get_guild (settings .GUILD_ID )) is None :
36- logger .critical (f"Guild (id={ settings .GUILD_ID } ) not found" )
37- raise HTTPException (500 , f"Guild (id={ settings .GUILD_ID } ) not found" )
54+ guild = get_guild ()
3855
3956 # get category
4057 if (ctf_channel_category := get_category .get_category (guild , settings .CTF_CHANNEL_CATEGORY_ID )) is None :
@@ -43,23 +60,13 @@ async def _create_channel(session:AsyncSession, member:discord.Member, event_db_
4360
4461 try :
4562 async with session .begin ():
46- # get a new event_db
47- events_db = await crud .read_event (
48- session ,
49- id = event_db_id ,
50- archived = False , # ensure the event isn't archived
51- lock_owner_token = lock_owner_token
52- )
53- if len (events_db ) != 1 :
54- raise RuntimeError (f"Event (id={ event_db_id } ) not found" )
55- event_db = events_db [0 ]
5663 ctftime_event = True if event_db .event_id is not None else False
5764
5865 # check channel
5966 if (channel_id := event_db .channel_id ) is not None and \
6067 guild .get_channel (channel_id ) is not None :
6168 # exists -> no need to create
62- return
69+ return event_db
6370
6471 if ctftime_event :
6572 events_api = await ctf_api .fetch_ctf_events (event_db .event_id )
@@ -107,49 +114,35 @@ async def _create_channel(session:AsyncSession, member:discord.Member, event_db_
107114 except Exception as e :
108115 logger .error (f"fail to send notification to channel (id={ channel .id } ): { str (e )} " )
109116 # ignore exception
110-
111- return
112117
118+ return event_db
113119
114- async def _join_channel (session :AsyncSession , member :discord .Member , event_db_id :int , lock_owner_token :str ):
120+
121+ async def _join_channel (session :AsyncSession , member :discord .Member , event_db :model .Event , lock_owner_token :str ):
115122 # 在這個 function 有 exception 就直接 raise 出來
116123 # get guild
117- bot = await get_bot ()
118- if (guild := bot .get_guild (settings .GUILD_ID )) is None :
119- logger .critical (f"Guild (id={ settings .GUILD_ID } ) not found" )
120- raise HTTPException (500 , f"Guild (id={ settings .GUILD_ID } ) not found" )
124+ guild = get_guild ()
121125
122126 joined_channel = False # joined channel in Discord, but not in database
123127 joined = False # joined channel in Discord and database
124128 log_msg :str = ""
125129 try :
126130 async with session .begin ():
127- # get a new event_db
128- events_db = await crud .read_event (
129- session ,
130- id = event_db_id ,
131- archived = False , # ensure the Event isn't archived
132- lock_owner_token = lock_owner_token
133- )
134- if len (events_db ) != 1 :
135- raise RuntimeError (f"Event (id={ event_db_id } ) not found" )
136- event_db = events_db [0 ]
137-
138131 # check channel
139132 if (channel_id := event_db .channel_id ) is None or \
140133 (channel := guild .get_channel (channel_id )) is None :
141- raise RuntimeError (f"TextChannel for Event (id={ event_db_id } ) not found" )
134+ raise RuntimeError (f"TextChannel for Event (id={ event_db . id } ) not found" )
142135
143136 # join channel
144137 await channel .set_permissions (member , view_channel = True )
145138 joined_channel = True
146139
147140 # update database
148141 try :
149- await crud .join_event (session , event_db_id , member .id , lock_owner_token )
142+ await crud .join_event (session , event_db . id , member .id , lock_owner_token )
150143 except IntegrityError :
151144 # ignore
152- raise HTTPException (409 , f"The user (discord_id={ member .id } ) has joined the Event (id={ event_db_id } )" )
145+ raise HTTPException (409 , f"The user (discord_id={ member .id } ) has joined the Event (id={ event_db . id } )" )
153146 except Exception :
154147 raise
155148 joined = True
@@ -196,22 +189,14 @@ async def create_and_join_channel(member:discord.Member, event_db_id:int):
196189 lock_owner_token :Optional [str ] = None
197190 async with database .with_get_db () as session :
198191 # try to lock event
199- try :
200- lock_owner_token = await crud .try_lock_event (session , event_db_id , 120 )
201- except crud .LockedError :
202- raise HTTPException (423 , f"Event (id={ event_db_id } ) was locked. Try again later." )
203- except crud .NotFoundError :
204- raise HTTPException (404 , f"Event (id={ event_db_id } ) not found" )
205- except Exception as e :
206- logger .error (f"Can't lock Event (id={ event_db_id } ): { str (e )} " )
207- raise HTTPException (f"Can't lock Event (id={ event_db_id } ): { str (e )} " )
192+ event_db , lock_owner_token = await read_event_one_wrapper (session , event_db_id )
208193
209194 try :
210195 # try to create channel
211- await _create_channel (session , member , event_db_id , lock_owner_token )
196+ event_db = await _create_channel (session , member , event_db , lock_owner_token )
212197
213198 # join channel
214- await _join_channel (session , member , event_db_id , lock_owner_token )
199+ await _join_channel (session , member , event_db , lock_owner_token )
215200 except Exception as e :
216201 if isinstance (e , HTTPException ):
217202 raise
@@ -239,41 +224,17 @@ async def archive_event(event_db_id:int, reason:str):
239224 event_db_returning = {}
240225
241226 # get guild
242- bot = await get_bot ()
243- if (guild := bot .get_guild (settings .GUILD_ID )) is None :
244- logger .critical (f"Guild (id={ settings .GUILD_ID } ) not found" )
245- raise HTTPException (500 , f"Guild (id={ settings .GUILD_ID } ) not found" )
227+ guild = get_guild ()
246228
247229 # get archive category
248230 if (archive_category := get_category .get_category (guild , settings .ARCHIVE_CATEGORY_ID )) is None :
249231 logger .critical (f"Archive Category (id={ settings .ARCHIVE_CATEGORY_ID } ) not found" )
250232 raise HTTPException (500 , f"Archive Category (id={ settings .ARCHIVE_CATEGORY_ID } ) not found" )
251233
252234 async with database .with_get_db () as session :
253- # try to lock the Event
254- try :
255- lock_owner_token = await crud .try_lock_event (session , event_db_id , 120 )
256- except crud .NotFoundError :
257- raise HTTPException (404 , f"Event (id={ event_db_id } ) not found" )
258- except crud .LockedError :
259- raise HTTPException (423 , f"Event (id={ event_db_id } ) was locked. Try again later." )
260- except Exception as e :
261- logger .error (f"Can't lock Event (id={ event_db_id } ): { str (e )} " )
262- raise HTTPException (500 , f"Can't lock Event (id={ event_db_id } )" )
263-
235+ event_db , lock_owner_token = await read_event_one_wrapper (session , event_db_id )
264236 try :
265237 async with session .begin ():
266- # get a new event_db
267- events_db = await crud .read_event (
268- session = session ,
269- archived = False , # ensure the Event isn't archived
270- id = event_db_id ,
271- lock_owner_token = lock_owner_token ,
272- )
273- if len (events_db ) != 1 :
274- raise RuntimeError (f"Event (id={ event_db_id } ) not found" )
275- event_db = events_db [0 ]
276-
277238 # update database
278239 event_db :model .Event = await crud .update_event (
279240 session = session ,
@@ -360,41 +321,17 @@ async def link_event_to_channel(event_db_id:int, channel_id:int):
360321 lock_owner_token = None
361322
362323 # get guild
363- bot = await get_bot ()
364- if (guild := bot .get_guild (settings .GUILD_ID )) is None :
365- logger .critical (f"Guild (id={ settings .GUILD_ID } ) not found" )
366- raise HTTPException (500 , f"Guild (id={ settings .GUILD_ID } ) not found" )
324+ guild = get_guild ()
367325
368326 # get channel
369327 if (channel := guild .get_channel (channel_id )) is None or \
370328 not isinstance (channel , discord .TextChannel ):
371329 raise HTTPException (400 , f"Channel (id={ channel_id } ) not found" )
372330
373331 async with database .with_get_db () as session :
374- # try to lock the Event
375- try :
376- lock_owner_token = await crud .try_lock_event (session , event_db_id , 120 )
377- except crud .NotFoundError :
378- raise HTTPException (404 , f"Event (id={ event_db_id } ) not found" )
379- except crud .LockedError :
380- raise HTTPException (423 , f"Event (id={ event_db_id } ) was locked. Try again later." )
381- except Exception as e :
382- logger .error (f"Can't lock Event (id={ event_db_id } ): { str (e )} " )
383- raise HTTPException (500 , f"Can't lock Event (id={ event_db_id } )" )
384-
332+ event_db , lock_owner_token = await read_event_one_wrapper (session , event_db_id )
385333 try :
386334 async with session .begin ():
387- # get a new event_db
388- events_db = await crud .read_event (
389- session = session ,
390- archived = False , # ensure the Event isn't archived
391- id = event_db_id ,
392- lock_owner_token = lock_owner_token
393- )
394- if len (events_db ) != 1 :
395- raise RuntimeError (f"Event (id={ event_db_id } ) not found" )
396- event_db = events_db [0 ]
397-
398335 # update database
399336 event_db :model .Event = await crud .update_event (
400337 session = session ,
@@ -428,10 +365,7 @@ async def create_custom_event(title:str):
428365 :raise HTTPException:
429366 """
430367 # get guild
431- bot = await get_bot ()
432- if (guild := bot .get_guild (settings .GUILD_ID )) is None :
433- logger .critical (f"Guild (id={ settings .GUILD_ID } ) not found" )
434- raise HTTPException (500 , f"Guild (id={ settings .GUILD_ID } ) not found" )
368+ guild = get_guild ()
435369
436370 # create the custom event in database
437371 event_db_id = None
0 commit comments