Skip to content

Commit 966d429

Browse files
committed
restructuring
1 parent 2c60c9e commit 966d429

File tree

6 files changed

+114
-118
lines changed

6 files changed

+114
-118
lines changed
File renamed without changes.

main.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from piazzabot.piazzabot import app_handler, logger, dbengine, cache
2+
from piazzabot.database import Course
3+
4+
from fastapi import FastAPI, Request, status
5+
from sqlalchemy.orm import Session
6+
7+
api = FastAPI()
8+
9+
10+
@api.on_event("startup")
11+
async def startup_event():
12+
with Session(dbengine) as session:
13+
courses = session.query(Course)
14+
for course in courses:
15+
cache[course.workspace] = course.forum
16+
17+
logger.info("cache built:")
18+
logger.info(cache)
19+
20+
21+
@api.post("/slack/events")
22+
async def endpoint(req: Request):
23+
return await app_handler.handle(req)
24+
25+
26+
@api.get("/slack/install")
27+
async def install(req: Request):
28+
return await app_handler.handle(req)
29+
30+
31+
@api.get("/slack/oauth_redirect")
32+
async def oauth_redirect(req: Request):
33+
return await app_handler.handle(req)
34+
35+
36+
@api.on_event("shutdown")
37+
def shutdown_event():
38+
logger.info("Shutting down PiazzaBot...")
39+
with Session(dbengine) as session:
40+
for workspace in cache:
41+
course = Course(workspace=workspace, forum=cache[workspace])
42+
session.merge(course)
43+
session.commit()
44+
45+
logger.info("goodbye!")
46+
47+
48+
@api.get('/healthcheck', status_code=status.HTTP_200_OK)
49+
def perform_healthcheck():
50+
return {'healthcheck': 'Everything OK!'}

piazzabot/__init__.py

Whitespace-only changes.

piazzabot/constants.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import os
2+
from urllib import parse
3+
4+
CLIENT_ID, CLIENT_SECRET, SIGNING_SECRET = (
5+
os.environ["SLACK_CLIENT_ID"],
6+
os.environ["SLACK_CLIENT_SECRET"],
7+
os.environ["SLACK_SIGNING_SECRET"],
8+
)
9+
10+
DB_HOST, DB_USER, DB_PASS, DB_NAME = (
11+
os.environ.get("DB_HOST"),
12+
os.environ.get("DB_USER"),
13+
parse.quote_plus(os.environ.get("DB_PASS")),
14+
os.environ.get("DB_NAME")
15+
)
16+
17+
BASE_URL = "https://piazza.com/class/"
18+
19+
ERROR_NO_FORUM_ID = "Sorry, the forum id hasn't been set! "
20+
ERROR_NO_FORUM_ID += "You can set it via slash command:\n"
21+
ERROR_NO_FORUM_ID += "`/piazza-update-id [course_id]`\n"
22+
ERROR_NO_FORUM_ID += "You can find the course id in any url on your piazza forum. "
23+
ERROR_NO_FORUM_ID += "it'll be the long alphanumeric string."

piazzabot/database.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from constants import DB_HOST, DB_USER, DB_PASS, DB_NAME
2+
3+
import sqlalchemy
4+
from sqlalchemy.engine import Engine
5+
from sqlalchemy import Column, String
6+
from sqlalchemy.ext.declarative import declarative_base
7+
8+
9+
connection = f"mysql+pymysql://{DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}"
10+
dbengine: Engine = sqlalchemy.create_engine(connection, pool_pre_ping=True)
11+
Base = declarative_base()
12+
13+
14+
class Course(Base):
15+
__tablename__ = 'courses'
16+
__table_args__ = {'schema': DB_NAME}
17+
18+
workspace = Column("workspace", String(32), nullable=False, primary_key=True)
19+
forum = Column("forum", String(32), nullable=False)
20+
21+
def __repr__(self):
22+
return "Course({0}, {1})".format(self.workspace, self.forum)
Lines changed: 19 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,50 @@
1+
import logging
12
import os
2-
3-
from signal import signal, SIGINT
4-
from sys import exit
3+
import re
54

65
from slack_bolt import App
76
from slack_bolt.adapter.fastapi import SlackRequestHandler
8-
97
from slack_bolt.oauth.oauth_settings import OAuthSettings
108
from slack_sdk.oauth.installation_store.sqlalchemy import SQLAlchemyInstallationStore
119
from 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
1711
from 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

2516
logging.basicConfig(level=logging.INFO)
26-
2717
logger = 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
4521
installation_store = SQLAlchemyInstallationStore(
46-
client_id=client_id,
47-
engine=engine,
22+
client_id=CLIENT_ID,
23+
engine=dbengine,
4824
logger=logger
4925
)
5026
oauth_state_store = SQLAlchemyOAuthStateStore(
5127
expiration_seconds=120,
52-
engine=engine,
28+
engine=dbengine,
5329
logger=logger
5430
)
5531

5632
try:
57-
engine.execute("select count(*) from slack_bots")
33+
dbengine.execute("select count(*) from slack_bots")
5834
except 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
8041
app = 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):
9960
app_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")
11465
def 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

Comments
 (0)