summaryrefslogtreecommitdiff
path: root/yaksh/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'yaksh/models.py')
-rw-r--r--yaksh/models.py129
1 files changed, 113 insertions, 16 deletions
diff --git a/yaksh/models.py b/yaksh/models.py
index 12bada8..1eca721 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -13,6 +13,8 @@ from django.contrib.contenttypes.models import ContentType
from taggit.managers import TaggableManager
from django.utils import timezone
from django.core.files import File
+import glob
+
try:
from StringIO import StringIO as string_io
except ImportError:
@@ -26,7 +28,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 +129,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 +167,13 @@ 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,
+ help_text="Please upload video files in mp4, ogv, webm format"
+ )
+
def __str__(self):
return "{0}".format(self.name)
@@ -182,11 +197,42 @@ 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.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.writestr(filename, lesson_file.file.read())
+ 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):
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):
@@ -491,6 +537,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 +629,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 +883,33 @@ class Course(models.Model):
percentage = 0
return percentage
+ def is_student(self, user):
+ return user in self.students.all()
+
+ 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,
+ static_files)
+ 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()
+ status = False
+ for module in modules:
+ if module.get_lesson_units():
+ status = True
+ break
+ return status
+
def __str__(self):
return self.name
@@ -1020,7 +1111,7 @@ class Question(models.Model):
tags = question.pop('tags') if 'tags' in question else None
test_cases = question.pop('testcase')
que, result = Question.objects.get_or_create(**question)
- if file_names:
+ if file_names and file_path:
que._add_files_to_db(file_names, file_path)
if tags:
que.tags.add(*tags)
@@ -1089,13 +1180,18 @@ class Question(models.Model):
files = FileUpload.objects.filter(question=self)
files_list = []
for f in files:
- zip_file.write(f.file.path, (os.path.basename(f.file.path)))
+ zip_file.write(f.file.path, os.path.join("additional_files",
+ os.path.basename(
+ f.file.path
+ )
+ )
+ )
files_list.append(((os.path.basename(f.file.path)), f.extract))
return files_list
def _add_files_to_db(self, file_names, path):
for file_name, extract in file_names:
- q_file = os.path.join(path, file_name)
+ q_file = glob.glob(os.path.join(path, "**", file_name))[0]
if os.path.exists(q_file):
que_file = open(q_file, 'rb')
# Converting to Python file object with
@@ -1130,16 +1226,17 @@ class Question(models.Model):
shutil.rmtree(tmp_file_path)
def read_yaml(self, file_path, user, files=None):
- yaml_file = os.path.join(file_path, "questions_dump.yaml")
- msg = ""
- if os.path.exists(yaml_file):
- with open(yaml_file, 'r') as q_file:
- questions_list = q_file.read()
- msg = self.load_questions(questions_list, user,
- file_path, files
- )
- else:
- msg = "Please upload zip file with questions_dump.yaml in it."
+ msg = "Failed to upload Questions"
+ for ext in ["yaml", "yml"]:
+ for yaml_file in glob.glob(os.path.join(file_path,
+ "*.{0}".format(ext)
+ )):
+ if os.path.exists(yaml_file):
+ with open(yaml_file, 'r') as q_file:
+ questions_list = q_file.read()
+ msg = self.load_questions(questions_list, user,
+ file_path, files
+ )
if files:
delete_files(files, file_path)