Merge branch 'development' of https://github.com/Rushilwiz/SkoolOS into development

This commit is contained in:
Raffu Khondaker 2020-06-14 23:11:58 -04:00
commit 2315f4ff48
23 changed files with 293 additions and 443 deletions

View File

@ -1,56 +1,102 @@
import os
import sys
import signal
import time import time
import event_processor import sys
import os
import pyinotify
class SkoolOSDaemon: class EventHandler(pyinotify.ProcessEvent):
"""Constructor""" _methods = [
def __init__(self, work_dir='/tmp'): "IN_CREATE",
self.work_dir = work_dir "IN_CLOSE_WRITE",
self.start_time = None "IN_DELETE",
self.end_time = None "IN_MOVED_TO",
self.log_file = None "IN_MOVED_FROM",
def __write_pid_file(self): "IN_OPEN",
try: ]
dirName = "/tmp/skooloslogs"
# Create log Directory def process_IN_CREATE(self, event):
os.mkdir(dirName) description = \
except FileExistsError: "Event: Created file\n" \
pass "Event Path: {}\n" \
pid = str(os.getpid()) "Timestamp: {}\n".format(
file_ = open('/tmp/skoolosdaemonpid', 'w') event.pathname,
file_.write(pid) time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
file_.close() )
def readable_time(self, input_time): print(description)
return time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime(input_time))
def start(self): def process_IN_CLOSE_WRITE(self, event):
self.__write_pid_file() description = \
self.start_time = time.time() "Event: Wrote to a file\n" \
self.log_file = open('/tmp/skooloslogs/' + str(self.start_time), 'w') "Event Path: {}\n" \
self.log_file.write("Start time: \n" + self.readable_time(self.start_time) + "\n\n") "Timestamp: {}\n".format(
sys.stdout = self.log_file event.pathname,
event_processor.watch_dir(self.work_dir) time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
def stop(self): )
event_processor.stop_watching() print(description)
self.end_time = time.time()
self.log_file.write("Stop time: \n" + self.readable_time(self.end_time)) def process_IN_DELETE(self, event):
self.log_file.write("Total work time: " + description = \
time.strftime("%H:%M:%S", time.gmtime(self.end_time - self.start_time))) "Event: Deleted file\n" \
"Event Path: {}\n" \
"Timestamp: {}\n".format(
event.pathname,
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
)
print(description)
def process_IN_MOVED_TO(self, event):
description = \
"Event: Moved a file in\n" \
"Event Path: {}\n" \
"Timestamp: {}\n".format(
event.pathname,
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
)
print(description)
def process_IN_MOVED_FROM(self, event):
description = \
"Event: Moved a file out\n" \
"Event Path: {}\n" \
"Timestamp: {}\n".format(
event.pathname,
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
)
print(description)
def process_IN_OPEN(self, event):
description = \
"Event: Opened file\n" \
"Event Path: {}\n" \
"Timestamp: {}\n".format(
event.pathname,
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
)
print(description)
logger = None NOTIFIER = None
def Main():
def signal_handler(signum, frame):
logger.stop()
signal.signal(signal.SIGINT, signal_handler)
# signal.signal(signal.SIGTERM, signal_handler)
global logger
logger = SkoolOSDaemon("/tmp")
logger.start()
if __name__ == "__main__": def watch_dir(watched_dir="/tmp", logdir="/tmp/skooloslogs"):
Main() if not os.path.exists(logdir):
os.makedirs(logdir)
logfile = open(
logdir + "skoolos_" + time.strftime("%m%d%Y-%H%M%S", time.localtime()),
'w')
sys.stdout = logfile
print("Start time: " +
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + "\n\n")
global NOTIFIER
wm = pyinotify.WatchManager()
mask = pyinotify.IN_CREATE | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_DELETE | \
pyinotify.IN_MOVED_TO | pyinotify.IN_MOVED_FROM | pyinotify.IN_OPEN
NOTIFIER = pyinotify.ThreadedNotifier(wm, EventHandler())
NOTIFIER.start()
wm.add_watch(watched_dir, mask, rec=True)
def stop_watching():
NOTIFIER.stop()
print("End time: " +
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + "\n\n")

