Skip to content

Commit 744a357

Browse files
author
Paul Philion
committed
Initial work on roles, but it will be complicated. Creating a checkpoint and moving on the smaller changes
1 parent 5ac4eb5 commit 744a357

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ htmlcov:
2828

2929
clean:
3030
rm -rf __pycache__
31-
rm -rf $(VENV)
31+
rm -rf .venv/
3232
rm -rf htmlcov
3333
rm -f discord.log
3434
rm -f dpytest_*.dat

netbot/cog_scn.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ async def sync(self, ctx:discord.ApplicationContext):
251251
async def reindex(self, ctx:discord.ApplicationContext):
252252
"""reindex the all cached information"""
253253
self.redmine.reindex()
254+
#self.bot.reindex() FIXME, once roles are working
254255
await ctx.respond("Rebuilt redmine indices.")
255256

256257

netbot/netbot.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
import asyncio
99
import discord
1010
from dotenv import load_dotenv
11+
from discord import Role
1112
from discord.ext import commands, tasks
1213

13-
from redmine.model import TicketNote, Ticket, NamedId, Team
14+
from redmine.model import TicketNote, Ticket, NamedId, Team, TeamSet
1415
from redmine import synctime
1516
from redmine.redmine import Client
1617

@@ -69,11 +70,15 @@ def __init__(self, client: Client):
6970
log.info(f'initializing {self}')
7071
intents = discord.Intents.default()
7172
intents.message_content = True
73+
intents.members = True # Needed to access member roles
7274

7375
self.run_sync = True # ticket sync on by default
7476
self.lock = asyncio.Lock()
7577
self.ticket_locks = {}
7678

79+
self.roles: dict[str,Role] = {}
80+
self.teams = TeamSet()
81+
7782
self.formatter = DiscordFormatter(client.url)
7883

7984
self.redmine = client
@@ -96,10 +101,38 @@ def run_bot(self):
96101
log.info(f"starting {self}")
97102
super().run(os.getenv('DISCORD_TOKEN'))
98103

104+
105+
def cache_roles(self):
106+
# Noting: "guild" maps to discord server, and the API is designed to run on many "Discord servers" concurrently
107+
for guild in self.guilds:
108+
for member in guild.members:
109+
for role in member.roles:
110+
user = self.redmine.user_mgr.find_discord_user(member.name)
111+
#log.debug(f"<<< {role.name} {user.name}")
112+
if user:
113+
self.teams.add_user(role.name, user.name, user.id)
114+
else:
115+
log.warning(f"Unknown user: {member.name} for team: {role.name}")
116+
117+
log.debug(f"Loaded teams: {self.teams}")
118+
119+
120+
def get_all_teams(self, include_users: bool = True) -> dict[str, Team]:
121+
return self.teams
122+
123+
124+
def reindex(self):
125+
log.debug("NetBot.reindex")
126+
self.cache_roles()
127+
128+
99129
async def on_ready(self):
100130
#log.info(f"Logged in as {self.user} (ID: {self.user.id})")
101131
#log.debug(f"bot: {self}, guilds: {self.guilds}")
102132

133+
# reindex: cache roles, etc.
134+
self.reindex()
135+
103136
# start the tasks running
104137
self.sync_all_threads.start()
105138
self.run_daily_tasks.start()
@@ -244,11 +277,8 @@ def get_channel_by_name(self, channel_name: str) -> discord.TextChannel:
244277

245278

246279
def get_role_by_name(self, role_name: str) -> discord.Role:
247-
# Noting: "guild" maps to discord server, and the API is designed to run on many "Discord servers" concurrently
248-
for guild in self.guilds:
249-
for role in guild.roles:
250-
if role_name == role.name:
251-
return role
280+
# Load from cache
281+
return self.roles.get(role_name, None)
252282

253283

254284
async def on_application_command_error(self, context: discord.ApplicationContext,

redmine/model.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,44 @@ def __post_init__(self):
170170
def __str__(self) -> str:
171171
return self.name
172172

173+
def add_user(self, named:NamedId):
174+
if not self.users:
175+
self.users = []
176+
self.users.append(named)
177+
178+
179+
class TeamSet:
180+
_teams: dict[str,Team] = {}
181+
182+
def __str__(self) -> str:
183+
return str(self._teams)
184+
185+
def get(self, name: str) -> Team:
186+
self._teams.get(name, None)
187+
188+
189+
def in_team(self, username:str, teamname:str) -> bool:
190+
if username is None or teamname is None:
191+
return False
192+
193+
team = self.get(teamname)
194+
if team:
195+
for team_user in team.users:
196+
if team_user.name == username:
197+
return True
198+
199+
return False
200+
201+
202+
def add_user(self, teamname:str, username:str, userid:int) -> None:
203+
team = self.get(teamname)
204+
if not team:
205+
team = Team(id=-1, name=teamname)
206+
team.users = []
207+
self._teams[teamname] = team
208+
# TODO check if user already in team before adding: set behavior.
209+
team.add_user(NamedId(userid, username))
210+
173211

174212
DISCORD_ID_FIELD = "Discord ID"
175213

0 commit comments

Comments
 (0)