Skip to content

Commit c1de2fa

Browse files
committed
add typehinting, flake8
1 parent 700092e commit c1de2fa

2 files changed

Lines changed: 39 additions & 21 deletions

File tree

.flake8

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[flake8]
2+
max-line-length=120
3+
ignore =
4+
E252, # not using spaces around '=' in function arguments
5+
E302, # expecting 2 blank lines between non-member functions
6+
E731, # do not use lambda, use def
7+
W605, # invalid escape sequence
8+
exclude = env, .git

core/utils.py

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import asyncio
22
import smtplib
33
import traceback
4+
from aiohttp import ClientSession
45
from contextlib import asynccontextmanager
56
from datetime import date, datetime
67
from datetime import time as dt_time
@@ -11,21 +12,34 @@
1112

1213
import asyncpg
1314
from jinja2 import Environment, PackageLoader
14-
from sanic import response
15+
from sanic import response, Sanic
16+
from sanic.request import Request
17+
from sanic.response import HTTPResponse
1518

1619

1720
class Oauth2:
18-
def __init__(self, client_id, client_secret, scope=None, redirect_uri=None, session=None):
21+
"""An Oauth2 class to handle logging in with Discord"""
22+
23+
def __init__(self, client_id: str, client_secret: str, scope: str, redirect_uri: str, session: ClientSession):
1924
self.client_id = client_id
2025
self.client_secret = client_secret
2126
self.scope = scope
2227
self.redirect_uri = redirect_uri
23-
self.discord_login_url = 'https://discord.com/api/oauth2/authorize?client_id={}&redirect_uri={}&response_type=code&scope={}'.format(client_id, redirect_uri, scope)
28+
self.discord_login_url = 'https://discord.com/api/oauth2/authorize' + \
29+
f'?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope={scope}'
2430
self.discord_token_url = 'https://discord.com/api/oauth2/token'
2531
self.discord_api_url = 'https://discord.com/api/v6'
2632
self.session = session
2733

28-
async def get_access_token(self, code):
34+
async def get_access_token(self, code: str):
35+
"""Get an access token to make a request to the Discord API
36+
37+
Parameters
38+
----------
39+
code: str
40+
The code that gets sent to the request arguments when the user is redirected
41+
back to the redirect URI after authorization.
42+
"""
2943
payload = {
3044
'client_id': self.client_id,
3145
'client_secret': self.client_secret,
@@ -43,11 +57,12 @@ async def get_access_token(self, code):
4357
resp = await z.json()
4458
return resp.get('access_token')
4559

46-
async def get_user_json(self, access_token):
60+
async def get_user_json(self, access_token: str):
61+
"""Get user information with our new access token"""
4762
url = self.discord_api_url + '/users/@me'
4863

4964
headers = {
50-
'Authorization': 'Bearer {}'.format(access_token)
65+
'Authorization': f'Bearer {access_token}'
5166
}
5267

5368
async with self.session.get(url, headers=headers) as z:
@@ -56,7 +71,7 @@ async def get_user_json(self, access_token):
5671

5772

5873
@asynccontextmanager
59-
async def open_db_connection(app, **options):
74+
async def open_db_connection(app: Sanic, **options):
6075
user = options.pop('user', app.config.DB_USERNAME)
6176
password = options.pop('password', app.config.DB_PASSWORD)
6277
database = options.pop('database', app.config.DB_NAME)
@@ -68,7 +83,7 @@ async def open_db_connection(app, **options):
6883
# finally:
6984
await conn.close()
7085

71-
async def render_template(template, request, **context):
86+
async def render_template(template: str, request: Request, **context) -> HTTPResponse:
7287
"""
7388
Function to return jinja variables to the html
7489
"""
@@ -88,14 +103,13 @@ async def render_template(template, request, **context):
88103
request.ctx.session['messages'] = [] # Clear messages after every request
89104
return response.html(html_content)
90105

91-
def add_message(request, category, message, redirect_to=None):
92-
"""Add a flash message to appear at the top of a page and redirect to an endpoint if provided"""
106+
def add_message(request: Request, category: str, message: str, redirect_to: str):
107+
"""Add a flash message to appear at the top of a page and redirect to an endpoint"""
93108
request.ctx.session['messages'].append([category, message])
94-
if redirect_to:
95-
return response.redirect(redirect_to)
109+
return response.redirect(redirect_to)
96110

97111

98-
def disable_xss(content):
112+
def disable_xss(content: str) -> str:
99113
"""Prevent cross-site scripting"""
100114
return content.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
101115

@@ -125,8 +139,6 @@ def daterange(start_date: date, end_date: date) -> list:
125139
day_count = (end_date - start_date).days + 1
126140
return [start_date + timedelta(days=i) for i in range(day_count)]
127141

128-
129-
130142
def thisweek(today: date) -> list:
131143
"""Gets a list of dates for this week"""
132144
if 0 <= today.weekday() <= 4:
@@ -138,7 +150,6 @@ def thisweek(today: date) -> list:
138150

139151
return daterange(monday, friday)
140152

141-
142153
async def get_school_week(requested_date: date, first_day: date, week=True):
143154
no_school = [
144155
date(2020, 9, 28), # Yom Kippur
@@ -206,7 +217,6 @@ async def get_school_week(requested_date: date, first_day: date, week=True):
206217
'date': d,
207218
'day': prev_day + 1})
208219

209-
210220
this_week = thisweek(requested_date)
211221

212222
if week:
@@ -217,7 +227,9 @@ async def get_school_week(requested_date: date, first_day: date, week=True):
217227
except IndexError:
218228
week_fmt.append(f"{day.strftime('%a %m/%d')}<br>NO SCHOOL")
219229
else:
220-
week_fmt.append(f"{day.strftime('%a %m/%d')}<br>{day_info['cohort'].title()} {day_map[day_info['day'] % 2]} day")
230+
week_fmt.append(
231+
f"{day.strftime('%a %m/%d')}<br>{day_info['cohort'].title()} {day_map[day_info['day'] % 2]} day"
232+
)
221233
return week_fmt
222234

223235
try:
@@ -228,7 +240,6 @@ async def get_school_week(requested_date: date, first_day: date, week=True):
228240
day_info['day'] = day_map[day_info['day'] % 2]
229241
return day_info
230242

231-
232243
async def handle_daily_emails(app):
233244
"""Send out an email at a specified time every weekday"""
234245
today = date.today()
@@ -249,7 +260,6 @@ async def handle_daily_emails(app):
249260
# Could be here if the func was called after the time on Friday
250261
return app.add_task(handle_daily_emails)
251262

252-
253263
today_info = await get_school_week(today, date(2020, 9, 8), week=False)
254264
if today_info is None:
255265
# No school
@@ -266,7 +276,7 @@ async def handle_daily_emails(app):
266276
msg['From'] = app.config.CUSTOM_EMAIL
267277
msg['To'] = email
268278
body = MIMEText(
269-
f"Today, {today.strftime('%m/%d/%Y')}, is a {today_info['cohort'].title()} {today_info['day']} day. <br><br>"
279+
f"Today, {today.strftime('%m/%d/%Y')}, is a {today_info['cohort'].title()} {today_info['day']} day.<br><br>"
270280
f"Click <a href=\"http{'s' if not app.config.DEV else ''}://{app.config.DOMAIN}"
271281
f"/schoolweek/unsubscribe/{msg['To']}\">here</a> to unsubscribe.", 'html')
272282

0 commit comments

Comments
 (0)