Skip to content

Commit 0b22091

Browse files
authored
Merge branch 'main' into dependTest-merged
2 parents 46b22de + ca7724b commit 0b22091

File tree

74 files changed

+2324
-352
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+2324
-352
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
node_modules
1212
pocs-capstone/backend/.env
1313
pocs-capstone/backend/tutorial-env/
14+
pocs-capstone/backend/henry_env/
1415
pocs-capstone/backend/db/__pycache__/
1516
pocs-capstone/backend/db/migrations/
1617
pocs-capstone/backend/backend/__pycache__/
@@ -121,3 +122,4 @@ pocs-capstone/frontend/src/components/Tutorial/Tutorial-screenshots/original scr
121122
pocs-capstone/frontend/src/components/Tutorial/Tutorial-screenshots/original screenshots/calendar.png
122123
pocs-capstone/frontend/src/components/Tutorial/Tutorial-screenshots/original screenshots/completed-tasks.png
123124
pocs-capstone/frontend/src/components/Tutorial/Tutorial-screenshots/original screenshots/inventory.png
125+
pocs-capstone/backend/venv/*

pocs-capstone/backend/backend/db/__init__.py

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.contrib import admin
2+
3+
# Register your models here.
4+
"""
5+
from .models import Question
6+
from .models import Note
7+
8+
admin.site.register(Question)
9+
admin.site.register(Note)
10+
"""
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class DbConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'db'
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from rest_framework_simplejwt.authentication import JWTAuthentication
2+
from django.conf import settings
3+
4+
from rest_framework.authentication import CSRFCheck
5+
from rest_framework import exceptions
6+
7+
def enforce_csrf(request):
8+
"""
9+
Enforce CSRF validation.
10+
"""
11+
check = CSRFCheck()
12+
# populates request.META['CSRF_COOKIE'], which is used in process_view()
13+
check.process_request(request)
14+
reason = check.process_view(request, None, (), {})
15+
if reason:
16+
# CSRF failed, bail with explicit error message
17+
raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
18+
19+
class CustomAuthentication(JWTAuthentication):
20+
21+
def authenticate(self, request):
22+
header = self.get_header(request)
23+
24+
if header is None:
25+
raw_token = request.COOKIES.get(settings.SIMPLE_JWT['AUTH_COOKIE']) or None
26+
else:
27+
raw_token = self.get_raw_token(header)
28+
if raw_token is None:
29+
return None
30+
31+
validated_token = self.get_validated_token(raw_token)
32+
enforce_csrf(request)
33+
return self.get_user(validated_token), validated_token
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
2+
import requests
3+
import bs4 as bs
4+
import pprint
5+
# import re
6+
# from dateutil import parser
7+
pp = pprint.PrettyPrinter(indent=2)
8+
9+
# Static settings
10+
BASE_URL = 'https://templeu.instructure.com/api/v1'
11+
12+
13+
'''Returns the response from a GET request to the Canvas API'''
14+
15+
16+
def canvas_request(url, headers, params):
17+
try:
18+
response = requests.get(url=url, headers=headers, params=params)
19+
status = response.status_code
20+
except Exception as e:
21+
return e, 500 # this is an internal service error due to failed request to external resource
22+
return response.json(), status # convert to json
23+
24+
25+
'''Return a list of all Canvas courses' IDs'''
26+
27+
28+
def get_courses(canvas_token): # later we'll add userId as a parameter
29+
auth_header = {'Authorization': 'Bearer ' + canvas_token}
30+
courses_params = {
31+
"per_page": 100,
32+
"enrollment_state": "active",
33+
"workflow_state": "available",
34+
"enrollment_type": "student"
35+
}
36+
37+
courses_data, status = canvas_request(
38+
BASE_URL + '/courses', auth_header, courses_params)
39+
40+
if status == 200:
41+
course_id_list = [] # a list of all the user's courses (their ids)
42+
43+
for course_entry in courses_data:
44+
course = (course_entry['id'], course_entry['name'])
45+
course_id_list.append(course)
46+
47+
return course_id_list, status
48+
return None, status
49+
50+
51+
'''Given a course ID, return a list of all assignments' IDs'''
52+
53+
54+
def get_assignments(canvas_token, course_id):
55+
auth_header = {'Authorization': 'Bearer ' + canvas_token}
56+
assignment_params = {
57+
"per_page": 5000,
58+
"include": "submission"
59+
}
60+
61+
assignments_data, status = canvas_request(
62+
BASE_URL + '/courses/' + str(course_id) + '/assignments', auth_header, assignment_params)
63+
64+
assignment_id_list = [] # a list of all the user's courses (their ids)
65+
for assignment_entry in assignments_data:
66+
try:
67+
assignment_id_list.append(assignment_entry['id'])
68+
except Exception as e:
69+
print(e)
70+
71+
return assignment_id_list, assignments_data
72+
73+
74+
'''Given a course ID, return a json object of course information for that particular course'''
75+
76+
77+
def get_course_info(canvas_token, course_id):
78+
auth_header = {'Authorization': 'Bearer ' + canvas_token}
79+
course_url = BASE_URL + '/courses/' + str(course_id)
80+
return canvas_request(url=course_url, headers=auth_header, params={})
81+
82+
83+
'''Given a course ID and assignment ID, return a dict of assignment information for that particular assignment'''
84+
85+
86+
def get_assignment_info(canvas_token, course_id, assignment_id):
87+
auth_header = {'Authorization': 'Bearer ' + canvas_token}
88+
89+
# TODO - This needs to move further back in the procedure
90+
user_url = BASE_URL + '/users/self'
91+
user_id = None
92+
93+
try:
94+
b, bstatus = canvas_request(
95+
url=user_url, headers=auth_header, params={})
96+
if bstatus == 200:
97+
user_id = b['id']
98+
except Exception as e:
99+
print(e)
100+
return None
101+
102+
assignment_url = BASE_URL + '/courses/' + \
103+
str(course_id) + '/assignments/' + str(assignment_id)
104+
a, status = canvas_request(url=assignment_url, headers=auth_header, params={
105+
"include[]": ['submission']})
106+
submission_details = {}
107+
108+
if status == 200:
109+
due = a['due_at']
110+
submission_details = a['submission']
111+
submitted = submission_details['submitted_at']
112+
else:
113+
due = None
114+
115+
if due != None:
116+
due = due[0:10] # hack into a string UwU
117+
if submitted != None:
118+
submitted = submitted[0:10] # hack into a string UwU
119+
120+
try:
121+
description = bs.BeautifulSoup(a['description'], 'lxml').get_text()
122+
except Exception as e:
123+
description = ""
124+
125+
return {'title': a['name'] or "No title.",
126+
'due_date': due,
127+
128+
'task_type': 'S',
129+
# 'task_level': 1, # TODO - this should be set here!
130+
# 'recurring': 'false',
131+
# 'recurring_time_delta': 0,
132+
'completed_date': submitted,
133+
'description': description,
134+
'course_id': a['course_id'],
135+
'assignment_id': a['id']
136+
}
137+
138+
139+
'''Given a course ID, return a list of all assignments' IDs'''
140+
141+
142+
def get_assignments(canvas_token, course_info):
143+
course_id = course_info[0]
144+
auth_header = {'Authorization': 'Bearer ' + canvas_token}
145+
assignment_params = {
146+
"per_page": 5000,
147+
"include": "submission"
148+
}
149+
150+
assignments_data, status = canvas_request(
151+
BASE_URL + '/courses/' + str(course_id) + '/assignments', auth_header, assignment_params)
152+
153+
assignment_id_list = [] # a list of all the user's courses (their ids)
154+
for assignment_entry in assignments_data:
155+
try:
156+
assignment_id_list.append(assignment_entry['id'])
157+
except Exception as e:
158+
print(e)
159+
160+
return assignment_id_list, assignments_data
161+
162+
163+
'''Given a course ID, return a json object of course information for that particular course'''
164+
165+
166+
def get_course_info(canvas_token, course_id):
167+
auth_header = {'Authorization': 'Bearer ' + canvas_token}
168+
course_url = BASE_URL + '/courses/' + str(course_id)
169+
return canvas_request(url=course_url, headers=auth_header, params={})
170+
171+
172+
'''Given a course ID and assignment ID, return a dict of assignment information for that particular assignment'''
173+
174+
175+
def parse_assignments(assignments, course_title):
176+
177+
tasks = []
178+
179+
for a in assignments:
180+
submission_details = {}
181+
182+
due = a['due_at']
183+
submission_details = a['submission']
184+
185+
submitted = submission_details['submitted_at']
186+
187+
if due != None:
188+
due = due[0:10] # hack into a string UwU
189+
if submitted != None:
190+
submitted = submitted[0:10] # hack into a string UwU
191+
192+
try:
193+
description = bs.BeautifulSoup(a['description'], 'lxml').get_text()
194+
except Exception as e:
195+
description = ""
196+
197+
tasks.append({'title': a['name'] or "No title.",
198+
'due_date': due,
199+
200+
'task_type': 'S',
201+
# 'task_level': 1, # TODO - this should be set here!
202+
# 'recurring': 'false',
203+
# 'recurring_time_delta': 0,
204+
'course_title': course_title,
205+
'completed_date': submitted,
206+
'description': description,
207+
'course_id': a['course_id'],
208+
'assignment_id': a['id'],
209+
})
210+
return tasks
211+
212+
213+
'''Given a list of assignment IDs, return a list where each entry is a dict of assignment information corresponding to those IDs'''
214+
215+
216+
def get_all_assignments(canvas_token):
217+
all_assignments = [] # list of all assignment IDs for all courses
218+
219+
course_info, status = get_courses(canvas_token) # all course IDs
220+
if status != 200:
221+
return None, status
222+
for course in course_info:
223+
# all assignment IDs for one specific course
224+
assignment_ids, assignments = get_assignments(canvas_token, course)
225+
226+
# for assignment_id in assignment_ids:
227+
# assignment_info = get_assignment_info(canvas_token, course_id, assignment_id)
228+
# all_assignments.append(assignment_info) # add each assignment dict from this course to list
229+
_assignments = parse_assignments(assignments, course[1])
230+
all_assignments = all_assignments+_assignments
231+
232+
return all_assignments, status

0 commit comments

Comments
 (0)