Merge branch 'development'

DWorking

B

W
.
This commit is contained in:
Rushil Umaretiya 2020-06-10 01:53:35 -04:00
commit 05faf2b2dc
42 changed files with 1998 additions and 170 deletions

126
.gitignore vendored
View File

@ -128,11 +128,129 @@ dmypy.json
# Pyre type checker # Pyre type checker
.pyre/ .pyre/
# PyCharm Files
.idea/
# VSCode # VSCode
.vscode/ .vscode/
#lmao mac # PyCharm Files
.idea/
# Mac lmao
.DS_Store .DS_Store
# Django #
*.log
*.pot
*.pyc
__pycache__
db.sqlite3
media
# Backup files #
*.bak
# If you are using PyCharm #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/gradle.xml
.idea/**/libraries
*.iws /out/
# Python #
*.py[cod]
*$py.class
# Distribution / packaging
.Python build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery
celerybeat-schedule.*
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# mkdocs documentation
/site
# mypy
.mypy_cache/
# Sublime Text #
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
*.sublime-workspace
*.sublime-project
# sftp configuration file
sftp-config.json
# Package control specific files Package
Control.last-run
Control.ca-list
Control.ca-bundle
Control.system-ca-bundle
GitHub.sublime-settings
# Visual Studio Code #
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history

1
2022rkhondak Submodule

@ -0,0 +1 @@
Subproject commit 8dca8b78c03fab721e9976a4675e2996802328a7

View File

@ -5,134 +5,4 @@ import os
import argparse import argparse
#already ccrerrated account through website, has to login
def update():
#get data from database
return
def yesorno(question):
questions = [
{
'type': 'input',
'name': 'response',
'message': question,
},
]
answers = prompt(questions)
if(answers["response"] == "y"):
return True
return False
def login():
#enter username
#enter password
questions = [
{
'type': 'input',
'name': 'webmail',
'message': 'What\'s TJ Webmail',
},
{
'type': 'password',
'name': 'password',
'message': 'Password?',
},
]
user = prompt(questions)
#reading from json of users (replace w GET to database) to check if user is registered
with open('users.json', 'r') as json_file:
data = json.load(json_file)
for i in range(len(data)):
if user["webmail"] == data[i]["webmail"]:
if(user["password"] == data[i]["password"]):
print("Logged in!")
return data[i]
else:
print("Password incorrect. Try again.")
return None
print("User not found. Please Try again")
return None
#did not create account through website, has to signup/login
def signup():
questions = [
{
'type': 'input',
'name': 'first-name',
'message': 'What\'s your first name',
},
{
'type': 'input',
'name': 'last-name',
'message': 'What\'s your last name?',
},
{
'type': 'list',
'name': 'grade',
'message': 'Grade?',
'choices':["9","10","11","12"]
},
{
'type': 'input',
'name': 'webmail',
'message': 'What\'s your TJ Webmail?',
},
{
'type': 'password',
'name': 'password',
'message': 'Password?',
},
]
user = prompt(questions)
for i in user:
if user[i] == "":
print("Some forms were left blank. Try again.\n")
return None
if len(user["password"]) < 6:
print("Password is too short. Try again.")
return None
if (("@tjhsst.edu" in user['webmail']) == False):
print("Webmail entered was not a @tjhhsst.edu. Try again.")
return None
user["classes"] = []
with open('users.json', 'r') as json_file:
data = json.load(json_file)
data.append(user)
open("users.json", "w").write(str(json.dumps(data)))
return user
def relogin():
questions = [
{
'type': 'list',
'name': 'choice',
'message': '',
'choices':["Continue as current user","Login into new user","Sign up into new account"]
},
]
answer = prompt(questions)
def setup(user):
#Read classes/assignenments and setup directory:
#SkoolOS/Math/Week1
for c in user["classes"]:
os.makedirs("../" + c)
for a in user["classes"][c]:
os.makedirs("../" + c + "/" + a)
def start():
if(os.path.exists(".login.txt") == False):
b = yesorno("Do you have a SkoolOS account?(y/N)")
if(b):
user = login()
if(user != None):
setup(user)
open(".login.txt", "w").write(str(user))
else:
user = signup()
if(user != None):
open(".login.txt").write(str(user))

9
CLI/index.html Normal file
View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Sign in with Ion</title>
</head>
<body>
Sign in with
</body>
</html>

23
CLI/oauth/index.html Normal file
View File

