-
-
Save jhamrick/a74f811e1a71f15ae5a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests as req | |
import pandas as pd | |
import dotenv | |
import os | |
import json | |
import subprocess as sp | |
from time import mktime | |
from datetime import datetime | |
from collections import OrderedDict | |
# api documentation: | |
# https://bcourses.berkeley.edu/doc/api/ | |
def upload(fp, sub_url, bcourse, bcourses_path=None): | |
""" | |
Uploads a file on a local machine to bcourses with optional folder path | |
option. | |
""" | |
# Get file token for upload | |
name = os.path.split(fp)[-1] | |
filesize = os.path.getsize(fp) | |
payload = {u'name':unicode(name), u'size':unicode(filesize)} | |
if bcourses_path: | |
payload[u'parent_folder_path'] = unicode(bcourses_path) | |
resp = req.post(sub_url, data=payload, headers=bcourse.header).json() | |
# Upload file data -- the -L tells curl to follow redirects | |
cmd = ["curl", "{}".format(resp['upload_url']), "-L"] | |
for param, val in resp['upload_params'].items(): | |
cmd.extend(["-F", "{}={}".format(param, val)]) | |
cmd.extend(["-F", "file=@{}".format(fp)]) | |
p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) | |
stdout, _ = p.communicate() | |
resp = json.loads(stdout) | |
print(resp) | |
class BCourses(object): | |
def __init__(self, **kwargs): | |
if 'course' not in kwargs.keys(): | |
self.course = u'COG SCI 131' | |
else: | |
self.course = kwargs['course'] | |
dotenv.load_dotenv('.env') | |
oauth = os.environ.get('TOKEN') | |
self.header = {'Authorization': 'Bearer ' + oauth} | |
self.params = {'per_page': 100} | |
self.api = 'https://bcourses.berkeley.edu/api/v1/courses' | |
self.course_id = str(self.get_course_id(self.course)) | |
def get_user_ids(self): | |
enroll = os.path.join(self.api, self.course_id, 'enrollments') | |
linx = req.head(enroll, params=self.params, headers=self.header).links | |
current = linx['current']['url'] | |
resp = req.get(current, params=self.params, headers=self.header) | |
users = pd.DataFrame(columns=['name', 'user_id', 'login_id', 'role']) | |
for idx,ss in enumerate(resp.json()): | |
users.loc[idx,'name'] = ss['user']['sortable_name'].upper() | |
users.loc[idx,'user_id'] = ss['user']['id'] | |
users.loc[idx,'login_id'] = ss['user']['login_id'] | |
users.loc[idx,'role'] = ss['role'] | |
count = idx + 1 | |
# Deal w. pagination; responses are capped at 100 entries per page | |
while 'next' in linx.keys(): | |
nex = linx['next']['url'] | |
resp = req.get(nex, params=self.params, headers=self.header) | |
for idx,ss in enumerate(resp.json()): | |
users.loc[count + idx, 'name'] = ss['user']['sortable_name'] | |
users.loc[count + idx, 'user_id'] = ss['user']['id'] | |
users.loc[count + idx, 'login_id'] = ss['user']['login_id'] | |
users.loc[count + idx, 'role'] = ss['role'] | |
linx = req.head(nex, params=self.params, headers=self.header).links | |
count = count + idx + 1 | |
return users.sort_index(axis=0, by='name').reset_index(drop=True) | |
def upload_comments(self, assgn_name='PS0'): | |
""" UNFINISHED -- Error using upload """ | |
assgn_id = self.get_assignment_id(assgn_name) | |
users = self.get_user_ids() | |
# TODO: only loop through users we have comment files for | |
for u_id in users.user_id: | |
sub = os.path.join(self.api, self.course_id, 'assignments', assgn_id, 'submissions', u_id, 'comments', 'files') | |
c_path = '' # path to comment file | |
upload(c_path, sub, self) | |
def upload_file(self, fp, bcourses_path=None): | |
""" UNFINISHED -- Error using upload """ | |
sub = os.path.join(self.api, self.course_id, 'files') | |
upload(fp, sub, self, bcourses_path) | |
def get_course_id(self, course): | |
resp = req.get(self.api, params=self.params, headers=self.header) | |
for cc in resp.json(): | |
if cc['course_code'] == course: | |
return cc['id'] | |
raise KeyError('Unable to find course %s'%course) | |
def get_assignment_id(self, name='PS0'): | |
assgn_url = os.path.join(self.api, self.course_id, 'assignments') | |
resp = req.get(assgn_url, params=self.params, headers=self.header) | |
for assgn in resp.json(): | |
if assgn['name'] == name: | |
return assgn['id'] | |
raise KeyError('Unable to find assignment %s'%name) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment