You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
12 KiB

from django.shortcuts import render
from django.http import Http404
import redis
import uuid
from redis_app.utils.index import create_index
# This model only helps us the development part to set rules on objects (we do not use the django model to save objects in it)
from .models import Person
DEFAULT_EXPIRE_TIME = 120
EXPIRE_REFRESH_TIME = 60
COURSE_CHANNEL = "course"
cancel = True
personLoggedIn = ""
redis_connection = redis.Redis(host='localhost', port=6379, decode_responses=True)
pub_sub = redis_connection.pubsub()
create_index(redis_connection=redis_connection)
def getPersonId(person_name, person_role):
query = f"@name:{person_name} @role:{person_role}"
results = redis_connection.execute_command('FT.SEARCH', 'idx:persons', query)
if results[0] > 0:
person_key = results[1]
return person_key
return False
def getCourseId2(course_title, course_teacher):
query = f"@title:{course_title} @teacher:{course_teacher}"
results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', query)
if results[0] > 0:
course_key = results[1]
return course_key
return False
def getCourseId(course):
return getCourseId2(course.get("title"), course.get("teacher"))
def home(request, person=''):
global cancel
cancel = True
return render(request, 'home.html', {'person': person})
def details(request, course_id):
global redis_connection
global cancel
global personLoggedIn
cancel = True
course = redis_connection.hgetall(f"course:{course_id}")
if not course:
raise Http404("Course does not exist")
course_id = getCourseId2(course['title'], course['teacher'])
if course_id == False:
raise Http404("Course does not exist")
course['id'] = course_id.split(":")[1]
return render(request, 'details.html', {'course': course, 'person': personLoggedIn})
# Handle error messages.
def register(request):
global personLoggedIn
global redis_connection
global cancel
cancel = True
if request.method == 'POST':
person_name = request.POST.get('name')
person_role = request.POST.get('role')
query = f"@name:{person_name} @role:{person_role}"
results = redis_connection.execute_command('FT.SEARCH', 'idx:persons', query)
# First element = number of results
if results[0] > 0:
return render(request, 'register.html', {'person': Person(name="", role=""), "error_message": "This user already exists!"})
person_key = f"person:{uuid.uuid4()}"
redis_connection.hset(person_key, mapping={
'name': person_name,
'role': person_role
})
personLoggedIn = redis_connection.hgetall(person_key)
return home(request, personLoggedIn)
return render(request, 'register.html', {'person': Person(name="", role=""), "error_message": "The form has been wrongly filled!"})
def login(request):
global personLoggedIn
global redis_connection
global cancel
cancel = True
if request.method == 'POST':
person_name = request.POST.get('name')
person_role = request.POST.get('role')
query = f"@name:{person_name} @role:{person_role}"
results = redis_connection.execute_command('FT.SEARCH', 'idx:persons', query)
if results[0] > 0:
person_key = results[1]
personLoggedIn = redis_connection.hgetall(person_key)
return home(request, personLoggedIn)
return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "No user found!"})
return login_form(request)
def register_form(request):
global cancel
cancel = True
return render(request, 'register.html', {'person': Person(name="", role="")})
def login_form(request):
global cancel
cancel = True
return render(request, 'login.html', {'person': Person(name="", role="")})
def logout(request):
global personLoggedIn
global cancel
cancel = True
personLoggedIn = ""
return render(request, 'login.html', {'person': Person(name="", role="")})
def courses(request):
global personLoggedIn
global cancel
cancel = True
if personLoggedIn == "":
return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"})
person_id = getPersonId(personLoggedIn["name"], personLoggedIn["role"]).split(":")[1]
course_keys = redis_connection.keys(f"course:*")
courses = []
for key in course_keys:
course_data = redis_connection.hgetall(key)
if personLoggedIn['role'] == "Student":
if person_id in course_data.get("students", "").split(","):
course_id = getCourseId2(course_data['title'], course_data['teacher'])
if course_id == False:
continue
course_data['id'] = course_id.split(":")[1]
courses.append(course_data)
else:
teacher_id = course_data["teacher"]
if teacher_id == person_id:
course_id = getCourseId2(course_data['title'], course_data['teacher'])
if course_id == False:
continue
course_data['id'] = course_id.split(":")[1]
courses.append(course_data)
return render(request, 'courses.html', {'person': personLoggedIn, 'courses': courses})
def change_profile(request):
global personLoggedIn
global cancel
cancel = True
if personLoggedIn == '':
return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"})
if request.method == 'POST':
person_name = request.POST.get('name')
person_role = request.POST.get('role')
person_id = getPersonId(personLoggedIn["name"], personLoggedIn["role"])
if not person_id:
return render(request, 'profile.html', {'person': personLoggedIn, "error_message": "Internal error: No user found!"})
redis_connection.hmset(person_id, mapping={"name": person_name, "role": person_role})
personLoggedIn["name"] = person_name
personLoggedIn["role"] = person_role
return render(request, 'profile.html', {'person': personLoggedIn})
return login_form(request)
def profile(request):
global personLoggedIn
global cancel
cancel = True
if personLoggedIn == '':
return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"})
return render(request, 'profile.html', {'person': personLoggedIn})
def delete_course(course_id):
course = redis_connection.hgetall(f"course:{course_id}")
if not course:
return False
redis_connection.delete(f"course:{course_id}")
return True
def delete_course_view(request, course_id):
global personLoggedIn
res = delete_course(course_id)
if not res:
return courses(request)
return courses(request)
def create_course(course_title, course_summary, course_level, course_places, course_teacher):
course_id = uuid.uuid4()
redis_connection.hset(f"course:{course_id}", mapping={
"title": course_title,
"summary": course_summary,
"level": course_level,
"places": course_places,
"teacher": course_teacher
})
redis_connection.expire(f"course:{course_id}", DEFAULT_EXPIRE_TIME)
def update_course(course_id, course_title, course_summary, course_level, course_places, course_teacher):
redis_connection.hset(f"course:{course_id}", mapping={
"title": course_title,
"summary": course_summary,
"level": course_level,
"places": course_places,
"teacher": course_teacher
})
redis_connection.expire(f"course:{course_id}", DEFAULT_EXPIRE_TIME)
def create_course_view(request):
global personLoggedIn
return render(request, 'create.html', {'person': personLoggedIn})
def update_course_view(request, course_id):
global personLoggedIn
course = redis_connection.hgetall(f"course:{course_id}")
if not course:
raise Http404("Course does not exist")
course_id = getCourseId2(course['title'], course['teacher'])
if course_id == False:
raise Http404("Course does not exist")
course['id'] = course_id.split(":")[1]
return render(request, 'update.html', {'person': personLoggedIn, 'course': course})
def create_course_form(request):
global personLoggedIn
global redis_connection
global cancel
cancel = True
if personLoggedIn == '':
return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"})
if request.method == 'POST':
course_title = request.POST.get('title')
course_summary = request.POST.get('summary')
course_level = request.POST.get('level')
course_places = request.POST.get('places')
course_teacher = getPersonId(personLoggedIn.get('name'), personLoggedIn.get('role')).split(":")[1]
create_course(course_title, course_summary, course_level, course_places, course_teacher)
return courses(request)
return render(request, 'create.html', {'person': personLoggedIn, "error_message": "The form has been wrongly filled!"})
def update_course_form(request, course_id):
global personLoggedIn
global redis_connection
global cancel
cancel = True
if personLoggedIn == '':
return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"})
if request.method == 'POST':
course_title = request.POST.get('title')
course_summary = request.POST.get('summary')
course_level = request.POST.get('level')
course_places = request.POST.get('places')
course_teacher = getPersonId(personLoggedIn.get('name'), personLoggedIn.get('role')).split(":")[1]
update_course(course_id, course_title, course_summary, course_level, course_places, course_teacher)
return courses(request)
return render(request, 'update.html', {'person': personLoggedIn, "error_message": "The form has been wrongly filled!"})
def course_register(course_id, person_id):
course = redis_connection.hgetall(f"course:{course_id}")
person = redis_connection.hgetall(f"person:{person_id}")
if not course or not person:
return False
students = course.get('students', '')
if person_id in students.split(','):
return True
if students:
new_students = person_id
else:
new_students = students + "," + person_id
redis_connection.hset(f"course:{course_id}", "students", new_students)
return True
def course_unregister(course_id, person_id):
course = redis_connection.hgetall(f"course:{course_id}")
person = redis_connection.hgetall(f"person:{person_id}")
if not course or not person:
return False
students = course.get('students', '')
if person_id not in students.split(','):
return True
students_list = students.split(",")
if len(students_list) == 1:
new_students = ""
else:
new_students = ",".join([student for student in students_list if student != person_id])
redis_connection.hset(f"course:{course_id}", "students", new_students)
return True
def refresh_expire(course_id):
course = redis_connection.hgetall(f"course:{course_id}")
if not course:
return False
ttl = redis_connection.ttl(f"course:{course_id}")
if ttl <= 0:
return False
redis_connection.expire(f"course:{course_id}", ttl + EXPIRE_REFRESH_TIME)
return True
def publish(course):
pub_sub.publish(COURSE_CHANNEL + ":" + getCourseId(course), str(course))
# Courses is a list of coursee id to subscribe to
def subscribe(courses_id):
global cancel
cancel = False
pub_sub.psubscribe(*courses_id)
for message in pub_sub.listen():
if cancel:
break
if message["type"] != 'pmessage':
continue
send_new_course_notification(message)
def send_new_course_notification(message):
print(message)
# Every id is only the number, not the course:number or person:number