View File

@ -1,65 +0,0 @@
import time
import pyinotify
def readable_time(input_time):
return time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime(input_time))
class EventProcessor(pyinotify.ProcessEvent):
_methods = ["IN_OPEN",
"IN_CREATE",
"IN_CLOSE_WRITE",
"IN_DELETE",
"IN_MOVED_TO",
"IN_MOVED_FROM",
]
def __method_format(method):
return {
"IN_OPEN":"Opened a file",
"IN_CREATE":"Created a file",
"IN_CLOSE_WRITE":"Wrote to a file",
"IN_DELETE":"Deleted a file",
"IN_MOVED_TO":"Moved a file or directory in from elsewhere",
"IN_MOVED_FROM":"Moved a file or directory elsewhere",
}.get(method, "Unknown event")
def __process_generator(cls, method):
def _method_name(self, event):
description = "Event description: {}\n" \
"Path name: {}\n" \
"Event Name: {}\n" \
"Timestamp: {}\n".format(__method_format(method),
event.pathname,
event.maskname,
readable_time(time.time())
)
if "IN_DELETE" in description:
description += "WARNING: Unexpected file deletion\n"
if "IN_MOVED_TO" in description:
description += "WARNING: Unexpected file add to work\n"
if "IN_MOVED_FROM" in description:
description += "WARNING: Unexpected file moved out of directory\n"
print(description)
_method_name.__name__ = "process_{}".format(method)
setattr(cls, _method_name.__name__, _method_name)
EVENT_NOTIFIER = None
def watch_dir(dir_to_watch):
global EVENT_NOTIFIER
for method in EventProcessor._methods:
__process_generator(EventProcessor, method)
watch_manager = pyinotify.WatchManager()
EVENT_NOTIFIER = pyinotify.ThreadedNotifier(watch_manager, EventProcessor())
watch_manager.add_watch(dir_to_watch, pyinotify.ALL_EVENTS, rec=True)
EVENT_NOTIFIER.loop()
def stop_watching():
EVENT_NOTIFIER.stop()

View File

@ -1,52 +0,0 @@
import pyinotify
wm = pyinotify.WatchManager()
mask = pyinotify.IN_CREATE | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_DELETE | \
pyinotify.IN_MOVED_TO | pyinotify.IN_MOVED_FROM | pyinotify.IN_OPEN
class EventHandler(pyinotify.ProcessEvent):
_methods = ["IN_CREATE",
"IN_CLOSE_WRITE",
"IN_DELETE",
"IN_MOVED_TO",
"IN_MOVED_FROM",
"IN_OPEN",
]
def __process_generator(self, event):
description = \
"Event: {}\n" \
"Event Path: {}\n" \
"Timestamp: {}\n".format(
method,
event.pathname,
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())
)
if "IN_DELETE" in description:
description += "WARNING: Unexpected file deletion\n"
if "IN_MOVED_TO" in description:
description += "WARNING: Unexpected file add to work\n"
if "IN_MOVED_FROM" in description:
description += "WARNING: Unexpected file moved out of directory\n"
return description
def process_IN_CREATE(self, event):
self.__process_generator(event)
def process_IN_CLOSE_WRITE(self, event):
self.__process_generator(event)
def process_IN_DELETE(self, event):
self.__process_generator(event)
def process_IN_MOVED_TO(self, event):
self.__process_generator(event)
def process_IN_MOVED_FROM(self, event):
self.__process_generator(event)
def process_IN_OPEN(self, event):
self.__process_generator(event)
notifier = pyinotify.ThreadedNotifier(wm, EventHandler())
notifier.start()
wdd = wm.add_watch('/tmp', mask, rec=True)
input("Press any key to continue...")
notifier.stop()

View File

@ -1,19 +0,0 @@
from bgservice import SkoolOSDaemon as sod
import threading
logger = sod()
if __name__ == "__main__":
line=1
print(line)
line+=1
logger.start()
print(line)
line+=1
input("Enter any key when you are done modifyng the /tmp/ directory")
print(line)
line+=1
logger.stop()
print(line)
line+=1

View File

@ -2,7 +2,7 @@ from django.contrib import admin
from .models import ( from .models import (
DefFiles, DefFiles,
Assignment, Assignment,
Classes, Class,
Teacher, Teacher,
Student Student
) )
@ -13,4 +13,4 @@ admin.site.register(Teacher)
admin.site.register(Student) admin.site.register(Student)
admin.site.register(DefFiles) admin.site.register(DefFiles)
admin.site.register(Assignment) admin.site.register(Assignment)
admin.site.register(Classes) admin.site.register(Class)

View File

@ -30,7 +30,7 @@
# #
# #################################### # ####################################
# #
# from api.models import Assignment, Student, Classes, Teacher, DefFiles # from api.models import Assignment, Student, Class, Teacher, DefFiles
# from datetime import datetime # from datetime import datetime
# #
# f1 = DefFiles( # f1 = DefFiles(
@ -76,8 +76,8 @@
# A3.files.add(f4) # A3.files.add(f4)
# A3.save() # A3.save()
# #
# #classes # #Class
# math = Classes( # math = Class(
# name='Math5', # name='Math5',
# #
# ) # )
@ -86,7 +86,7 @@
# math.assignments.add(A2) # math.assignments.add(A2)
# math.save() # math.save()
# #
# english = Classes( # english = Class(
# name='English', # name='English',
# ) # )
# english.save() # english.save()
@ -104,8 +104,8 @@
# repo="https://github.com/therealraffi/2022rkhondak.git", # repo="https://github.com/therealraffi/2022rkhondak.git",
# ) # )
# raffu.save() # raffu.save()
# raffu.classes.add(math) # raffu.Class.add(math)
# raffu.classes.add(english) # raffu.Class.add(english)
# raffu.save() # raffu.save()
# #
# #teachers # #teachers
@ -115,7 +115,7 @@
# ion_user="eharris1" # ion_user="eharris1"
# ) # )
# ng.save() # ng.save()
# ng.classes.add(math) # ng.Class.add(math)
# ng.save() # ng.save()
# #
# chao = Teacher( # chao = Teacher(
@ -124,5 +124,5 @@
# ion_user="AKBailey" # ion_user="AKBailey"
# ) # )
# chao.save() # chao.save()
# chao.classes.add(english) # chao.Class.add(english)
# chao.save() # chao.save()

View File

@ -1,4 +1,4 @@
# Generated by Django 3.0.7 on 2020-06-14 19:14 # Generated by Django 3.0.7 on 2020-06-14 23:00
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -14,6 +14,19 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.CreateModel(
name='Class',
fields=[
('name', models.CharField(max_length=100, primary_key=True, serialize=False)),
('description', models.CharField(default='Class Description', max_length=500)),
('repo', models.URLField(blank=True, default='')),
('path', models.CharField(default='', max_length=100)),
('assignments', models.TextField(blank=True, default='')),
('default_file', models.CharField(blank=True, default='', max_length=100)),
('confirmed', models.TextField(blank=True, default='')),
('unconfirmed', models.TextField(blank=True, default='')),
],
),
migrations.CreateModel( migrations.CreateModel(
name='DefFiles', name='DefFiles',
fields=[ fields=[
@ -28,13 +41,9 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='Teacher', name='Teacher',
fields=[ fields=[
('created', models.DateTimeField(auto_now_add=True)), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('first_name', models.CharField(max_length=100)), ('git', models.CharField(blank=True, default='', max_length=100)),
('last_name', models.CharField(max_length=100)), ('classes', models.ManyToManyField(to='api.Class')),
('classes', models.CharField(blank=True, default='', max_length=100)),
('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)),
('git', models.CharField(max_length=100)),
('email', models.CharField(blank=True, default='', max_length=100)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
), ),
@ -42,21 +51,12 @@ class Migration(migrations.Migration):
name='Student', name='Student',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('website', models.CharField(blank=True, default='https://google.com', max_length=150)), ('grade', models.IntegerField(blank=True, default=0)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('git', models.CharField(blank=True, default='', max_length=100)),
],
),
migrations.CreateModel(
name='Classes',
fields=[
('name', models.CharField(max_length=100, primary_key=True, serialize=False)),
('repo', models.URLField(blank=True, default='')), ('repo', models.URLField(blank=True, default='')),
('path', models.CharField(default='', max_length=100)), ('classes', models.CharField(blank=True, default='', max_length=100)),
('teacher', models.CharField(default='', max_length=100)), ('added_to', models.CharField(blank=True, default='', max_length=100)),
('assignments', models.TextField(blank=True, default='')), ('completed', models.TextField(blank=True, default='')),
('default_file', models.CharField(blank=True, default='', max_length=100)),
('confirmed', models.TextField(blank=True, default='')),
('unconfirmed', models.TextField(blank=True, default='')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
), ),

View File

@ -1,52 +0,0 @@
# Generated by Django 3.0.7 on 2020-06-14 20:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='student',
name='website',
),
migrations.AddField(
model_name='student',
name='added_to',
field=models.CharField(blank=True, default='', max_length=100),
),
migrations.AddField(
model_name='student',
name='classes',
field=models.CharField(blank=True, default='', max_length=100),
),
migrations.AddField(
model_name='student',
name='completed',
field=models.TextField(blank=True, default=''),
),
migrations.AddField(
model_name='student',
name='git',
field=models.CharField(blank=True, default='https://github.com/', max_length=100),
),
migrations.AddField(
model_name='student',
name='grade',
field=models.IntegerField(blank=True, default=9),
),
migrations.AddField(
model_name='student',
name='repo',
field=models.URLField(blank=True, default=''),
),
migrations.AddField(
model_name='student',
name='student_id',
field=models.IntegerField(blank=True, default=0),
),
]

View File

@ -0,0 +1,31 @@
# Generated by Django 3.0.7 on 2020-06-15 00:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='class',
name='confirmed',
),
migrations.AddField(
model_name='class',
name='confirmed',
field=models.ManyToManyField(blank=True, related_name='confirmed', to='api.Student'),
),
migrations.RemoveField(
model_name='class',
name='unconfirmed',
),
migrations.AddField(
model_name='class',
name='unconfirmed',
field=models.ManyToManyField(blank=True, related_name='unconfirmed', to='api.Student'),
),
]

View File

@ -1,43 +0,0 @@
# Generated by Django 3.0.7 on 2020-06-14 20:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0002_auto_20200614_2034'),
]
operations = [
migrations.RemoveField(
model_name='student',
name='student_id',
),
migrations.RemoveField(
model_name='teacher',
name='created',
),
migrations.RemoveField(
model_name='teacher',
name='email',
),
migrations.RemoveField(
model_name='teacher',
name='first_name',
),
migrations.RemoveField(
model_name='teacher',
name='last_name',
),
migrations.AlterField(
model_name='student',
name='git',
field=models.CharField(blank=True, default='', max_length=100),
),
migrations.AlterField(
model_name='student',
name='grade',
field=models.IntegerField(blank=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-15 02:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0002_auto_20200615_0046'),
]
operations = [
migrations.AlterField(
model_name='teacher',
name='classes',
field=models.ManyToManyField(blank=True, related_name='teacher', to='api.Class'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 3.0.7 on 2020-06-14 21:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0003_auto_20200614_2044'),
]
operations = [
migrations.AlterField(
model_name='student',
name='grade',
field=models.IntegerField(blank=True, default=0),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 3.0.7 on 2020-06-15 02:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0003_auto_20200615_0233'),
]
operations = [
migrations.RemoveField(
model_name='teacher',
name='classes',
),
migrations.AddField(
model_name='class',
name='teachers',
field=models.ManyToManyField(blank=True, related_name='teachers', to='api.Teacher'),
),
]

View File

@ -1,49 +1,49 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
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):
owner = models.ForeignKey('auth.User', related_name='assignments', on_delete=models.CASCADE)
name=models.CharField(max_length=100, primary_key=True) class Student(models.Model):
due_date=models.DateTimeField()
# files = models.ManyToManyField(DefFiles)
files=models.CharField(max_length=100, default="", blank=True)
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):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
grade = models.IntegerField(default=0, blank=True)
git=models.CharField(default="", max_length=100, blank=True)
repo=models.URLField(default="", blank=True)
classes=models.CharField(max_length=100, default="", blank=True)
added_to=models.CharField(max_length=100, default="", blank=True)
completed=models.TextField(default="", blank=True)
def save(self, *args, **kwargs):
super(Student, self).save(*args, **kwargs)
def __str__(self):
return f"{self.user.username}'s Profile"
class Class(models.Model):
name = models.CharField(primary_key=True, max_length=100) name = models.CharField(primary_key=True, max_length=100)
description = models.CharField(default="Class Description", max_length=500)
repo=models.URLField(default="", blank=True) repo=models.URLField(default="", blank=True)
path=models.CharField(max_length=100, default="") path=models.CharField(max_length=100, default="")
teacher=models.CharField(max_length=100, default="")
assignments=models.TextField(default="", blank=True) assignments=models.TextField(default="", blank=True)
default_file=models.CharField(max_length=100, default="", blank=True) default_file=models.CharField(max_length=100, default="", blank=True)
confirmed=models.TextField(default="", blank=True) confirmed=models.ManyToManyField(Student, blank=True, related_name='confirmed')
unconfirmed=models.TextField(default="", blank=True) unconfirmed=models.ManyToManyField(Student, blank=True, related_name='unconfirmed')
# assignments = models.ManyToManyField(Assignment, default="") # assignments = models.ManyToManyField(Assignment, default="")
# default_file = models.ManyToManyField(DefFiles) # default_file = models.ManyToManyField(DefFiles)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
return super(Classes, self).save(*args, **kwargs) return super(Class, self).save(*args, **kwargs)
def __str__(self):
return self.name
class Teacher(models.Model): class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
# classes = models.ManyToManyField(Classes, default="") classes=models.ManyToManyField(Class, blank=True, related_name='classes')
classes=models.CharField(max_length=100, default="", blank=True) git=models.CharField(max_length=100, default="", blank=True)
ion_user=models.CharField(primary_key=True, max_length=100)
git=models.CharField(max_length=100)
def __str__(self):
return f"{self.user.username}'s Profile"
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super(Teacher, self).save(*args, **kwargs) super(Teacher, self).save(*args, **kwargs)
@ -58,8 +58,26 @@ class Student(models.Model):
added_to=models.CharField(max_length=100, default="", blank=True) added_to=models.CharField(max_length=100, default="", blank=True)
completed=models.TextField(default="", blank=True) completed=models.TextField(default="", blank=True)
def save(self, *args, **kwargs):
super(Student, self).save(*args, **kwargs)
class Assignment(models.Model):
owner = models.ForeignKey('auth.User', related_name='assignments', on_delete=models.CASCADE)
name=models.CharField(max_length=100, primary_key=True)
due_date=models.DateTimeField()
# files = models.ManyToManyField(DefFiles)
files=models.CharField(max_length=100, default="", blank=True)
path=models.CharField(max_length=100)
classes=models.CharField(max_length=100)
teacher=models.CharField(max_length=100)
def __str__(self): def __str__(self):
return f"{self.user.username}'s Profile" return '%s' % (self.name)
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)

View File

@ -9,8 +9,8 @@ urlpatterns = [
path('teachers/<str:pk>/', views.TeacherDetail.as_view()), path('teachers/<str:pk>/', views.TeacherDetail.as_view()),
path('assignments/', views.AssignmentList.as_view()), path('assignments/', views.AssignmentList.as_view()),
path('assignments/<str:pk>/', views.AssignmentDetail.as_view()), path('assignments/<str:pk>/', views.AssignmentDetail.as_view()),
path('classes/', views.ClassesList.as_view()), path('classes/', views.ClassList.as_view()),
path('classes/<str:pk>/', views.ClassesDetail.as_view()), path('classes/<str:pk>/', views.ClassDetail.as_view()),
] ]
urlpatterns = format_suffix_patterns(urlpatterns) urlpatterns = format_suffix_patterns(urlpatterns)

View File

@ -1,5 +1,5 @@
from .models import Student, Teacher, Classes, Assignment, DefFiles from .models import Student, Teacher, Class, Assignment, DefFiles
from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, UserSerializer from .serializers import StudentSerializer, TeacherSerializer, ClassSerializer, AssignmentSerializer, UserSerializer
from rest_framework import generics, viewsets, permissions, response, status from rest_framework import generics, viewsets, permissions, response, status
from django.http import Http404 from django.http import Http404
from rest_framework.views import APIView from rest_framework.views import APIView
@ -14,7 +14,7 @@ from rest_framework.response import Response
class UserViewSet(viewsets.ModelViewSet): class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all() queryset = User.objects.all()
serializer_class = UserSerializer serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated] permission_Class = [permissions.IsAuthenticated]
class StudentViewSet(viewsets.ModelViewSet): class StudentViewSet(viewsets.ModelViewSet):
@ -23,7 +23,7 @@ class StudentViewSet(viewsets.ModelViewSet):
""" """
queryset = Student.objects.all() queryset = Student.objects.all()
serializer_class = StudentSerializer serializer_class = StudentSerializer
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(owner=self.request.user) serializer.save(owner=self.request.user)
@ -34,18 +34,18 @@ class TeacherViewSet(viewsets.ModelViewSet):
""" """
queryset = Teacher.objects.all() queryset = Teacher.objects.all()
serializer_class = TeacherSerializer serializer_class = TeacherSerializer
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(owner=self.request.user) serializer.save(owner=self.request.user)
class ClassesViewSet(viewsets.ModelViewSet): class ClassViewSet(viewsets.ModelViewSet):
""" """
API endpoint that allows users to be viewed or edited. API endpoint that allows users to be viewed or edited.
""" """
queryset = Classes.objects.all() queryset = Class.objects.all()
serializer_class = ClassesSerializer serializer_class = ClassSerializer
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer): def perform_create(self, serializer):
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser): if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
@ -61,7 +61,7 @@ class AssignmentViewSet(viewsets.ModelViewSet):
""" """
queryset = Assignment.objects.all() queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer serializer_class = AssignmentSerializer
permission_classes = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly] permission_Class = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly]
def perform_create(self, serializer): def perform_create(self, serializer):
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser): if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
@ -76,4 +76,4 @@ class AssignmentViewSet(viewsets.ModelViewSet):
# """ # """
# queryset = DefFiles.objects.all() # queryset = DefFiles.objects.all()
# serializer_class = DefFilesSerializer # serializer_class = DefFilesSerializer
# permissions_classes = [permissions.IsAuthenticatedOrReadOnly] # permissions_Class = [permissions.IsAuthenticatedOrReadOnly]

View File

@ -9,7 +9,7 @@ router = routers.DefaultRouter()
router.register(r'students', api_views.StudentViewSet) router.register(r'students', api_views.StudentViewSet)
router.register(r'teachers', api_views.TeacherViewSet) router.register(r'teachers', api_views.TeacherViewSet)
router.register(r'assignments', api_views.AssignmentViewSet) router.register(r'assignments', api_views.AssignmentViewSet)
router.register(r'classes', api_views.ClassesViewSet) router.register(r'classes', api_views.ClassViewSet)
# router.register(r'files', api_views.DefFilesViewSet) # router.register(r'files', api_views.DefFilesViewSet)
router.register(r'users', api_views.UserViewSet) router.register(r'users', api_views.UserViewSet)

View File

@ -13,22 +13,20 @@ body {
color: #333333; color: #333333;
margin-top: 5rem; margin-top: 5rem;
font-family: 'Segoe UI'; font-family: 'Segoe UI';
margin-left: 2.5rem;
margin-right: 2.5rem;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
color: #444444; color: #444444;
} }
ul {
margin: 0;
}
.bg-steel { .bg-steel {
background: #3cba54; background: #3cba54;
} }
.site-header .navbar-nav .nav-link { .site-header .navbar-nav .nav-link {
color: #cbd5db; color: #e1e1e1;
} }
.site-header .navbar-nav .nav-link:hover { .site-header .navbar-nav .nav-link:hover {
@ -38,63 +36,3 @@ ul {
.site-header .navbar-nav .nav-link.active { .site-header .navbar-nav .nav-link.active {
font-weight: 500; font-weight: 500;
} }
.content-section {
background: #ffffff;
padding: 10px 20px;
border: 1px solid #dddddd;
border-radius: 3px;
margin-bottom: 20px;
}
.article-title {
color: #444444;
}
a.article-title:hover {
color: #428bca;
text-decoration: none;
}
.article-content {
white-space: pre-line;
}
.article-img {
height: 65px;
width: 65px;
margin-right: 16px;
}
.article-metadata {
padding-bottom: 1px;
margin-bottom: 4px;
border-bottom: 1px solid #e3e3e3
}
.article-metadata a:hover {
color: #333;
text-decoration: none;
}
.article-svg {
width: 25px;
height: 25px;
vertical-align: middle;
}
.account-img {
height: 125px;
width: 125px;
margin-right: 20px;
margin-bottom: 16px;
}
.account-heading {
font-size: 2.5rem;
}
.nounderline {
text-decoration: none !important;
color: black !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -21,8 +21,8 @@
<nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top"> <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
<div class="container"> <div class="container">
<a class="navbar-brand" href="#"> <a class="navbar-brand" href="#">
<img src="/docs/4.3/assets/brand/bootstrap-solid.svg" width="30" height="30" class="d-inline-block align-top" alt=""> <img src="{% static 'skoolos/tj_trans.png' %}" width="30" height="30" class="d-inline-block align-top" alt="">
Bootstrap SkoolOS
</a> </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>

View File

@ -1,3 +1,15 @@
{% extends "skoolos/base.html" %} {% extends "skoolos/base.html" %}
{% block content %} {% block content %}
<div class="content-section">
{% for class in classes %}
<div class="card-columns">
<a class="card" href="#" style="text-decoration: none;">
<div class="card-body">
<h5 class="card-title">{{ class.name }}</h5>
<p class="card-text">{{ class.description }}</p>
</div>
</a>
</div>
{% endfor %}
</div>
{% endblock content %} {% endblock content %}

View File

@ -1,10 +1,24 @@
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from api.models import Student, Teacher
# Create your views here. # Create your views here.
@login_required() @login_required()
def home (request): def home (request):
try:
student = Student.objects.get(user=request.user)
return render(request, "skoolos/home.html", {'classes': student.confirmed.all()})
except Student.DoesNotExist:
pass
try:
teacher = Teacher.objects.get(user=request.user)
return render(request, "skoolos/home.html", {'classes': teacher.classes})
except Teacher.DoesNotExist:
pass
return render(request, "skoolos/home.html") return render(request, "skoolos/home.html")
@login_required() @login_required()

View File

@ -145,4 +145,4 @@ def create_account (request):
def logout(request): def logout(request):
auth_logout(request) auth_logout(request)
messages.success(request, "You've been logged out!") messages.success(request, "You've been logged out!")
return redirect(request, "/login") return redirect("/login")