From 2bcfce7bfd7bdedd98110c962e1908161674a2ce Mon Sep 17 00:00:00 2001 From: Corentin Date: Sat, 26 Oct 2024 12:25:03 +0200 Subject: [PATCH] Can add and delete courses --- redis_app/templates/courses.html | 6 ++ redis_app/templates/create.html | 32 ++++++++ redis_app/templates/details.html | 11 +++ redis_app/templates/profile.html | 1 + redis_app/urls.py | 5 +- redis_app/views.py | 129 ++++++++++++++++++++++++++----- 6 files changed, 163 insertions(+), 21 deletions(-) create mode 100644 redis_app/templates/create.html diff --git a/redis_app/templates/courses.html b/redis_app/templates/courses.html index 4f4b769..36a9b68 100644 --- a/redis_app/templates/courses.html +++ b/redis_app/templates/courses.html @@ -8,5 +8,11 @@ {% else %}

No course yet

{% endif %} +
+ {% if person %} + {% if person.role == "Teacher" %} + Create + {% endif %} + {% endif %} \ No newline at end of file diff --git a/redis_app/templates/create.html b/redis_app/templates/create.html new file mode 100644 index 0000000..67fce04 --- /dev/null +++ b/redis_app/templates/create.html @@ -0,0 +1,32 @@ + + +
+ {% csrf_token %} +
+

Create a course

+ + {% if error_message %} + {{ error_message }} + {% endif %} + +
+
+ +
+
+ +
+
+ +
+
+
+ + +
+ + diff --git a/redis_app/templates/details.html b/redis_app/templates/details.html index 760ece5..b07de7e 100644 --- a/redis_app/templates/details.html +++ b/redis_app/templates/details.html @@ -1,5 +1,11 @@ + {% if error_message %} + {{ error_message }} + {% endif %} + {% if success_message %} + {{ success_message }} + {% endif %} {% if course %}

Welcome in the course {{ course.title }}!

@@ -14,5 +20,10 @@ {% else %}

No course found!

{% endif %} + {% if person %} + {% if person.role == "Teacher" %} + Delete + {% endif %} + {% endif %} \ No newline at end of file diff --git a/redis_app/templates/profile.html b/redis_app/templates/profile.html index 6d5fa1d..6de4c27 100644 --- a/redis_app/templates/profile.html +++ b/redis_app/templates/profile.html @@ -15,5 +15,6 @@ + Home \ No newline at end of file diff --git a/redis_app/urls.py b/redis_app/urls.py index 1b03e77..1a4abfb 100644 --- a/redis_app/urls.py +++ b/redis_app/urls.py @@ -3,7 +3,6 @@ from . import views urlpatterns = [ path('', views.home, name='home'), - path('', views.details, name='details'), path('register_form', views.register_form, name='register_form'), path('register', views.register, name='register'), path('login_form', views.login_form, name='login_form'), @@ -12,4 +11,8 @@ urlpatterns = [ path('change_profile', views.change_profile, name='change_profile'), path('profile', views.profile, name='profile'), path('logout', views.logout, name='logout'), + path('create_course', views.create_course_view, name='create_course'), + path('create_course_form', views.create_course_form, name='create_course_form'), + path('', views.details, name='details'), + path('delete/', views.delete_course_view, name='delete_course'), ] \ No newline at end of file diff --git a/redis_app/views.py b/redis_app/views.py index 027e037..19c286e 100644 --- a/redis_app/views.py +++ b/redis_app/views.py @@ -8,25 +8,62 @@ 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 course is None: + 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") - return render(request, 'details.html', {'course': course}) + 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') @@ -48,6 +85,8 @@ def register(request): 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') @@ -63,18 +102,26 @@ def login(request): 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] @@ -85,7 +132,7 @@ def courses(request): course_data = redis_connection.hgetall(key) if personLoggedIn['role'] == "Student": if person_id in course_data.get("students", "").split(","): - course_id = getCourseId(course_data['title'], course_data['teacher']) + course_id = getCourseId2(course_data['title'], course_data['teacher']) if course_id == False: continue course_data['id'] = course_id.split(":")[1] @@ -93,7 +140,7 @@ def courses(request): else: teacher_id = course_data["teacher"] if teacher_id == person_id: - course_id = getCourseId(course_data['title'], course_data['teacher']) + course_id = getCourseId2(course_data['title'], course_data['teacher']) if course_id == False: continue course_data['id'] = course_id.split(":")[1] @@ -102,6 +149,8 @@ def courses(request): 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!"}) @@ -122,6 +171,8 @@ def change_profile(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}) @@ -130,28 +181,20 @@ def profile(request): -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 getCourseId(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 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() @@ -164,6 +207,35 @@ def create_course(course_title, course_summary, course_level, course_places, cou }) 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 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] + course_key = f"course:{uuid.uuid4()}" + redis_connection.hset(course_key, mapping={ + 'title': course_title, + 'summary': course_summary, + 'level': course_level, + 'places': course_places, + 'teacher': course_teacher + }) + return courses(request) + + return render(request, 'create.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}") @@ -211,6 +283,23 @@ def refresh_expire(course_id): 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 \ No newline at end of file