]> git.cworth.org Git - turbot/commitdiff
Create a sheet for the hunt when creating a new hunt
authorCarl Worth <cworth@cworth.org>
Mon, 19 Oct 2020 21:43:40 +0000 (14:43 -0700)
committerCarl Worth <cworth@cworth.org>
Mon, 19 Oct 2020 23:11:39 +0000 (16:11 -0700)
I don't know how much we'll need this, but here it is for consistency.

This commit adds support for the Google sheets API (accessed via a
pickled token from an encrypted SSM parameter). This will be very
handy in the future when creating sheets for each puzzle channel, etc.

turbot/actions.py
turbot/sheets.py
turbot_lambda/turbot_lambda.py

index 30ae6767d774a5a6268b8a795f1a714e2ce7aea2..b586d39048dab8942429d79bf3e5a6035b034f5c 100644 (file)
@@ -1,5 +1,6 @@
 from turbot.blocks import input_block
 import uuid
+import turbot.sheets
 
 def new_hunt(turb, payload):
     """Handler for the action of user pressing the new_hunt button"""
@@ -37,6 +38,7 @@ def new_hunt_submission(turb, payload):
     slug = state['slug']['slug']['value']
     url = state['url']['url']['value']
 
+    # Create a channel for the hunt
     response = turb.slack_client.conversations_create(name=slug)
 
     if not response['ok']:
@@ -49,6 +51,10 @@ def new_hunt_submission(turb, payload):
     user_id = payload['user']['id']
     channel_id = response['channel']['id']
 
+    # Create a sheet for the channel
+    sheet = turbot.sheets.sheets_create(turb, slug)
+
+    # Insert the newly-created hunt into the database
     turb.hunts_table = turb.db.Table("hunts")
     turb.hunts_table.put_item(
         Item={
@@ -60,6 +66,7 @@ def new_hunt_submission(turb, payload):
         }
     )
 
+    # Invite the initiating user to the channel
     turb.slack_client.conversations_invite(channel=channel_id, users=user_id)
 
     return {
index a578b100267243ff07539afc375637a95e177c98..8ab302d38579a8f744a475a34a39c769f715813a 100644 (file)
@@ -1,44 +1,11 @@
-from flask import current_app
-import pickle
-import os.path
-import os
+PUZZLE_TEMPLATE_ID = "1drSoyrE4gM3JaGweDkOybwXWdKPIDTfUmB1gQCYS3Uw"
+PUZZLE_TEMPLATE_SHEETS = ["Text", "Grid"]
 
-from google.auth.transport.requests import Request
-from googleapiclient.discovery import build
-
-TEMPLATE_SHEET_ID = "1drSoyrE4gM3JaGweDkOybwXWdKPIDTfUmB1gQCYS3Uw"
-TEMPLATE_SHEET_SHEETS = ["Text", "Grid"]
-
-turbot_deploy_dir = os.environ.get('TURBOT_DEPLOY_DIR', '.')
-TOKEN_FILE = "{}/.gsheets-token.pickle".format(turbot_deploy_dir)
-
-creds = None
-
-def sheets_create(name):
+def sheets_create(turb, name):
     """Create a new sheet with the given name.
 
-    Returns the URL for the spreadsheet.
+    Returns the dict with 'id' and 'url'of the spreadsheet.
     """
-    global creds
-
-    # The token file stores token from last login/refresh
-    if not creds:
-        if os.path.exists(TOKEN_FILE):
-            with open(TOKEN_FILE, 'rb') as token:
-                creds = pickle.load(token)
-
-    # Refresh credentials if necessary
-    if creds and not creds.valid:
-        creds.refresh(Request())
-
-    # If there are no (valid) credentials available, give up
-    if not creds or not creds.valid:
-        current_app.logger.error("No token found in {}".format(TOKEN_FILE))
-        current_app.logger.error("Try running ./gsheets-authenticate.py")
-        return None
-
-    service = build('sheets', 'v4', credentials=creds)
-    sheets = service.spreadsheets()
 
     # Create a new spreadsheet
     spreadsheet_body = {
@@ -47,21 +14,32 @@ def sheets_create(name):
         }
     }
 
