diff --git a/models/github/__init__.py b/models/github/__init__.py index aa0e03b..2b3c35e 100644 --- a/models/github/__init__.py +++ b/models/github/__init__.py @@ -4,7 +4,7 @@ # Import all trivial models from .commit import Commit -from .event_type import EventType, convert_str_to_event_type +from .event_type import EventType, convert_keywords_to_events from .issue import Issue from .pull_request import PullRequest from .ref import Ref diff --git a/models/github/event_type.py b/models/github/event_type.py index b6e9f19..6449021 100644 --- a/models/github/event_type.py +++ b/models/github/event_type.py @@ -21,8 +21,8 @@ class EventType(Enum): PULL_MERGED = ("prm", "A Pull Request was merged") PULL_OPENED = ("pro", "A Pull Request was opened") PULL_READY = ("prr", "A Pull Request is ready") - ISSUE_OPENED = ("io", "An Issue was opened") - ISSUE_CLOSED = ("ic", "An Issue was closed") + ISSUE_OPENED = ("iso", "An Issue was opened") + ISSUE_CLOSED = ("isc", "An Issue was closed") # Review REVIEW = ("rv", "A Review was given on a Pull Request") @@ -44,15 +44,30 @@ def __init__(self, keyword, docs): self.docs = docs -def convert_str_to_event_type(event_keyword: str) -> EventType | None: +def convert_keywords_to_events(keywords: list[str]) -> set[EventType]: """ - Returns the `EventType` member corresponding to the passed keyword. - If no `EventType` is matched, returns `None`. - :param event_keyword: Short string representing the event. - :return: `EventType` member corresponding to the keyword. + Returns a set of `EventType` members corresponding to the passed keywords. + If no `EventType` is matched, returns an empty set. + :param keywords: List of short strings representing the events. + :return: Set of `EventType` members corresponding to the keywords. """ - for event_type in EventType: - if event_type.keyword == event_keyword: - return event_type - print("Event not in enum") - return None + if len(keywords) == 0 or "default" in keywords: + return { + EventType.BRANCH_CREATED, + EventType.TAG_CREATED, + EventType.PULL_OPENED, + EventType.ISSUE_OPENED, + EventType.REVIEW, + EventType.COMMIT_COMMENT, + EventType.ISSUE_COMMENT, + EventType.PUSH, + EventType.STAR_ADDED, + } + if "all" in keywords or "*" in keywords: + return set(EventType) + return { + event_type + for event_type in EventType + for keyword in keywords + if event_type.keyword == keyword + } diff --git a/slack_bot/runner.py b/slack_bot/runner.py index 4d89279..544070d 100644 --- a/slack_bot/runner.py +++ b/slack_bot/runner.py @@ -6,7 +6,7 @@ from bottle import MultiDict -from models.github import EventType, convert_str_to_event_type +from models.github import EventType, convert_keywords_to_events from models.slack import Channel from utils.json import JSON from utils.storage import Storage @@ -60,11 +60,7 @@ def run_subscribe_command( :param args: `list` of events to subscribe to. """ repo: str = args[0] - new_events: set[EventType] = { - convert_str_to_event_type(arg) for arg in args[1:] - } - # Remove all the entries which do not correspond to a correct [EventType]. - new_events -= {None} + new_events = convert_keywords_to_events(args[1:]) if repo in self.subscriptions: channels: set[Channel] = self.subscriptions[repo] channel: Channel | None = next( @@ -129,21 +125,21 @@ def run_unsubscribe_command( if channel is not None: # If this channel has subscribed to some events # from this repo, update the list of events. - events = channel.events - for arg in args[1:]: - event: EventType | None = convert_str_to_event_type(arg) + current_events = channel.events + chosen_events = convert_keywords_to_events(args[1:]) + for event in chosen_events: try: - events.remove(event) + current_events.remove(event) except KeyError: # This means that the user tried to unsubscribe from # an event that wasn't subscribed to in the first place. pass self.subscriptions[repo].remove(channel) - if len(events) != 0: + if len(current_events) != 0: self.subscriptions[repo].add( Channel( name=current_channel, - events=events, + events=current_events, ) ) return self.run_list_command(current_channel=current_channel, ephemeral=True) @@ -186,6 +182,17 @@ def run_list_command( "type": "divider", }, ] + if len(blocks) == 0: + prompt = "This channel has not yet subscribed to anything." + prompt += "You can subscribe to your favorite repositories " + prompt += "using the `/subscribe` command. For more info, use the `/help` command." + + blocks = [ + { + "type": "mrkdwn", + "text": prompt, + }, + ] return { "response_type": "ephemeral" if ephemeral else "in_channel", "blocks": blocks, @@ -222,9 +229,12 @@ def run_help_command() -> dict[str, Any]: "text": ( "*Events*\n" "GitHub events are abbreviated as follows:\n" + "0. `default` or no arguments: Subscribe " + "to the most common and important events.\n" + "1. `all` or `*`: Subscribe to every supported event.\n" + " ".join( [ - f"{i + 1}. `{event.keyword}`: {event.docs}\n" + f"{i + 2}. `{event.keyword}`: {event.docs}\n" for i, event in enumerate(EventType) ] ) diff --git a/utils/storage.py b/utils/storage.py index 65a1136..0e37051 100644 --- a/utils/storage.py +++ b/utils/storage.py @@ -5,7 +5,7 @@ import json import os -from models.github import EventType, convert_str_to_event_type +from models.github import EventType, convert_keywords_to_events from models.slack import Channel @@ -45,10 +45,7 @@ def import_subscriptions() -> dict[str, set[Channel]]: repo: { Channel( name=channel, - events={ - convert_str_to_event_type(event_keyword) - for event_keyword in events - }, + events=convert_keywords_to_events(events), ) for channel, events in channels.items() } @@ -58,7 +55,7 @@ def import_subscriptions() -> dict[str, set[Channel]]: else: # Default subscriptions, for dev and testing return { - "fake-rdrive-flutter": { + "github-slack-bot": { Channel("#github-slack-bot", set(EventType)), } }