1+ import logging
12import os
2-
3- from signal import signal , SIGINT
4- from sys import exit
3+ import re
54
65from slack_bolt import App
76from slack_bolt .adapter .fastapi import SlackRequestHandler
8-
97from slack_bolt .oauth .oauth_settings import OAuthSettings
108from slack_sdk .oauth .installation_store .sqlalchemy import SQLAlchemyInstallationStore
119from slack_sdk .oauth .state_store .sqlalchemy import SQLAlchemyOAuthStateStore
1210
13- import sqlalchemy
14- from sqlalchemy .engine import Engine
15- from sqlalchemy .ext .declarative import declarative_base
16- from sqlalchemy import Column , String
1711from sqlalchemy .orm import Session
18- from sqlalchemy import select
19- from urllib import parse
2012
21- import re
22-
23- import logging
13+ from piazzabot .database import Base , Course , dbengine
14+ from piazzabot .constants import CLIENT_ID , CLIENT_SECRET , SIGNING_SECRET , ERROR_NO_FORUM_ID , BASE_URL
2415
2516logging .basicConfig (level = logging .INFO )
26-
2717logger = logging .getLogger (__name__ )
28-
29- # Set up DB
30- db_host , db_user , db_pass , db_name = (
31- os .environ .get ("DB_HOST" ),
32- os .environ .get ("DB_USER" ),
33- parse .quote_plus (os .environ .get ("DB_PASS" )),
34- os .environ .get ("DB_NAME" )
35- )
36- client_id , client_secret , signing_secret = (
37- os .environ ["SLACK_CLIENT_ID" ],
38- os .environ ["SLACK_CLIENT_SECRET" ],
39- os .environ ["SLACK_SIGNING_SECRET" ],
40- )
41- connection = f"mysql+pymysql://{ db_user } :{ db_pass } @{ db_host } /{ db_name } "
42- engine : Engine = sqlalchemy .create_engine (connection , pool_pre_ping = True )
18+ cache = {}
4319
4420# Set up Oauth backend
4521installation_store = SQLAlchemyInstallationStore (
46- client_id = client_id ,
47- engine = engine ,
22+ client_id = CLIENT_ID ,
23+ engine = dbengine ,
4824 logger = logger
4925)
5026oauth_state_store = SQLAlchemyOAuthStateStore (
5127 expiration_seconds = 120 ,
52- engine = engine ,
28+ engine = dbengine ,
5329 logger = logger
5430)
5531
5632try :
57- engine .execute ("select count(*) from slack_bots" )
33+ dbengine .execute ("select count(*) from slack_bots" )
5834except Exception as e :
59- installation_store .metadata .create_all (engine )
60- oauth_state_store .metadata .create_all (engine )
61-
62- # Set up custom table
63- Base = declarative_base ()
64-
65-
66- class Course (Base ):
67- __tablename__ = 'courses'
68- __table_args__ = {'schema' : db_name }
69-
70- workspace = Column ("workspace" , String (32 ), nullable = False , primary_key = True )
71- forum = Column ("forum" , String (32 ), nullable = False )
35+ installation_store .metadata .create_all (dbengine )
36+ oauth_state_store .metadata .create_all (dbengine )
7237
73- def __repr__ (self ):
74- return "Course({0}, {1})" .format (self .workspace , self .forum )
75-
76-
77- Base .metadata .create_all (engine )
38+ Base .metadata .create_all (dbengine )
7839
7940# Set up app
8041app = App (
8142 token = os .environ .get ("SLACK_BOT_TOKEN" ),
82- signing_secret = signing_secret ,
43+ signing_secret = SIGNING_SECRET ,
8344 installation_store = installation_store ,
8445 oauth_settings = OAuthSettings (
85- client_id = client_id ,
86- client_secret = client_secret ,
46+ client_id = CLIENT_ID ,
47+ client_secret = CLIENT_SECRET ,
8748 state_store = oauth_state_store ,
8849 scopes = [
8950 "chat:write.public" ,
@@ -99,16 +60,6 @@ def __repr__(self):
9960app_handler = SlackRequestHandler (app )
10061
10162
102- error = "Sorry, the forum id hasn't been set! "
103- error += "You can set it via slash command:\n "
104- error += "`/piazza-update-id [course_id]`\n "
105- error += "You can find the course id in any url on your piazza forum. "
106- error += "it'll be the long alphanumeric string."
107-
108- cache = {}
109- base_url = "https://piazza.com/class/"
110-
111-
11263# Provides a means of setting the forum ID from a running app.
11364@app .command ("/piazza-update-id" )
11465def update_forum_id (ack , respond , command , context ):
@@ -123,11 +74,10 @@ def update_forum_id(ack, respond, command, context):
12374 cache [workspace_id ] = forum_id
12475 logging .info (f"after cache insert. cache[{ workspace_id } ] should be { forum_id } , is { cache [workspace_id ]} " )
12576 c = Course (workspace = workspace_id , forum = forum_id )
126- with Session ( engine ) as session :
127- logging . info ( f"in session thing. course is: { c } " )
77+
78+ with Session ( dbengine ) as session :
12879 session .merge (c )
12980 session .commit ()
130- logging .info ("after commit" )
13181
13282 respond (f"Updated forum! new id is { forum_id } " , )
13383
@@ -148,13 +98,13 @@ def regex_message_match(say, context, event, client, logger, body):
14898 first_match = context ["matches" ][0 ]
14999 logger .warning (f"Forum not set. First ID is: { first_match } " )
150100 client .chat_postEphemeral (
151- text = error ,
101+ text = ERROR_NO_FORUM_ID ,
152102 channel = context ["channel_id" ],
153103 user = context ["user_id" ]
154104 )
155105 return
156106
157- posts_url = base_url + forum_id + "/post/"
107+ posts_url = BASE_URL + forum_id + "/post/"
158108 # build message contents
159109 text = ""
160110 for match in context ['matches' ]:
@@ -175,52 +125,3 @@ def regex_message_match(say, context, event, client, logger, body):
175125 text = text .strip ("\n " ),
176126 thread_ts = thread_ts
177127 )
178-
179-
180- # exit handler
181- def cleanup ():
182- logging .info ("Shutting down PiazzaBot..." )
183-
184- global cache
185- global engine
186- with Session (engine ) as session :
187- for workspace in cache :
188- course = Course (workspace = workspace , forum = cache [workspace ])
189- session .merge (course )
190- session .commit ()
191-
192- logging .info ("goodbye!" )
193-
194-
195-
196- from fastapi import FastAPI , Request
197-
198- api = FastAPI ()
199-
200- @api .on_event ("startup" )
201- async def startup_event ():
202- with Session (engine ) as session :
203- courses = session .query (Course )
204- for course in courses :
205- cache [course .workspace ] = course .forum
206-
207- logger .info ("cache built:" )
208- logger .info (cache )
209-
210- @api .post ("/slack/events" )
211- async def endpoint (req : Request ):
212- return await app_handler .handle (req )
213-
214-
215- @api .get ("/slack/install" )
216- async def install (req : Request ):
217- return await app_handler .handle (req )
218-
219-
220- @api .get ("/slack/oauth_redirect" )
221- async def oauth_redirect (req : Request ):
222- return await app_handler .handle (req )
223-
224- @api .on_event ("shutdown" )
225- def shutdown_event ():
226- cleanup ()
0 commit comments