|
@@ -6,16 +6,57 @@ BANGS = ('!',)
|
|
|
|
|
|
|
|
|
def pop_arg(text):
|
|
|
+ """
|
|
|
+ Pop an argument from a string of text. The text is split at the first
|
|
|
+ substring containing only whitespace characters, ignoring leading and
|
|
|
+ trailing whitespace of the string, with the text preceeding being
|
|
|
+ returned as the first value, and the text following being returned
|
|
|
+ as the second value.
|
|
|
+
|
|
|
+ Both return values will be stripped of leading and trailing whitespace.
|
|
|
+ If the given text is None, both return values will be None. If there is
|
|
|
+ no text following the split point, the second return value will be None.
|
|
|
+ """
|
|
|
if text is None:
|
|
|
return None, None
|
|
|
+ text = text.strip()
|
|
|
parts = text.split(maxsplit=1)
|
|
|
if len(parts) == 1:
|
|
|
return parts[0], None
|
|
|
- return parts[0], parts[1].strip()
|
|
|
+ return parts[0], parts[1]
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
class RollbotMessage:
|
|
|
+ """
|
|
|
+ A data class modeling a message that was received by a Rollbot.
|
|
|
+ This class is used both for mundane messages and for commands.
|
|
|
+
|
|
|
+ Init Fields:
|
|
|
+ src - a string describing the source of the message, usually GROUPME
|
|
|
+ name - the plaintext display name of the sender of the message
|
|
|
+ sender_id - the service-specific id of the sender, which will not change
|
|
|
+ group_id - the id of the "group" the message was sent to, which can
|
|
|
+ mean different concepts depending on src
|
|
|
+ message_id - the service-specific unique id of the message
|
|
|
+ message_txt - the raw, full text of the message
|
|
|
+ from_admin - a boolean flag denoting if the sender has admin privileges
|
|
|
+
|
|
|
+ Derived Fields:
|
|
|
+ is_command - a boolean flag denoting if the message is a command. This
|
|
|
+ will be true if message_txt begins with a "!" character followed by
|
|
|
+ one or more non-whitespace characters (with whitespace between the
|
|
|
+ bang and the first non-whitespace character being ignored)
|
|
|
+ raw_command - the raw text of the command, i.e., the first "word" after
|
|
|
+ the bang, with leading and trailing whitespace removed. This field
|
|
|
+ will only be present if is_command is True
|
|
|
+ command - raw_command normalized to lower case. This field will only be
|
|
|
+ present if is_command is True
|
|
|
+ raw_args - the raw text of the arguments following command, i.e., the
|
|
|
+ remaining ontent of message_txt, with leading and trailing whitespace
|
|
|
+ removed. This field will only be present if is_command is True
|
|
|
+
|
|
|
+ """
|
|
|
src: str
|
|
|
name: str
|
|
|
sender_id: str
|
|
@@ -82,11 +123,35 @@ class RollbotMessage:
|
|
|
)
|
|
|
|
|
|
def args(self, normalize=True):
|
|
|
+ """
|
|
|
+ Lazily pop arguments from the raw argument string of this message
|
|
|
+ and yield them one at a time as a generator. If the optional
|
|
|
+ normalize parameter is set to False, the arguments will
|
|
|
+ be returned exactly as they appear in the message, and if normalize
|
|
|
+ is set to True or omitted, the arguments will be converted to lower
|
|
|
+ case.
|
|
|
+
|
|
|
+ For details on argument "popping", see the rollbot.pop_arg function.
|
|
|
+
|
|
|
+ Behavior is undefined if this method is called on a message whose
|
|
|
+ is_command field is false.
|
|
|
+ """
|
|
|
arg, rest = pop_arg(self.raw_args)
|
|
|
while arg is not None:
|
|
|
yield arg.lower() if normalize else arg
|
|
|
arg, rest = pop_arg(rest)
|
|
|
|
|
|
+ def arg_list(self):
|
|
|
+ """
|
|
|
+ Take the raw argument string of this message and split it on any
|
|
|
+ sequence of one or more whitespace characters, and return the result.
|
|
|
+ This can be useful to pass to an argparse.ArgumentParser.
|
|
|
+
|
|
|
+ Behavior is undefined if this method is called on a message whose
|
|
|
+ is_command field is false.
|
|
|
+ """
|
|
|
+ return self.raw_args.split()
|
|
|
+
|
|
|
|
|
|
class RollbotFailure(Enum):
|
|
|
INVALID_COMMAND = auto()
|