]> git.cworth.org Git - turbot/commitdiff
Make a top-level turbot package
authorCarl Worth <cworth@cworth.org>
Tue, 29 Sep 2020 17:07:15 +0000 (10:07 -0700)
committerCarl Worth <cworth@cworth.org>
Tue, 29 Sep 2020 19:44:21 +0000 (12:44 -0700)
This will be useful as we soon start splitting up the single turbot.py
file into multiple modules that want to include things from each
other.

Makefile
turbot.py [deleted file]
turbot/__init__.py [new file with mode: 0644]
turbot/turbot.py [new file with mode: 0755]

index d38a9a984c71be5bb68e37f30c1f122667659ece..d0719d8cdb82fdf9ef6ace038f5a4fca019a4b45 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ endif
        pip-compile --no-index --generate-hashes --allow-unsafe
 
 run: require-venv
-       FLASK_APP=turbot FLASK_DEBUG=true flask run
+       FLASK_APP=turbot.turbot FLASK_DEBUG=true flask run
 
 turbot.wsgi: turbot.wsgi.in Makefile
        envsubst < turbot.wsgi.in > turbot.wsgi
diff --git a/turbot.py b/turbot.py
deleted file mode 100755 (executable)
index 2b9462f..0000000
--- a/turbot.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python3
-
-from flask import Flask, request, make_response
-
-from slackeventsapi import SlackEventAdapter
-from slack import WebClient
-from slack.errors import SlackApiError
-from slack.signature import SignatureVerifier
-import os
-import requests
-import re
-
-app = Flask(__name__)
-
-slack_signing_secret = os.environ['SLACK_SIGNING_SECRET']
-slack_bot_token = os.environ['SLACK_BOT_TOKEN']
-
-slack_events = SlackEventAdapter(slack_signing_secret, "/slack/events", app)
-signature_verifier = SignatureVerifier(slack_signing_secret)
-slack_client = WebClient(slack_bot_token)
-
-def slack_is_valid_request(request):
-    """Returns true if request actually came from Slack.
-
-    By means of checking the requests signature together with the slack
-    signing key.
-
-    Note: If flask is in debug mode, this function will always return true."""
-
-    if app.debug:
-        return True
-
-    data = request.get_data()
-    headers = request.headers
-
-    return signature_verifier.is_valid_request(data, headers)
-
-def slack_send_reply(request, text):
-    """Send a Slack message as a reply to a specified request.
-
-    If the request is associated with a direct message, the reply is
-    made by using the "response_url" from the request. Otherwise, the
-    reply will be sent to the channel associated with the request.
-
-    Note: If flask is in debug mode, this function will just print the
-    text to stdout."""
-
-    channel_name = request.form.get('channel_name')
-    response_url = request.form.get('response_url')
-    channel = request.form.get('channel_id')
-
-    if (app.debug):
-        print("Sending message to channel '{}': {}".format(channel, text))
-        return
-
-    if (channel_name == "directmessage"):
-        resp = requests.post(response_url,
-                             json = {"text": text},
-                             headers = {"Content-type": "application/json"})
-        if (resp.status_code != 200):
-            app.logger.error("Error posting request to Slack: " + resp.text)
-    else:
-        try:
-            slack_client.chat_postMessage(channel=channel, text=text)
-        except SlackApiError as e:
-            app.logger.error("Slack API error: " + e.response["error"])
-
-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
-
-@app.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 ""
-
-@slack_events.on("error")
-def handle_error(error):
-    app.logger.error("Error from Slack: " + str(error))
diff --git a/turbot/__init__.py b/turbot/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/turbot/turbot.py b/turbot/turbot.py
new file mode 100755 (executable)
index 0000000..2b9462f
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+
+from flask import Flask, request, make_response
+
+from slackeventsapi import SlackEventAdapter
+from slack import WebClient
+from slack.errors import SlackApiError
+from slack.signature import SignatureVerifier
+import os
+import requests
+import re
+
+app = Flask(__name__)
+
+slack_signing_secret = os.environ['SLACK_SIGNING_SECRET']
+slack_bot_token = os.environ['SLACK_BOT_TOKEN']
+
+slack_events = SlackEventAdapter(slack_signing_secret, "/slack/events", app)
+signature_verifier = SignatureVerifier(slack_signing_secret)
+slack_client = WebClient(slack_bot_token)
+
+def slack_is_valid_request(request):
+    """Returns true if request actually came from Slack.
+
+    By means of checking the requests signature together with the slack
+    signing key.
+
+    Note: If flask is in debug mode, this function will always return true."""
+
+    if app.debug:
+        return True
+
+    data = request.get_data()
+    headers = request.headers
+
+    return signature_verifier.is_valid_request(data, headers)
+
+def slack_send_reply(request, text):
+    """Send a Slack message as a reply to a specified request.
+
+    If the request is associated with a direct message, the reply is
+    made by using the "response_url" from the request. Otherwise, the
+    reply will be sent to the channel associated with the request.
+
+    Note: If flask is in debug mode, this function will just print the
+    text to stdout."""
+
+    channel_name = request.form.get('channel_name')
+    response_url = request.form.get('response_url')
+    channel = request.form.get('channel_id')
+
+    if (app.debug):
+        print("Sending message to channel '{}': {}".format(channel, text))
+        return
+
+    if (channel_name == "directmessage"):
+        resp = requests.post(response_url,
+                             json = {"text": text},
+                             headers = {"Content-type": "application/json"})
+        if (resp.status_code != 200):
+            app.logger.error("Error posting request to Slack: " + resp.text)
+    else:
+        try:
+            slack_client.chat_postMessage(channel=channel, text=text)
+        except SlackApiError as e:
+            app.logger.error("Slack API error: " + e.response["error"])
+
+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
+
+@app.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 ""
+
+@slack_events.on("error")
+def handle_error(error):
+    app.logger.error("Error from Slack: " + str(error))