diff --git a/cog_scn.py b/cog_scn.py index db8299b..754c794 100644 --- a/cog_scn.py +++ b/cog_scn.py @@ -182,7 +182,6 @@ async def teams(self, ctx:discord.ApplicationContext, teamname:str=None): if teamname: team = self.redmine.get_team(teamname) if team: - #await self.print_team(ctx, team) await ctx.respond(self.format_team(team)) else: await ctx.respond(f"Unknown team name: {teamname}") # error @@ -195,6 +194,15 @@ async def teams(self, ctx:discord.ApplicationContext, teamname:str=None): await ctx.respond(buff[:2000]) # truncate! + @scn.command(description="list all open epics") + async def epics(self, ctx:discord.ApplicationContext): + """List all the epics, grouped by tracker""" + # get the epics. + epics = self.redmine.ticket_mgr.get_epics() + # format the epics and respond + msg = self.bot.formatter.format_epics(epics) + await ctx.respond(msg) + @scn.command(description="list blocked email") async def blocked(self, ctx:discord.ApplicationContext): team = self.redmine.get_team(BLOCKED_TEAM_NAME) diff --git a/formatting.py b/formatting.py index 7b7aa62..c84d72a 100644 --- a/formatting.py +++ b/formatting.py @@ -28,6 +28,7 @@ 'High': '🔼', 'Urgent': '⚠️', 'Immediate': '❗', + 'EPIC': '🎇', } class DiscordFormatter(): @@ -176,6 +177,20 @@ def format_ticket_alert(self, ticket: Ticket, discord_ids: list[str], msg: str): return f"ALERT #{self.format_link(ticket)} {' '.join(ids_str)}: {msg}" + def format_epic(self, name: str, epic: list[Ticket]) -> str: + buff = f"**{name}**\n" + for ticket in epic: + buff += self.format_ticket_row(ticket) + return buff + + + def format_epics(self, epics: dict[str,list[Ticket]]) -> str: + buff = "" + for name, epic in epics.items(): + buff += self.format_epic(name, epic) + '\n' + return buff[:MAX_MESSAGE_LEN] # truncate! + + def main(): ticket_manager = TicketManager(RedmineSession.fromenvfile(), "1") diff --git a/requirements.txt b/requirements.txt index c6765a6..f54f71e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,6 @@ frozenlist==1.4.0 humanize==4.8.0 idna==3.4 IMAPClient==3.0.0 -install==1.3.5 isort==5.13.2 markdown-it-py==3.0.0 mccabe==0.7.0 diff --git a/tickets.py b/tickets.py index a420d09..8aae5f4 100644 --- a/tickets.py +++ b/tickets.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 """redmine ticket handling""" +from collections import defaultdict import datetime as dt import logging import re @@ -213,6 +214,29 @@ def get_tickets(self, ticket_ids: list[int]) -> list[Ticket]: log.info(f"Unknown ticket numbers: {ticket_ids}") return [] + def get_epics(self) -> dict[str, list[Ticket]]: + """Get all the open epics, organized by tracker""" + # query tickets pri = epic + # http://localhost/issues.json?priority_id=14 + epic_priority_id = 14 # fixme - lookup based on "EPIC", from redmine.get_priorities() + response = self.session.get(f"/issues.json?priority_id={epic_priority_id}&limit=100") + if not response: + return None + + epics = defaultdict(list) + result = TicketsResult(**response) + if result.total_count > 0: + # iterate to slot by tracker + for epic in result.issues: + tracker_name = epic.tracker.name + if tracker_name not in epics.keys(): + # create the tracker list + epics[tracker_name] = [epic] + else: + epics[tracker_name].append(epic) + + return epics + def expire(self, ticket:Ticket): """Expire a ticket: