Skip to content

Commit 27fc4e7

Browse files
author
Paul Philion
committed
Initial work on ticket-1608: Nailing down trackers and teams
1 parent cf53b9e commit 27fc4e7

File tree

3 files changed

+49
-25
lines changed

3 files changed

+49
-25
lines changed

netbot/netbot.py

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from dotenv import load_dotenv
1111
from discord.ext import commands, tasks
1212

13-
from redmine.model import TicketNote, Ticket, NamedId
13+
from redmine.model import TicketNote, Ticket, NamedId, Team
1414
from redmine import synctime
1515
from redmine.redmine import Client
1616

@@ -20,17 +20,8 @@
2020
log = logging.getLogger(__name__)
2121

2222

23-
# _TRACKER_MAPPING = {
24-
# "External-Comms-Intake": "admin-team",
25-
# "Admin": "admin-team",
26-
# "Comms": "outreach",
27-
# "Infra-Config": "routing-and-infrastructure",
28-
# "Infra-Field": "installs",
29-
# "Software-Dev": "network-software",
30-
# "Research": "uw-research-nsf",
31-
# }
3223
CHANNEL_MAPPING = {
33-
"support": "External-Comms-Intake",
24+
"intake": "External-Comms-Intake",
3425
"admin-team": "Admin",
3526
"outreach": "Comms",
3627
"routing-and-infrastructure": "Infra-Config",
@@ -40,13 +31,13 @@
4031
}
4132

4233
TEAM_MAPPING = {
43-
#"support": "External-Comms-Intake", ## FIXME - intake is a tracker, not a team? worry later
34+
"intake": "intake-team",
4435
"admin-team": "admin-team",
4536
"outreach": "comms-team",
4637
"routing-and-infrastructure": "infra-config-team",
4738
"installs": "infra-field-team",
4839
"network-software": "software-dev-team",
49-
"uw-research-nsf": "research-team",
40+
"uw-research-nsf": "uw-research-nsf-team",
5041
}
5142

5243
# utility method to get a list of (one) ticket from the title of the channel, or empty list
@@ -375,12 +366,35 @@ async def notify_expiring_tickets(self):
375366
await self.expiration_notification(ticket)
376367

377368

378-
def expire_expired_tickets(self):
379-
expired = self.redmine.ticket_mgr.expired_tickets()
380-
for ticket in expired:
369+
def group_for_tracker(self, tracker: NamedId) -> Team:
370+
"""For a tracker, look up a team"""
371+
for channel_name, tracker_name in CHANNEL_MAPPING.items():
372+
if tracker.name == tracker_name:
373+
# lookup team from channel
374+
team_name = TEAM_MAPPING.get(channel_name, None)
375+
if team_name:
376+
team = self.redmine.user_mgr.get_team_by_name(team_name)
377+
if team:
378+
return team
379+
else:
380+
log.error(f"Unable to find team for {tracker} and {team_name}")
381+
return None
382+
else:
383+
log.error(f"Unable to find channel mapping for {tracker} and {channel_name}")
384+
return None
385+
386+
# fallthru: not found
387+
log.error(f"Unable to find channel for {tracker}")
388+
return None
389+
390+
391+
def recycle_tickets(self):
392+
recycle_list = self.redmine.ticket_mgr.tickets_to_recycle() # older than max age
393+
for ticket in recycle_list:
381394
# notification to discord, or just note provided by expire?
382395
# - for now, add note to ticket with expire info, and allow sync.
383-
self.redmine.ticket_mgr.expire(ticket)
396+
new_owner = self.group_for_tracker(ticket.tracker)
397+
self.redmine.ticket_mgr.recycle(ticket, new_owner)
384398

385399

386400
@commands.slash_command(name="notify", description="Force ticket notifications")

redmine/tickets.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
EPIC_PRIORITY_NAME = "EPIC"
2525

2626

27-
TICKET_MAX_AGE = 4 * 7 # 4 weeks; 28 days
28-
TICKET_EXPIRE_NOTIFY = TICKET_MAX_AGE - 1 # 27 days, one day shorter than MAX_AGE
27+
TICKET_MAX_AGE = 7 * 3 # 3 weeks; 21 days
28+
#TICKET_EXPIRE_NOTIFY = TICKET_MAX_AGE - 1 # 20 days, one day shorter than MAX_AGE
2929

3030

3131
class TicketManager():
@@ -299,9 +299,9 @@ def get_epics(self) -> list[Ticket]:
299299
return epics
300300

301301

302-
def expire(self, ticket:Ticket):
303-
"""Expire a ticket:
304-
- reassign to intake
302+
def recycle(self, ticket:Ticket, team_id: int):
303+
"""Recycle a dusty ticket:
304+
- reassign to tracker-based team
305305
- set status to new
306306
- add note to owner and collaborators
307307
"""
@@ -310,9 +310,9 @@ def expire(self, ticket:Ticket):
310310
# ID can be resolved to discord-id, but not without call in user manager.
311311
# Ideally, this would @ the owner and collaborators.
312312
fields = {
313-
"assigned_to_id": INTAKE_TEAM_ID,
313+
"assigned_to_id": team_id,
314314
"status_id": "1", # New, TODO lookup using status lookup table.
315-
"notes": f"Ticket automatically expired after {TICKET_MAX_AGE} days due to inactivity.",
315+
"notes": f"Ticket automatically recycled after {TICKET_MAX_AGE} days due to inactivity.",
316316
}
317317
self.update(ticket.id, fields)
318318
log.info(f"Expired ticket {ticket.id}, {ticket.age_str}")
@@ -321,7 +321,7 @@ def expire(self, ticket:Ticket):
321321
def expiring_tickets(self) -> list[Ticket]:
322322
# tickets that are about to expire
323323
tickets = set()
324-
tickets.update(self.older_than(TICKET_EXPIRE_NOTIFY))
324+
#tickets.update(self.older_than(TICKET_EXPIRE_NOTIFY))
325325
tickets.update(self.due()) ### FIXME REMOVE
326326
return tickets
327327

tests/test_netbot.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ def setUp(self):
3434
#- add trivial test for on_application_command_error
3535

3636

37+
SKIP_TRACKERS = ["Test-Reject"]
38+
39+
def test_group_for_tracker(self):
40+
trackers = self.bot.redmine.ticket_mgr.get_trackers()
41+
for tracker in trackers.values():
42+
if tracker.name not in TestNetbot.SKIP_TRACKERS:
43+
team = self.bot.group_for_tracker(tracker)
44+
self.assertIsNotNone(team)
45+
46+
3747
async def test_synchronize_ticket(self):
3848
# create a new ticket, identified by the tag, with a note
3949
body = f"Body for test {self.tag} {unittest.TestCase.id(self)}"

0 commit comments

Comments
 (0)