@ -0,0 +1,23 @@
<html>
<head>
<title>Sign into Ion</title>
<style>
body {
background: #5ac8fb;
background: -webkit-linear-gradient(to left, #52edc7, #5ac8fb);
background: linear-gradient(to left, #52edc7, #5ac8fb);
}
</style>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<div class="d-flex align-items-center justify-content-center" style="height: 100vh">
<a href="https://ion.tjhsst.edu/oauth/authorize/?response_type=code&client_id=QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2F&scope=read&state=w4hxAszhLTubmyrMqEbaJO6qAM4wCJ" title="Ion" class="border border-dark p-3 btn btn-lg mx-auto" style="box-shadow: 5px 10px;">
<img src="https://ion.tjhsst.edu/static/img/favicon.png">
Sign in with Ion
</a>
</div>
</body>
</html>

23
CLI/oauth/template.html Normal file
View File

@ -0,0 +1,23 @@
<html>
<head>
<title>Sign into Ion</title>
<style>
body {
background: #5ac8fb;
background: -webkit-linear-gradient(to left, #52edc7, #5ac8fb);
background: linear-gradient(to left, #52edc7, #5ac8fb);
}
</style>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<div class="d-flex align-items-center justify-content-center" style="height: 100vh">
<a href="AUTH_URL" title="Ion" class="border border-dark p-3 btn btn-lg mx-auto" style="box-shadow: 5px 10px;">
<img src="https://ion.tjhsst.edu/static/img/favicon.png">
Sign in with Ion
</a>
</div>
</body>
</html>

21
CLI/requirements.txt Normal file
View File

@ -0,0 +1,21 @@
asgiref==3.2.7
certifi==2020.4.5.1
chardet==3.0.4
click==7.1.2
Django==3.0.7
django-cors-middleware==1.5.0
django-oauth-toolkit==1.3.2
djangorestframework==3.11.0
idna==2.9
oauthlib==3.1.0
prompt-toolkit==1.0.14
Pygments==2.6.1
PyInquirer==1.0.3
pytz==2020.1
regex==2020.5.14
requests==2.23.0
selenium==3.141.0
six==1.15.0
sqlparse==0.3.1
urllib3==1.25.9
wcwidth==0.2.3

View File

@ -1,22 +0,0 @@
from __future__ import print_function, unicode_literals
from PyInquirer import prompt, print_json
from commands import start, update
import argparse
import json
import os
import argparse
my_parser = argparse.ArgumentParser(prog='skool', description='Let SkoolOS control your system', epilog="Try again")
my_parser.add_argument('--init', action="store_true") #returns true if run argument
args = my_parser.parse_args()
update()
outputs = vars(args)
if(outputs['init']):
start()

101
CLI/s-git.py Normal file
View File

@ -0,0 +1,101 @@
import subprocess
import os
import requests
import pprint
import json
#git clone student directory ==> <student-id>/classes/assignments
def initStudent(ion_user):
#check if git has already been initialized
if(os.path.exists(str(ion_user) +"/" + ".git")):
print("Already synced to: " + str(ion_user))
return
#get student repo from API
URL = "http://127.0.0.1:8000/students/" + ion_user + "/"
r = requests.get(url = URL, auth=('student','_$YFE#34.9_37jr'))
if(r.status_code == 200):
data = r.json()
repo = data['repo']
classes = data['classes']
print(data)
#git clone repo
process = subprocess.Popen(['git', 'clone', repo], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.wait()
# make classes directory
for c in classes:
cpath = str(ion_user) + "/" + c['name']
if(os.path.exists(cpath)):
print(cpath + " already exists...")
else:
os.mkdir(str(ion_user) + "/" + c['name'])
#make assignments directory
for a in c['assignments']:
path = str(ion_user) + "/" + c['name'] + "/" + a['name']
print(path)
if(os.path.exists("/" +path)):
print(path + " already exists...")
else:
os.mkdir(str(ion_user) + "/" + c['name'] + "/" + a['name'])
#push to remote repo
os.chdir(ion_user)
process = subprocess.Popen(['git', 'init'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.wait()
process = subprocess.Popen(['git', 'add', '.'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.wait()
process = subprocess.Popen(['git', 'commit', '-m', "First Commit"], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.wait()
process = subprocess.Popen(['git', 'push', '-u', 'origin','master'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.wait()
elif(r.status_code == 404):
print("Make new account!")
elif(r.status_code == 403):
print("Invalid username/password")
else:
print(r.status_code)
#Teachers
#make student repo by student id
def addStudent(stid, teacher):
os.mkdir(stid)
os.chdir(os.getcwd() + "/" + stid)
process = subprocess.Popen(['git', 'init'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.communicate()
process = subprocess.Popen(['git', 'add', '.'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.communicate()
process = subprocess.Popen(['git', 'commit', '-m', "First Commit"], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.communicate()
def addStudents(filename):
print(filename)
def addAsignment(name):
print(name)
def updateAssignment(name):
print(name)
def comment(filename, text):
print(text)
#initStudent("2022rkhondak")
ion_user = "2022rkhondak"
headers = {'Content-type': 'application/json'}
data = {'first_name': 'Jeff',
'git': 'https://github.com/',
'grade': 10,
'ion_user': '2022jlol1',
'last_name': 'lol.',
'student_id': 11111
}
data = json.dumps(data)
URL = "http://127.0.0.1:8000/students/" + ion_user + "/"
r = requests.put(url = URL, data= data, headers=headers ,auth=('raffukhondaker','hackgroup1'))
pprint.pprint(r.json())

23
CLI/server.py Normal file
View File

@ -0,0 +1,23 @@
from socket import *
from selenium import webdriver
import http.server
import socketserver
import threading
def create_server():
port = 8000
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), handler)
print("serving at port:" + str(port))
httpd.serve_forever()
threading.Thread(target=create_server).start()
print("Server has started. Continuing..")
browser = webdriver.Chrome()
browser.get("http://localhost:8000")
assert "<title>" in browser.page_source

View File

@ -3,15 +3,19 @@ from urllib.parse import urlparse
import requests import requests
from requests_oauthlib import OAuth2Session from requests_oauthlib import OAuth2Session
from selenium import webdriver; from selenium import webdriver
import os.path import os.path
import time import time
import http.server
import socketserver
from threading import Thread
from werkzeug.urls import url_decode
client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6' client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6'
client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY' client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY'
redirect_uri = 'http://localhost:8000/' redirect_uri = 'http://localhost:8000/'
token_url = 'https://ion.tjhsst.edu/oauth/token/' token_url = 'https://ion.tjhsst.edu/oauth/token/'
scope=["read"] scope = ["read"]
def main(): def main():
@ -25,38 +29,79 @@ def main():
if not os.path.exists(".profile"): if not os.path.exists(".profile"):
authenticate() authenticate()
print(open(".profile", "r").read())
else: else:
print(open(".profile", "r").read()) print(open(".profile", "r").read())
while True:
pass
def authenticate(): def authenticate():
oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope) oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/") authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
web_dir = os.path.join(os.path.dirname(__file__), 'oauth')
os.chdir(web_dir)
if os.path.exists("index.html"):
os.remove("index.html")
template = open("template.html", "r")
index = open("index.html", "w")
for line in template:
index.write(line.replace('AUTH_URL', authorization_url))
template.close()
index.close()
# server = Thread(target=create_server)
# server.daemon = True
# server.start()
browser = webdriver.Chrome() browser = webdriver.Chrome()
browser.get(authorization_url) browser.get("localhost:8000/")
while "http://localhost:8000/?code" not in browser.current_url: while "http://localhost:8000/?code" not in browser.current_url:
http.server.
time.sleep(0.25) time.sleep(0.25)
code = urlparse(browser.current_url).query[5:] url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/?", ""))
code = gets.get("code")
if state == gets.get("state"):
state = gets.get("state")
print("states good")
browser.quit() browser.quit()
print(code)
print(state)
payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id, payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id,
'client_secret': client_secret, 'csrfmiddlewaretoken': state} 'client_secret': client_secret, 'csrfmiddlewaretoken': state}
token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json() token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json()
print(token) print(token)
# headers = {'Authorization': f"Bearer {token['access_token']}"} headers = {'Authorization': f"Bearer {token['access_token']}"}
#
# # And finally get the user's profile!
# profile = requests.get("https://ion.tjhsst.edu/api/profile", headers=headers).json()
# username = profile['ion_username']
# email = profile['tj_email']
# first_name = profile['first_name']
# last_name = profile['last_name']
#print(profile) # And finally get the user's profile!
profile = requests.get("https://ion.tjhsst.edu/api/profile", headers=headers).json()
print(profile)
username = profile['ion_username']
email = profile['tj_email']
first_name = profile['first_name']
last_name = profile['last_name']
profileFile = open(".profile", "w")
profileFile.write(profile)
profileFile.close()
# server.stop
def create_server():
port = 8000
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), handler)
print("serving at port:" + str(port))
httpd.serve_forever()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

457
CLI/t-git-old.py Normal file
View File

@ -0,0 +1,457 @@
import subprocess
import os
import requests
import webbrowser
import pprint
import json
#git clone student directory ==> <student-id>/classes/assignments
'''
{
"url": "http://127.0.0.1:8000/teachers/eharris1/",
"first_name": "Errin",
"last_name": "Harris",
"classes": [
{
"url": "http://127.0.0.1:8000/classes/1/",
"name": "Math5",
"assignments": [
{
"name": "Week1_HW",
"due_date": "2020-06-07T07:46:30.537197Z",
"url": "http://127.0.0.1:8000/assignments/1/",
"files": [
{
"name": "instructions.txt"
}
]
},
{
"name": "Week2_HW",
"due_date": "2020-06-07T07:46:30.548596Z",
"url": "http://127.0.0.1:8000/assignments/2/",
"files": [
{
"name": "instructions.txt"
}
]
}
],
"repo": ""
}
],
"git": "therealraffi",
"ion_user": "eharris1"
},
'''
#get teacher info from api
def getTeacher(ion_user):
URL = "http://127.0.0.1:8000/teachers/" + ion_user + "/"
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
if(r.status_code == 200):
data = r.json()
return data
elif(r.status_code == 404):
return None
print("Make new account!")
elif(r.status_code == 403):
return None
print("Invalid username/password")
else:
return None
print(r.status_code)
def getDB(url):
r = requests.get(url = url, auth=('raffukhondaker','hackgroup1'))
return r.json()
class Teacher:
def __init__(self, data):
# teacher info already stored in API
# intitialze fields after GET request
self.first_name=data['first_name']
self.last_name=data['last_name']
self.git=data['git']
self.username=data['ion_user']
self.url= "http://127.0.0.1:8000/teachers/" + self.username + "/"
classes=data['classes'].split(",")
cdict = []
for cid in classes:
adict=[]
c = getDB("http://127.0.0.1:8000/classes/" + cid + "/")
name=c['name']
repo=c['repo']
path=c['path']
teacher=c['teacher']
id=c['id']
assignments=c['assignments'].split(",")
dfs = c['default_file'].split(' ')
dfdict=[]
for fid in dfs:
f = getDB("http://127.0.0.1:8000/files/" + fid + "/")
fname=f['name']
fpath=f['path']
dfdict.append({
'name':fname,
'path':fpath,
'classes':classes,
'assignment':"none",
'id':fid,
})
for aid in assignments:
fdict=[]
a = getDB("http://127.0.0.1:8000/assignments/" + aid + "/")
aname= a['name']
due_date = a['due_date']
apath=a['path']
classes=a['classes']
files = a['files'].split(' ')
for fid in files:
f = getDB("http://127.0.0.1:8000/files/" + fid + "/")
fname=f['name']
fpath=f['path']
fdict.append({
'name':fname,
'path':fpath,
'classes':classes,
'assignment':aname,
'id':fid,
})
adict.append({
'name':aname,
'due_date':due_date,
'path':apath,
'classes':classes,
'teacher':teacher,
'files':fdict,
})
cdict.append({
'name':name,
'path':path,
'teacher':teacher,
'assignments':adict,
'default_file':adict,
})
self.classes = cdict
def command(self,command):
ar = []
command = command.split(" ")
for c in command:
ar.append(c)
process = subprocess.Popen(ar, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p=process.poll()
output = process.communicate()[0]
#print(output.decode('utf-8'))
def initTeacher(self):
if(os.path.exists(self.username )):
print("Already synced to: " + str(self.username))
return
os.mkdir(self.username)
classes = self.classes
# make classes directory
for c in classes:
cname= c['name']
cpath = self.username + "/" + cname
input("Make new Git Repo with name: " + cname + " (Press any key to continue)\n")
webbrowser.open('https://github.com/new')
input("Repo created? (Press any key to continue)\n")
url='https://github.com/' + self.git + "/" + cname
print(url)
while(requests.get(url).status_code != 200):
print(requests.get(url))
r = input("Repo not created yet. (Press any key to continue after repo created, or 'N' to exit)\n")
if(r=="N" or r=="No"):
return
cdir = os.getcwd()
os.chdir(self.username)
self.command('git clone ' + url)
os.chdir(cdir)
#make class directory
#make default files for each class
for filename in c['default_file']:
f=open(cpath+"/"+filename['name'], "w")
f.close()
#make assignments directory
for a in c['assignments']:
path = cpath + "/" + a['name']
if(os.path.exists(path)):
print(path + " already exists...")
else:
os.mkdir(path)
f=open(path + "/instructions.txt", "w")
f.close()
#push to remote repo
os.chdir(cpath)
print(cpath)
self.command('git add .')
self.command('git commit -m Hello_Class')
self.command('git push -u origin master')
def checkGit(self, ass):
for a in ass:
if a =='.git':
return True
return False
def compareDB(self, fdict, url):
URL = url
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
data = r.json()['results']
allfiles = data
# far = []
# for f in allfiles:
# far.append(f['path'])
for f in fdict:
URL = url
in_db = False
pid=None
for dbf in allfiles:
if(dbf['path'] == f['path']):
in_db=True
break
if(in_db==False):
r = requests.post(url = URL, data=f , auth=('raffukhondaker','hackgroup1'))
print("POST: (" + URL + "): " + f['path'])
f['url']=r.json()['url']
print(r.status_code)
else:
URL = URL + str(dbf['id']) + "/"
r = requests.put(url = URL, data=f , auth=('raffukhondaker','hackgroup1'))
print(r.status_code)
print("UPDATED: (" + URL + "): " + f['path'])
f['url']=r.json()['url']
f['id']=dbf['id']
print(f)
return fdict
#update API and Github, all assignments / classes
def update(self):
#lists all classes
classes = os.listdir(self.username)
#checks all class directories first
for c in classes:
path = self.username + "/" + c
if(self.checkClass(path) == False):
return
cdict = []
for c in classes:
path = self.username + "/" + c
#lists all assignments and default files
ass = os.listdir(path)
#if no .git, directory not synced to git or API
if (self.checkGit(ass)==False):
self.addClass(path)
else:
#push to git
loc = os.getcwd()
os.chdir(path)
self.command('git add .')
self.command('git commit -m "Update"')
self.command('git push -u origin master')
os.chdir(loc)
ass.remove('.git')
loc = os.getcwd()
os.chdir(path)
repo = self.command('git config --get remote.origin.url')
os.chdir(loc)
#assignments
adict = []
#default files for classes
fdict=[]
#default files for assignments
afdict=[]
for a in ass:
aname=a
path = self.username + "/" + c + "/" + a
#need to add option
due_date= '2020-06-07T07:46:30.537197Z',
#check for default file
if(os.path.isfile(path)):
fdict.append({
'name':a,
'path':path
})
elif(os.path.isdir(path)):
for af in os.listdir(path):
path = path+ "/" + af
if(os.path.isfile(path)):
afdict.append({
'name':af,
'path':path
})
path = self.username + "/" + c + "/" + a
adict.append({
'name':aname,
'due_date': due_date[0],
'path':path,
'files':afdict
})
fdict=self.compareDB(fdict, "http://127.0.0.1:8000/files/")
afdict=self.compareDB(afdict,"http://127.0.0.1:8000/files/")
adict=self.compareDB(adict, 'http://127.0.0.1:8000/assignments/')
path = self.username + "/" + c
cdict.append({
'name':c,
'repo': repo,
'path':path,
'assignments':adict,
'default_file':fdict,
})
cdict=self.compareDB(cdict,'http://127.0.0.1:8000/classes/')
mdict= {
'first_name':self.first_name,
'last_name':self.last_name,
'git':self.git,
'ion_user':self.username,
'classes':cdict,
}
data = json.dumps(mdict)
# r = requests.put(url = 'http://127.0.0.1:8000/teachers/eharris1/', data=data, headers={'Content-type': 'application/json'} , auth=('raffukhondaker','hackgroup1'))
# print(print(r.json()))
#class name format: <course-name>_<ion_user>
#turn existing directory into class, Pre-condition: directory exists
#relative path to class: 2022rkhondak/Math4
def checkClass(self,path):
cname = path.split("/")
cname = cname[len(cname)-1]
if(("_" + self.username) in cname) == False:
print("Incorrect class name: Must be in the format: <course-name>_<ion_user>")
return False
dirs = os.listdir(path)
#checks if there is a file (not within Assignments) in class, need at least 1
deffile = False
#checks if there is a file in an Assignment, need at least 1 (default True in case no assignments)
as_file = True
as_bad = ""
for d in dirs:
if(os.path.isfile(d)):
deffile=True
if(os.path.isdir(d)) and d != '.git':
#checks if there is a file in an Assignment, need at least 1
as_file = False
asdir = os.listdir(d)
for a in asdir:
if(os.path.isfile(a)):
as_file=True
if(as_file==False):
as_bad = a
break
if(as_file==False):
print("Assignment '" + as_bad + "' does not have a default file!")
return False
if(deffile):
print("Need a default file in the " + path + " Directory!")
return False
return True
#adds class to git, not API
def addClasstoGit(self, path):
cname = path.split("/")
cname = cname[len(cname)-1]
#push to remote repo
if(self.checkClass(path)):
input("Make new Git Repo with name: " + cname + " (Press any key to continue)\n")
webbrowser.open('https://github.com/new')
input("Repo created? (Press any key to continue)\n")
url='https://github.com/' + self.git + "/" + cname
print(url)
while(requests.get(url).status_code != 200):
print(requests.get(url))
r = input("Repo not created yet. (Press any key to continue after repo created, or 'N' to exit)\n")
if(r=="N" or r=="No"):
return None
cdir = os.getcwd()
os.chdir(path)
self.command('git init')
self.command('git add .')
self.command('git commit -m Hello_Class')
self.command('git remote add origin ' + url + '.git')
self.command('git push -u origin master')
os.chdir(cdir)
#make a new class from scratch
def makeClass(self, subject):
cname = subject + "_" + self.username
os.chdir(self.username)
#check if class exists
if(os.path.exists(cname)):
print("Already synced to: " + str(self.username))
return
else:
os.mkdir(cname)
f=open(cname + "/README.md", "w")
f.close()
#push to remote repo
os.chdir(cname)
command(self, 'git init')
command(self, 'git add .')
command(self, 'git commit -m "Hello Class!"')
#git remote add origin git@github.com:alexpchin/<reponame>.git
command(self, 'git remote add origin git@github.com:'+ self.git + "/" + cname + ".git")
command(self, 'git push -u origin master')
cinfo=[
{
"name":cname,
"assignments":[],
"repo": "https://github.com:" + self.git + "/" + cname + ".git",
"default_file": [
{
"name":"README.md"
}
]
}
]
#update rest API
self.classes.append(cinfo)
update(self)
data = {
"url": self.url,
"first_name": self.first_name,
"last_name": self.first_name,
"classes": self.classes,
"git": self.git,
"ion_user": self.username
},
r = requests.put(url = self.url, data= data, headers={'Content-type': 'application/json'} ,auth=('raffukhondaker','hackgroup1'))
#make student repo by student id
def addStudent(self,stid):
print(stid)
def comment(self):
print("heheheh")
# data = getData("eharris1")
data={'url': 'http://127.0.0.1:8000/teachers/eharris1/', 'first_name': 'Errin', 'last_name': 'Harris', 'git': 'therealraffi', 'ion_user': 'eharris1', 'classes': [{'url': 'http://127.0.0.1:8000/classes/1/', 'name': 'Math5_eharris1', 'repo': 'http://127.0.0.1:8000/assignments/3/', 'assignments': [{'name': 'Week1_HW', 'due_date': '2020-06-07T07:46:30.537197Z', 'url': 'http://127.0.0.1:8000/assignments/1/', 'files': [{'name': 'instructions.txt'}]}, {'name': 'Week2_HW', 'due_date': '2020-06-07T07:46:30.548596Z', 'url': 'http://127.0.0.1:8000/assignments/2/', 'files': [{'name': 'instructions.txt'}]}], 'default_file': [{'name': 'instructions.txt'}]}]}
t = Teacher(data)
t.update()

366
CLI/t-git.py Normal file
View File

@ -0,0 +1,366 @@
import subprocess
import os
import requests
import webbrowser
import pprint
import json
import shutil
import time
import pyperclip
#git clone student directory ==> <student-id>/classes/assignments
#get teacher info from api
def getTeacher(ion_user):
URL = "http://127.0.0.1:8000/teachers/" + ion_user + "/"
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
if(r.status_code == 200):
data = r.json()
return data
elif(r.status_code == 404):
return None
print("Make new account!")
elif(r.status_code == 403):
return None
print("Invalid username/password")
else:
return None
print(r.status_code)
def getDB(url):
r = requests.get(url = url, auth=('raffukhondaker','hackgroup1'))
print("GET:" + str(r.status_code))
return(r.json())
def postDB(data, url):
r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
print("POST:" + str(r.status_code))
return(r.json())
def putDB(data, url):
r = requests.put(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
print("PUT:" + str(r.status_code))
return(r.json())
def delDB(url):
r = requests.delete(url = url, auth=('raffukhondaker','hackgroup1'))
print("DELETE:" + str(r.status_code))
return None
def command(command):
ar = []
command = command.split(" ")
for c in command:
ar.append(c)
process = subprocess.Popen(ar, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p=process.poll()
output = process.communicate()[1]
#print(output.decode('utf-8'))
#public methods: deleteClass, makeClass, update
class Teacher:
def __init__(self, data):
# teacher info already stored in API
# intitialze fields after GET request
self.first_name=data['first_name']
self.last_name=data['last_name']
self.git=data['git']
self.username=data['ion_user']
self.url= "http://127.0.0.1:8000/teachers/" + self.username + "/"
#classes in id form (Example: 4,5)
cid=data['classes'].split(",")
try:
cid.remove('')
except:
pass
try:
cid.remove("")
except:
pass
classes=[]
for c in cid:
url = "http://127.0.0.1:8000/classes/" + str(c) + "/"
classes.append(getDB(url))
self.classes = classes
self.sclass=str(data['classes'])
if(os.path.isdir(self.username)):
print("Synced to " + self.username)
else:
os.mkdir(self.username)
#update API and Github, all assignments / classes
def update(self):
#lists all classes
ignore=['.git','.DS_Store']
classes = os.listdir(self.username)
for i in ignore:
try:
classes.remove(i)
except:
pass
#list of classes that have been deleted (not with deleteClass)
extra = []
for c in self.classes:
extra.append(c)
for i in range(len(extra)):
e = extra[i]['path']
extra[i] = e
print("Extra: "+str(extra))
print("Local:" + str(classes))
#checks all class directories first
for c in classes:
path = self.username + "/" + c
if(self.checkClass(path) == False):
return
extra.remove(path)
print("Current classes: " + path)
for e in extra:
self.deleteClass(e)
for i in range(len(classes)):
c = classes[i]
path = self.username + "/" + c
#lists all assignments and default files
#if no .git, directory not synced to git or API
if (self.checkInDB(path)==False):
self.addClass(path)
else:
#push to git
loc = os.getcwd()
os.chdir(path)
command('git fetch origin')
command('git pull origin master')
command('git add .')
command('git commit -m "Update"')
command('git push -u origin master')
os.chdir(loc)
#class name format: <course-name>_<ion_user>
#turn existing directory into class, Pre-condition: directory exists
#relative path to class: 2022rkhondak/Math4
def checkClass(self,path):
cname = path.split("/")
cname = cname[len(cname)-1]
if(os.path.isfile(path)):
print(path + " must be in a Class directory.")
return False
if(("_" + self.username) in cname) == False:
print("Incorrect class name: Must be in the format: " + self.username+ "/<course-name>_<ion_user>, not " + path)
return False
dirs = os.listdir(path)
#checks if there is a file (not within Assignments) in class, need at least 1
deffile = False
#checks if there is a file in an Assignment, need at least 1 (default True in case no assignments)
as_file = True
as_bad = ""
for d in dirs:
if(os.path.isfile(d)):
deffile=True
else:
#checks if there is a file in an Assignment, need at least 1
as_file = False
asdir = os.listdir(path + "/" + d)
for a in asdir:
if(os.path.isfile(path + "/" + d + "/" +a)):
as_file=True
if(as_file==False):
as_bad = d
break
if(as_file==False):
print("Assignment '" + as_bad + "' does not have a default file!")
return False
if(deffile==False):
print("Need a default file in the " + path + " Directory!")
return False
return True
def checkInDB(self, path):
n = path.split("/")
n = n[len(n)-1]
for c in self.classes:
if(n == c['name']):
return True
return False
#adds class to git, not API
#Assuming valid class name
def addClasstoGit(self, path):
cname = path.split("/")
cname = cname[len(cname)-1]
#push to remote repo
url='https://github.com/' + self.git + "/" + cname
if(requests.get(url).status_code != 200):
input("Make new Git Repo with name: " + cname + " (Press any key to continue)\n")
try:
pyperclip.copy(cname)
print(cname + " copied to clipboard.")
except:
pass
time.sleep(2)
webbrowser.open('https://github.com/new')
input("Repo created? (Press any key to continue)\n")
print(url)
while(requests.get(url).status_code != 200):
r = input("Repo not created yet. (Press any key to continue after repo created, or 'N' to exit)\n")
if(r=="N" or r=="No"):
return None
cdir = os.getcwd()
os.chdir(path)
command('git init')
command('git add .')
command('git commit -m Hello_Class')
command('git remote add origin ' + url + '.git')
command('git push -u origin master')
else:
cdir = os.getcwd()
os.chdir(path)
print("Repo already exists. Cloning instead.")
command('git clone')
command('git fetch origin')
command('git pull')
command('git add .')
command('git commit -m Hello_Class')
command('git push -u origin master')
os.chdir(cdir)
print(cdir)
data={
'name':cname,
'repo':url,
'path':path,
'teacher':self.username
}
return data
#make class from existing directory, add to git and api
def addClass(self, path):
if (self.checkClass(path)):
data = self.addClasstoGit(path)
#make class instance in db
data = postDB(data, 'http://127.0.0.1:8000/classes/')
#add to instance
#upate self.classes
self.classes.append(data)
if(len(self.sclass)==0):
self.sclass = data['id']
else:
self.sclass = self.sclass + "," + str(data['id'])
#update teacher instance in db, classes field
data={
'first_name':self.first_name,
'last_name':self.last_name,
'git':self.git,
'ion_user':self.username,
'url':self.url,
'classes':self.sclass
}
putDB(data, self.url)
return data
#make a new class from scratch
#subject: string, assignments: list
#class name must be: <subject>_<ion_user>
def makeClass(self, cname, assignments):
#check if class exists
path = self.username + "/" + cname
if(os.path.exists(path)):
print("Class already exists: " + cname)
return
else:
if((("_" + self.username) in cname) == False):
print("class name must be: "+ cname + "_" + self.username)
return
cdir = os.getcwd()
os.mkdir(path)
f=open(path + "/README.md", "w")
f.close()
#push to remote repo
os.chdir(path)
for a in assignments:
os.mkdir(a)
f=open(a + "/instructions.txt", "w")
f.close()
os.chdir(cdir)
data = self.addClass(path)
return data
def deleteClass(self, path):
if(os.path.exists(path) == False):
print(path + " does not exist locally.")
resp = input("Do you want to delete " + path + " from the SkoolOS system? (y/N) ")
if(resp != 'y'):
return
cname = path.split("/")
cname = cname[len(cname)-1]
cid = None
repo = ''
for c in self.classes:
if cname == c['name']:
cid = str(c['id'])
repo = c['repo']
#remove from api
for i in range(len(self.classes)):
if(self.classes[i]['id'] == int(cid)):
print("DELETE: " + self.classes[i]['name'])
del self.classes[i]
s=""
#recreate sclass field, using ids
for c in self.classes:
s = s + str(c['id']) + ","
print(s)
s = s[:-1]
print(s)
data={
'first_name':self.first_name,
'last_name':self.last_name,
'git':self.git,
'ion_user':self.username,
'url':self.url,
'classes':s
}
print(putDB(data, self.url))
delDB("http://127.0.0.1:8000/classes/" + cid + "/")
break
#remove locally
try:
shutil.rmtree(path)
except:
pass
#remove from git
input("Delete repository: " + cname + ". Scroll to the bottom of the page and press 'Delete this repository' (Press any key to continue) ")
print(repo)
time.sleep(2)
webbrowser.open(repo + "/settings")
input("Repo deleted? (Press any key to continue) ")
print(repo)
while(requests.get(repo).status_code == 200):
r = input("Repo still no deleted yet. (Press any key to continue after repo deleted, or 'N' to exit)\n")
if(r=="N" or r=="No" or r=='n'):
return None
#make student repo by student id
def addStudent(self,stid):
print(stid)
def comment(self):
print("heheheh")
data = getTeacher("eharris1")
t = Teacher(data)
t.makeClass('English11_eharris1', ["Essay1"])
t.update()

16
CLI/test.py Normal file
View File

@ -0,0 +1,16 @@
import subprocess
import os
import time
def command(command):
ar = []
command = command.split(" ")
for c in command:
ar.append(c)
process = subprocess.Popen(ar, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p=process.poll()
output = process.communicate()[0]
print(output)
command('echo hello')
command('python runtest.py')

2
CLI/text.py Normal file
View File

@ -0,0 +1,2 @@
import textract
text = textract.process('test.py')

View File

@ -1 +0,0 @@
[{"first_name": "Raffu", "last_name": "Khondaker", "password": "password", "webmail": "2022rkhondak@tjhsst.edu", "classes": {"Math": ["week1_hw", "week2_hw", "week3_hw", "unit3_quiz"], "English": ["journal1", "journal2", "journal3"]}}]

0
Website/api/__init__.py Normal file
View File

3
Website/api/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
Website/api/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class ApiConfig(AppConfig):
name = 'api'

0
Website/api/auth.py Normal file
View File

128
Website/api/maker.py Normal file
View File

@ -0,0 +1,128 @@
from datetime import datetime
f1 = DefFiles(
name="instructions.txt"
)
f1.save()
f2 = DefFiles(
name="instructions.txt"
)
f2.save()
f3 = DefFiles(
name="sample.txt"
)
f3.save()
f4 = DefFiles(
name="rubric.txt"
)
f4.save()
a1 = Assignment.objects.get(pk=1)
a1.files.add(f1)
a1.save()
a2 = Assignment.objects.get(pk=2)
a2.files.add(f2)
a2.save()
a3 = Assignment.objects.get(pk=3)
a3.files.add(f3)
a3.files.add(f4)
a3.save()
####################################
from api.models import Assignment, Student, Classes, Teacher, DefFiles
from datetime import datetime
f1 = DefFiles(
name="instructions.txt"
)
f1.save()
f2 = DefFiles(
name="instructions.txt"
)
f2.save()
f3 = DefFiles(
name="sample.txt"
)
f3.save()
f4 = DefFiles(
name="rubric.txt"
)
f4.save()
A1 = Assignment(
name='Week1_HW',
due_date=datetime.now(),
)
A1.save()
A1.files.add(f1)
A1.save()
A2 = Assignment(
name='Week2_HW',
due_date=datetime.now(),
)
A2.save()
A2.files.add(f2)
A2.save()
A3 = Assignment(
name='Journal1',
due_date=datetime.now(),
)
A3.save()
A3.files.add(f3)
A3.files.add(f4)
A3.save()
#classes
math = Classes(
name='Math5',
)
math.save()
math.assignments.add(A1)
math.assignments.add(A2)
math.save()
english = Classes(
name='English',
)
english.save()
english.assignments.add(A3)
english.save()
#students
raffu = Student(
first_name = "Raffu",
last_name = "Khondaker",
student_id = 1579460,
ion_user="2022rkhondak",
webmail = "2022rkhondak@tjhsst.edu",
grade = 10,
repo="https://github.com/therealraffi/2022rkhondak.git",
)
raffu.save()
raffu.classes.add(math)
raffu.classes.add(english)
raffu.save()
#teachers
ng = Teacher(
first_name = "Errin",
last_name = "Harris",
ion_user="eharris1"
)
ng.save()
ng.classes.add(math)
ng.save()
chao = Teacher(
first_name = "Abagail",
last_name = "Bailey",
ion_user="AKBailey"
)
chao.save()
chao.classes.add(english)
chao.save()

View File

@ -0,0 +1,75 @@
# Generated by Django 3.0.7 on 2020-06-09 02:03
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Assignment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('due_date', models.DateTimeField()),
('files', models.CharField(max_length=100)),
('path', models.CharField(max_length=100)),
('classes', models.CharField(max_length=100)),
('teacher', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Classes',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('repo', models.URLField(default='')),
('path', models.CharField(default='', max_length=100)),
('teacher', models.CharField(default='', max_length=100)),
('assignments', models.CharField(default='', max_length=100)),
('default_file', models.CharField(default='', max_length=100)),
],
),
migrations.CreateModel(
name='DefFiles',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('path', models.CharField(max_length=100)),
('assignment', models.CharField(default='', max_length=100)),
('classes', models.CharField(max_length=100)),
('teacher', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Teacher',
fields=[
('created', models.DateTimeField(auto_now_add=True)),
('first_name', models.CharField(max_length=100)),
('last_name', models.CharField(max_length=100)),
('classes', models.CharField(default='', max_length=100)),
('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)),
('git', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Student',
fields=[
('created', models.DateTimeField(auto_now_add=True)),
('first_name', models.CharField(max_length=100)),
('last_name', models.CharField(max_length=100)),
('student_id', models.IntegerField()),
('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)),
('webmail', models.EmailField(blank=True, max_length=254)),
('grade', models.IntegerField()),
('git', models.CharField(max_length=100)),
('repo', models.URLField(default='')),
('classes', models.ManyToManyField(default='', to='api.Classes')),
],
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-09 03:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='teacher',
name='classes',
field=models.CharField(blank=True, default='', max_length=100),
),
]

View File

59
Website/api/models.py Normal file
View File

@ -0,0 +1,59 @@
from django.db import models
class DefFiles(models.Model):
name=models.CharField(max_length=100)
path=models.CharField(max_length=100)
assignment=models.CharField(max_length=100, default="")
classes=models.CharField(max_length=100)
teacher=models.CharField(max_length=100)
class Assignment(models.Model):
name=models.CharField(max_length=100)
due_date=models.DateTimeField()
# files = models.ManyToManyField(DefFiles)
files=models.CharField(max_length=100)
path=models.CharField(max_length=100)
classes=models.CharField(max_length=100)
teacher=models.CharField(max_length=100)
def __str__(self):
return '%s' % (self.name)
class Classes(models.Model):
name = models.CharField(max_length=100)
repo=models.URLField(default="")
path=models.CharField(max_length=100, default="")
teacher=models.CharField(max_length=100, default="")
assignments=models.CharField(max_length=100, default="")
default_file=models.CharField(max_length=100, default="")
# assignments = models.ManyToManyField(Assignment, default="")
# default_file = models.ManyToManyField(DefFiles)
def save(self, *args, **kwargs):
return super(Classes, self).save(*args, **kwargs)
class Teacher(models.Model):
created = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
# classes = models.ManyToManyField(Classes, default="")
classes=models.CharField(max_length=100, default="", blank=True)
ion_user=models.CharField(primary_key=True, max_length=100)
git=models.CharField(max_length=100)
class Student(models.Model):
created = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
student_id = models.IntegerField()
ion_user=models.CharField(primary_key=True, max_length=100)
webmail = models.EmailField(blank=True)
grade = models.IntegerField()
git=models.CharField(max_length=100)
classes = models.ManyToManyField(Classes, default="")
repo = models.URLField(default="")
def save(self, *args, **kwargs):
return super(Student, self).save(*args, **kwargs)

View File

@ -0,0 +1,37 @@
from django.contrib.auth.models import User, Group
from .models import Student, Teacher, Classes, Assignment, DefFiles
from rest_framework import serializers, permissions
class DefFilesSerializer(serializers.HyperlinkedModelSerializer):
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta:
model = DefFiles
fields = ['name', 'path','assignment','classes', "teacher",'url', 'id']
class AssignmentSerializer(serializers.HyperlinkedModelSerializer):
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
# files = DefFilesSerializer(many=True, read_only=True,allow_null=True)
class Meta:
model = Assignment
fields = ['name', 'due_date', 'url', 'path' , "classes","teacher",'files', 'id']
class ClassesSerializer(serializers.HyperlinkedModelSerializer):
# assignments = AssignmentSerializer(many=True, read_only=True,allow_null=True)
# default_file=DefFilesSerializer(many=True, read_only=True,allow_null=True)
class Meta:
model = Classes
fields = ['url', 'name', 'repo','path', "teacher",'assignments',"default_file",'id']
class StudentSerializer(serializers.HyperlinkedModelSerializer):
classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
class Meta:
model = Student
fields = ['url', 'first_name', 'last_name', 'grade','webmail','student_id', 'git','repo','ion_user','classes']
class TeacherSerializer(serializers.ModelSerializer):
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
class Meta:
model = Teacher
fields = ['url', 'first_name', 'last_name','git','ion_user','classes']

3
Website/api/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

0
Website/api/urls.py Normal file
View File

131
Website/api/views-back.py Normal file
View File

@ -0,0 +1,131 @@
# class StudentList(APIView):
# """
# List all snippets, or create a new snippet.
# """
# def get(self, request, format=None):
# snippets = Student.objects.all()
# serializer = StudentSerializer(snippets, many=True)
# return response.Response(serializer.data)
# def post(self, request, format=None):
# serializer = StudentSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class StudentDetail(APIView):
# """
# Retrieve, update or delete a snippet instance.
# """
# def get_object(self, pk):
# try:
# return Student.objects.get(pk=pk)
# except Student.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = StudentSerializer(snippet)
# return response.Response(serializer.data)
# def put(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = StudentSerializer(snippet, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None):
# snippet = self.get_object(pk)
# snippet.delete()
# return response.Response(status=status.HTTP_204_NO_CONTENT)
# class TeacherList(APIView):
# """
# List all snippets, or create a new snippet.
# """
# def get(self, request, format=None):
# snippets = Teacher.objects.all()
# serializer = TeacherSerializer(snippets, many=True)
# return response.Response(serializer.data)
# def post(self, request, format=None):
# serializer = TeacherSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class TeacherDetail(APIView):
# """
# Retrieve, update or delete a snippet instance.
# """
# def get_object(self, pk):
# try:
# return Teacher.objects.get(pk=pk)
# except Teacher.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = TeacherSerializer(snippet)
# return response.Response(serializer.data)
# def put(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = TeacherSerializer(snippet, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None):
# snippet = self.get_object(pk)
# snippet.delete()
# return response.Response(status=status.HTTP_204_NO_CONTENT)
# class ClassesList(APIView):
# """
# List all snippets, or create a new snippet.
# """
# def get(self, request, format=None):
# snippets = Classes.objects.all()
# serializer = ClassesSerializer(snippets, many=True)
# return response.Response(serializer.data)
# def post(self, request, format=None):
# serializer = ClassesSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class ClassesDetail(APIView):
# """
# Retrieve, update or delete a snippet instance.
# """
# def get_object(self, pk):
# try:
# return Classes.objects.get(pk=pk)
# except Classes.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = ClassesSerializer(snippet)
# return response.Response(serializer.data)
# def put(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = ClassesSerializer(snippet, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None):
# snippet = self.get_object(pk)
# snippet.delete()
# return response.Response(status=status.HTTP_204_NO_CONTENT)

48
Website/api/views.py Normal file
View File

@ -0,0 +1,48 @@
from .models import Student, Teacher, Classes, Assignment, DefFiles
from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, DefFilesSerializer
from rest_framework import generics, viewsets, permissions, response, status
from django.http import Http404
from rest_framework.views import APIView
class StudentViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Student.objects.all()
serializer_class = StudentSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
class TeacherViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Teacher.objects.all()
serializer_class = TeacherSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
class ClassesViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Classes.objects.all()
serializer_class = ClassesSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
class AssignmentViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
class DefFilesViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = DefFiles.objects.all()
serializer_class = DefFilesSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]

21
Website/manage.py Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolsite.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

View File

16
Website/skoolsite/asgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
ASGI config for skoolsite project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolsite.settings')
application = get_asgi_application()

View File

@ -0,0 +1,131 @@
"""
Django settings for skoolsite project.
Generated by 'django-admin startproject' using Django 3.0.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '$v+-0wm%yys7r3&e0s&*tyh-vyc9v&twb_8yk6==290io9yq3('
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api',
]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'skoolsite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'skoolsite.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'

22
Website/skoolsite/urls.py Normal file
View File

@ -0,0 +1,22 @@
from django.urls import path
from rest_framework import routers
from api import views
from django.contrib import admin
from django.conf.urls import include
router = routers.DefaultRouter()
router.register(r'students', views.StudentViewSet)
router.register(r'teachers', views.TeacherViewSet)
router.register(r'assignments', views.AssignmentViewSet)
router.register(r'classes', views.ClassesViewSet)
router.register(r'files', views.DefFilesViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
]

16
Website/skoolsite/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for skoolsite project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolsite.settings')
application = get_wsgi_application()

View File

@ -0,0 +1,3 @@
{% block page_content %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "base.html" %}
{% block content %}
<p>Logged out!</p>
<a href="{% url 'login'%}">Click here to login again.</a>
{% endblock %}

View File

@ -0,0 +1,37 @@
{% extends "base.html" %}
{% block page_content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{# Assumes you setup the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
{% endblock %}

View File

@ -1,6 +1,21 @@
asgiref==3.2.7
certifi==2020.4.5.1
chardet==3.0.4
click==7.1.2
Django==3.0.7
django-cors-middleware==1.5.0
django-oauth-toolkit==1.3.2
djangorestframework==3.11.0
idna==2.9
oauthlib==3.1.0
prompt-toolkit==1.0.14 prompt-toolkit==1.0.14
Pygments==2.6.1 Pygments==2.6.1
PyInquirer==1.0.3 PyInquirer==1.0.3
pytz==2020.1
regex==2020.5.14 regex==2020.5.14
requests==2.23.0
selenium==3.141.0
six==1.15.0 six==1.15.0
sqlparse==0.3.1
urllib3==1.25.9
wcwidth==0.2.3 wcwidth==0.2.3

2
runtest.py Normal file
View File

@ -0,0 +1,2 @@
for i in range(0, 100000):
print(i)