From 20b692ea468a280e3edb4a9e7f97543b5499025d Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 26 Jun 2018 13:13:22 +0530 Subject: Changes in views, models, forms, urls, file_utils - Add new view function to download course content - Add new attribute to Lesson model - Add new model methods to add course, module and lesson content - Add validation in forms to check for lesson video file format - Add functions in file_utils to add static files and templates to the zip file --- yaksh/models.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 5d17dba..b97859d 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -26,7 +26,10 @@ import zipfile import tempfile from textwrap import dedent from ast import literal_eval -from .file_utils import extract_files, delete_files +from .file_utils import ( + extract_files, delete_files, write_templates_to_zip, + write_static_files_to_zip +) from yaksh.code_server import ( submit, get_result as get_result_from_code_server ) @@ -124,7 +127,10 @@ def dict_to_yaml(dictionary): def get_file_dir(instance, filename): - upload_dir = instance.lesson.name.replace(" ", "_") + if isinstance(instance, LessonFile): + upload_dir = instance.lesson.name.replace(" ", "_") + else: + upload_dir = instance.name.replace(" ", "_") return os.sep.join((upload_dir, filename)) @@ -159,6 +165,11 @@ class Lesson(models.Model): # Activate/Deactivate Lesson active = models.BooleanField(default=True) + # A video file + video_file = models.FileField(upload_to=get_file_dir, default=None, + null=True, blank=True + ) + def __str__(self): return "{0}".format(self.name) @@ -182,6 +193,37 @@ class Lesson(models.Model): lesson_file_obj.file.save(file_name, django_file, save=True) return new_lesson + def remove_file(self): + if self.video_file: + file_path = self.video_file.path + if os.path.exists(file_path): + os.remove(file_path) + + def _add_lesson_to_zip(self, module, course, zip_file, path): + lesson_name = self.name.replace(" ", "_") + course_name = course.name.replace(" ", "_") + module_name = module.name.replace(" ", "_") + sub_folder_name = os.sep.join(( + course_name, module_name, lesson_name + )) + lesson_files = self.get_files() + if self.video_file: + video_file = os.sep.join((sub_folder_name, os.path.basename( + self.video_file.name))) + zip_file.write(self.video_file.path, video_file) + for lesson_file in lesson_files: + if os.path.exists(lesson_file.file.path): + filename = os.sep.join((sub_folder_name, os.path.basename( + lesson_file.file.name))) + zip_file.write(lesson_file.file.path, filename) + unit_file_path = os.sep.join(( + path, "templates", "yaksh", "unit.html" + )) + lesson_data = {"course": course, "module": module, + "lesson": self, "lesson_files": lesson_files} + write_templates_to_zip(zip_file, unit_file_path, lesson_data, + lesson_name, sub_folder_name) + ############################################################################# class LessonFile(models.Model): @@ -491,6 +533,10 @@ class LearningModule(models.Model): return [unit.quiz for unit in self.learning_unit.filter( type="quiz")] + def get_lesson_units(self): + return [unit.lesson for unit in self.learning_unit.filter( + type="lesson").order_by("order")] + def get_learning_units(self): return self.learning_unit.order_by("order") @@ -579,6 +625,20 @@ class LearningModule(models.Model): new_module.learning_unit.add(new_unit) return new_module + def _add_module_to_zip(self, course, zip_file, path): + module_name = self.name.replace(" ", "_") + course_name = course.name.replace(" ", "_") + folder_name = os.sep.join((course_name, module_name)) + lessons = self.get_lesson_units() + for lesson in lessons: + lesson._add_lesson_to_zip(self, course, zip_file, path) + module_file_path = os.sep.join(( + path, "templates", "yaksh", "module.html" + )) + module_data = {"course": course, "module": self, "lessons": lessons} + write_templates_to_zip(zip_file, module_file_path, module_data, + module_name, folder_name) + def __str__(self): return self.name @@ -819,6 +879,29 @@ class Course(models.Model): percentage = 0 return percentage + def is_student(self, user): + return user in self.students.all() + + def create_zip(self, zip_file, path): + course_name = self.name.replace(" ", "_") + modules = self.get_learning_modules() + file_path = os.sep.join((path, "templates", "yaksh", "index.html")) + write_static_files_to_zip(zip_file, course_name, path) + course_data = {"course": self, "modules": modules} + write_templates_to_zip(zip_file, file_path, course_data, + "index", course_name) + for module in modules: + module._add_module_to_zip(self, zip_file, path) + + def has_lessons(self): + modules = self.get_learning_modules() + status = False + for module in modules: + if module.get_lesson_units(): + status = True + break + return status + def __str__(self): return self.name -- cgit From ddd2981529798b8c59dec33e50ccf6e808f3bc19 Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 26 Jun 2018 16:03:10 +0530 Subject: Fix course download to support Python 2 and 3 --- yaksh/models.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index b97859d..34aee25 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -210,12 +210,12 @@ class Lesson(models.Model): if self.video_file: video_file = os.sep.join((sub_folder_name, os.path.basename( self.video_file.name))) - zip_file.write(self.video_file.path, video_file) + zip_file.writestr(video_file, self.video_file.read()) for lesson_file in lesson_files: if os.path.exists(lesson_file.file.path): filename = os.sep.join((sub_folder_name, os.path.basename( lesson_file.file.name))) - zip_file.write(lesson_file.file.path, filename) + zip_file.writestr(filename, lesson_file.file.read()) unit_file_path = os.sep.join(( path, "templates", "yaksh", "unit.html" )) @@ -228,7 +228,7 @@ class Lesson(models.Model): ############################################################################# class LessonFile(models.Model): lesson = models.ForeignKey(Lesson, related_name="lesson") - file = models.FileField(upload_to=get_file_dir) + file = models.FileField(upload_to=get_file_dir, default=None) def remove(self): if os.path.exists(self.file.path): @@ -882,16 +882,19 @@ class Course(models.Model): def is_student(self, user): return user in self.students.all() - def create_zip(self, zip_file, path): - course_name = self.name.replace(" ", "_") - modules = self.get_learning_modules() - file_path = os.sep.join((path, "templates", "yaksh", "index.html")) - write_static_files_to_zip(zip_file, course_name, path) - course_data = {"course": self, "modules": modules} - write_templates_to_zip(zip_file, file_path, course_data, - "index", course_name) - for module in modules: - module._add_module_to_zip(self, zip_file, path) + def create_zip(self, path): + zip_file_name = string_io() + with zipfile.ZipFile(zip_file_name, "a") as zip_file: + course_name = self.name.replace(" ", "_") + modules = self.get_learning_modules() + file_path = os.sep.join((path, "templates", "yaksh", "index.html")) + write_static_files_to_zip(zip_file, course_name, path) + course_data = {"course": self, "modules": modules} + write_templates_to_zip(zip_file, file_path, course_data, + "index", course_name) + for module in modules: + module._add_module_to_zip(self, zip_file, path) + return zip_file_name def has_lessons(self): modules = self.get_learning_modules() -- cgit From c075bc00bc57507f2af4d47f7f2e5e063df6921a Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 10 Jul 2018 15:47:46 +0530 Subject: Change in file_utils, forms, models, lesson.css, add_lesson.html, views - Add new function in the file_utils to render template - Add webm as supported video format in forms - Add help text in video_file field - Add lesson.css file for adding custom styling for lessons - Add static_files dict in download_course views function --- yaksh/models.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 34aee25..464eeb5 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -166,9 +166,11 @@ class Lesson(models.Model): active = models.BooleanField(default=True) # A video file - video_file = models.FileField(upload_to=get_file_dir, default=None, - null=True, blank=True - ) + video_file = models.FileField( + upload_to=get_file_dir, default=None, + null=True, blank=True, + help_text="Please upload video files in mp4, ogv, webm format" + ) def __str__(self): return "{0}".format(self.name) @@ -882,13 +884,14 @@ class Course(models.Model): def is_student(self, user): return user in self.students.all() - def create_zip(self, path): + def create_zip(self, path, static_files): zip_file_name = string_io() with zipfile.ZipFile(zip_file_name, "a") as zip_file: course_name = self.name.replace(" ", "_") modules = self.get_learning_modules() file_path = os.sep.join((path, "templates", "yaksh", "index.html")) - write_static_files_to_zip(zip_file, course_name, path) + write_static_files_to_zip(zip_file, course_name, path, + static_files) course_data = {"course": self, "modules": modules} write_templates_to_zip(zip_file, file_path, course_data, "index", course_name) -- cgit