]> git.cworth.org Git - turbot/blobdiff - turbot/rot.py
Break out rot.py and slack.py from turbot.py
[turbot] / turbot / rot.py
diff --git a/turbot/rot.py b/turbot/rot.py
new file mode 100644 (file)
index 0000000..e991941
--- /dev/null
@@ -0,0 +1,71 @@
+from flask import Blueprint, request, make_response
+from turbot.slack import slack_is_valid_request, slack_send_reply
+import re
+
+rot_route = Blueprint('rot_route', __name__)
+
+def rot_string(str, n=13):
+    """Return a rotated version of a string
+
+    Specifically, this functions returns a version of the input string
+    where each uppercase letter has been advanced 'n' positions in the
+    alphabet (wrapping around). Lowercase letters and any non-alphabetic
+    characters will be unchanged."""
+
+    result = ''
+    for letter in str:
+        if letter.isupper():
+            result += chr(ord("A") + (ord(letter) - ord("A") + n) % 26)
+        else:
+            result += letter
+    return result
+
+@rot_route.route('/rot', methods = ['POST'])
+def rot():
+    """Implements the /rot route for the /rot slash command in Slack
+
+    This implements the /rot command of our Slack bot. The format of this
+    command is as follows:
+
+        /rot [count|*] String to be rotated
+
+    The optional count indicates an amount to rotate each character in the
+    string. If the count is '*' or is not present, then the string will
+    be rotated through all possible 25 values.
+
+    The result of the rotation is provided as a message in Slack. If the
+    slash command was issued in a direct message, the response is made by
+    using the "response_url" from the request. This allows the bot to reply
+    in a direct message that it is not a member of. Otherwise, if the slash
+    command was issued in a channel, the bot will reply in that channel."""
+
+    if not slack_is_valid_request(request):
+        return make_response("invalid request", 403)
+
+    query = request.form.get('text')
+    match = re.match(r'^([0-9]+|\*) (.*)$', query)
+    if (match):
+        try:
+            count = int(match.group(1))
+        except ValueError:
+            count = None
+        text = match.group(2)
+    else:
+        count = None
+        text = query
+
+    text = text.upper()
+
+    reply = "```/rot {} {}\n".format(count if count else '*', text)
+
+    if count:
+        reply += rot_string(text, count)
+    else:
+        reply += "\n".join(["{:02d} ".format(count) + rot_string(text, count)
+                            for count in range(1, 26)])
+
+    reply += "```"
+
+    slack_send_reply(request, reply)
+
+    return ""