-    new_sheet = sheets.create(body=spreadsheet_body).execute()
-    spreadsheet_url = new_sheet["spreadsheetUrl"]
-    spreadsheet_id = new_sheet["spreadsheetId"]
+    new_sheet = turb.sheets.create(body=spreadsheet_body).execute()
+
+    return {
+        'id': new_sheet["spreadsheetId"],
+        'url': new_sheet["spreadsheetUrl"]
+    }
+
+def sheets_create_for_puzzle(turb, name):
+    """Creates a new sheet for a puzzle of the given name
+
+    Like sheets_create(), but also copies the puzzle template sheet."""
+
+    # First create the new sheet
+    new_sheet = sheets_create(turb, name)
 
     # Copy some sheets from the Template spreadsheet
 
-    response = sheets.get(spreadsheetId=TEMPLATE_SHEET_ID).execute()
+    response = turb.sheets.get(spreadsheetId=PUZZLE_TEMPLATE_ID).execute()
 
     for sheet in response["sheets"]:
-        if sheet["properties"]["title"] in TEMPLATE_SHEET_SHEETS:
-            sheets.sheets().copyTo(spreadsheetId=TEMPLATE_SHEET_ID,
-                                   sheetId=sheet["properties"]["sheetId"],
-                                   body={
-                                       "destinationSpreadsheetId":
-                                       spreadsheet_id
-                                   }).execute()
-
-    return spreadsheet_url
+        if sheet["properties"]["title"] in PUZZLE_TEMPLATE_SHEETS:
+            turb.sheets.sheets().copyTo(spreadsheetId=PUZZLE_TEMPLATE_ID,
+                                        sheetId=sheet["properties"]["sheetId"],
+                                        body={
+                                            "destinationSpreadsheetId":
+                                            new_sheet['id']
+                                        }).execute()
+
+    return new_sheet
index 9d878af8c7e05a92b58846e96a20c9c54fd682c5..ab670d34c74c60476c90036fd0629834beb96703 100644 (file)
@@ -1,10 +1,14 @@
 from urllib.parse import parse_qs
 from slack import WebClient
+import base64
 import boto3
 import requests
 import json
 import os
+import pickle
 from types import SimpleNamespace
+from google.auth.transport.requests import Request
+from googleapiclient.discovery import build
 
 import turbot.actions
 import turbot.commands
@@ -23,11 +27,34 @@ response = ssm.get_parameter(Name='SLACK_BOT_TOKEN', WithDecryption=True)
 slack_bot_token = response['Parameter']['Value']
 slack_client = WebClient(slack_bot_token)
 
+response = ssm.get_parameter(Name='GSHEETS_PICKLE_BASE64', WithDecryption=True)
+gsheets_pickle_base64 = response['Parameter']['Value']
+gsheets_pickle = base64.b64decode(gsheets_pickle_base64)
+gsheets_creds = pickle.loads(gsheets_pickle)
+if gsheets_creds:
+    if gsheets_creds.valid:
+        print("Loaded valid GSheets credentials from SSM")
+    else:
+        gsheets_creds.refresh(Request())
+        gsheets_pickle = pickle.dumps(gsheets_creds)
+        gsheets_pickle_base64 = base64.b64encode(gsheets_pickle)
+        print("Storing refreshed GSheets credentials into SSM")
+        ssm.put_parameter(Name='GSHEETS_PICKLE_BASE64',
+                          Type='SecureString',
+                          Value=gsheets_pickle_base64,
+                          Overwrite=True)
+service = build('sheets',
+                'v4',
+                credentials=gsheets_creds,
+                cache_discovery=False)
+sheets = service.spreadsheets()
+
 db = boto3.resource('dynamodb')
 
 turb = SimpleNamespace()
 turb.slack_client = slack_client
 turb.db = db
+turb.sheets = sheets
 
 def error(message):
     """Generate an error response for a Slack request