11import asyncio
22import os
3+ from hikari import GuildForumChannel , GuildPublicThread , ForumTag , RESTApp
34from copy import deepcopy
4- from threading import Lock
55
6- import discord
76
87from src .utils .data_types import (
98 ProjectItemEditedAssignees ,
1413 SimpleProjectItemEvent ,
1514)
1615from src .utils .error import ForumChannelNotFound
17- from src .utils .utils import add_tag_to_thread , get_post_id , retrieve_discord_id
16+ from src .utils .utils import get_post_id , retrieve_discord_id
1817
18+ async def run (state : dict [str , bool | list [ProjectItemEvent ]]):
19+ discord_rest = RESTApp ()
20+ await discord_rest .start ()
1921
20- class DiscordClient (discord .Client ):
21- bg_task : asyncio .Task
22-
23- def __init__ (self , * , state , lock , ** kwargs ):
24- super ().__init__ (** kwargs )
25- self .state : dict [str , bool | list [ProjectItemEvent ]] = state
26- self .lock : Lock = lock
27-
28- async def on_ready (self ):
29- print (f"Logged on as { self .user } !" )
30- self .bg_task = self .loop .create_task (self .process_updates ())
31-
32- async def process_updates (self ):
22+ async with discord_rest .acquire (os .getenv ("DISCORD_TOKEN" )) as client :
3323 forum_channel_id = int (os .getenv ("FORUM_CHANNEL_ID" ))
34- forum_channel : discord . ForumChannel = self . get_channel (forum_channel_id )
35- if forum_channel is None :
24+ forum_channel = await client . fetch_channel (forum_channel_id )
25+ if forum_channel is None or not isinstance ( forum_channel , GuildForumChannel ) :
3626 raise ForumChannelNotFound (f"Forum channel with ID { forum_channel_id } not found." )
37- local_queue_copy : list [ProjectItemEvent ] = []
3827
39- while True :
40- with self .lock :
41- if self .state ["update-received" ]:
42- local_queue_copy = deepcopy (self .state ["update-queue" ])
43- self .state ["update-queue" ].clear ()
44- self .state ["update-received" ] = False
28+ if state ["update-received" ]:
29+ local_queue_copy : list [ProjectItemEvent ] = deepcopy (state ["update-queue" ])
30+ state ["update-queue" ].clear ()
31+ state ["update-received" ] = False
4532
4633 for event in local_queue_copy :
47- post_id = await get_post_id (event .name , forum_channel )
34+ post_id = await get_post_id (event .name , forum_channel_id , client )
4835 author_discord_id = retrieve_discord_id (event .sender )
4936 if post_id is None :
5037 message = f"Nowy task stworzony { event .name } przez <@{ author_discord_id } >"
51- await forum_channel .create_thread (name = event .name , content = message , auto_archive_duration = 10080 )
52- post_id = await get_post_id (event .name , forum_channel )
53- thread : discord .Thread = forum_channel .get_thread (int (post_id )) or await self .fetch_channel (
54- int (post_id )
55- )
56- if thread is None :
38+ post : GuildPublicThread = await client .create_forum_post (forum_channel , event .name , message , auto_archive_duration = 10080 )
39+ else :
40+ post = await client .fetch_channel (post_id )
41+
42+ if not isinstance (post , GuildPublicThread ):
5743 continue
5844
5945 if isinstance (event , SimpleProjectItemEvent ):
6046 match event .event_type .value :
6147 case "archived" :
6248 message = f"Task zarchiwizowany przez <@{ author_discord_id } >."
63- await thread . send ( message )
64- await thread . edit ( archived = True )
49+ await client . create_message ( post . id , message )
50+ await client . edit_channel ( post . id , archived = True )
6551 case "restored" :
6652 message = f"Task przywrócony przez <@{ author_discord_id } >."
67- await thread . send ( message )
68- await thread . edit ( archived = False )
53+ await client . create_message ( post . id , message )
54+ await client . edit_channel ( post . id , archived = False )
6955 case "deleted" :
70- await thread . delete ( )
56+ await client . delete_channel ( post . id )
7157 elif isinstance (event , ProjectItemEditedAssignees ):
7258 assignee_mentions : list [str ] = []
7359 if event .new_assignees :
@@ -81,29 +67,34 @@ async def process_updates(self):
8167 message = (
8268 f"Osoby przypisane do taska edytowane, aktualni przypisani: { ', ' .join (assignee_mentions )} "
8369 )
84- await thread . send ( message )
70+ await client . create_message ( post . id , message )
8571 elif isinstance (event , ProjectItemEditedBody ):
8672 message = f"Opis taska zaktualizowany przez <@{ author_discord_id } >. Nowy opis: { event .new_body } "
87- await thread . send ( message )
73+ await client . create_message ( post . id , message )
8874 elif isinstance (event , ProjectItemEditedTitle ):
89- await thread . edit ( name = event .new_title )
75+ await client . edit_channel ( post . id , name = event .new_title )
9076 elif isinstance (event , ProjectItemEditedSingleSelect ):
91- thread_tags = list (thread .applied_tags )
92- for tag in thread_tags :
93- if tag .name .startswith (f"{ event .value_type .value } : " ):
94- await thread .remove_tags (tag )
77+ current_tag_ids = list (post .applied_tag_ids )
78+ available_tags = list (forum_channel .available_tags )
9579
96- await add_tag_to_thread (
97- thread , forum_channel , f"{ event .value_type .value } : { event .new_value } " , event .value_type .value
80+ for tag in available_tags :
81+ if tag .id in current_tag_ids and tag .name .startswith (f"{ event .value_type .value } : " ):
82+ current_tag_ids .remove (tag .id )
83+
84+ new_tag_name = f"{ event .value_type .value } : { event .new_value } "
85+ new_tag = next (
86+ (tag for tag in available_tags if tag .name == new_tag_name ),
87+ None
9888 )
9989
100- local_queue_copy .clear ()
90+ if new_tag is None :
91+ new_tag = ForumTag (name = new_tag_name )
92+ await client .edit_channel (forum_channel .id , available_tags = available_tags .append (new_tag ))
10193
102- await asyncio . sleep ( 1 )
94+ current_tag_ids . append ( new_tag . id )
10395
96+ await client .edit_channel (post .id , applied_tag_ids = current_tag_ids )
10497
105- def run (state , lock ):
106- intents = discord .Intents .default ()
98+ local_queue_copy .clear ()
10799
108- client = DiscordClient (intents = intents , state = state , lock = lock )
109- client .run (os .getenv ("DISCORD_BOT_TOKEN" ))
100+ await asyncio .sleep (1 )
0 commit comments