diff options
-rw-r--r-- | CHANGELOG.txt | 36 | ||||
-rw-r--r-- | README_production.rst | 30 | ||||
-rw-r--r-- | online_test/__init__.py | 2 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | yaksh/migrations/0009_auto_20180113_1124.py | 149 | ||||
-rw-r--r-- | yaksh/migrations/0010_auto_20180226_1324.py | 34 | ||||
-rw-r--r-- | yaksh/migrations/0011_release_0_8_0.py | 68 |
7 files changed, 282 insertions, 39 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d3364e0..01d80dd 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,8 +1,29 @@ -=== 0.8.0 === +=== 0.8.0 (23-03-2018) === + +* Refactored the add_group command to allow creation of moderator group and add users to moderator group and renamed to create_moderator. +* Deprecated multiple management commands: dump_user_data, load_exam, load_question_xml, results2csv. +* Changed the unit of time_between_attempts field within Quiz model from days to hours. +* Fixed assignment upload feature. +* Error output is displayed using Ajax instead of reloading the entire page. +* Added Mathjax to the repository. +* Added Yaksh logo on the website. +* Changed travis build distribution from precise (Ubuntu 12.04 LTS) to trusty (Ubuntu 14.04 LTS). +* Fixed a bug that allowed creation of multiple answerpapers. +* Added MCQ/MCC Shuffle testcases feature for question paper. +* Added Arrange in Correct Order question type feature. +* Added a feature to create a course with lessons, quizzes and exercises. +* Fixed a bug where a oauth users' email is not verified. +* Added a feature to show per student course completion status. +* Fixed a bug where a moderator could change question paper of other moderator. +* Fixed a bug where a teacher could not access question paper for a course. +* Fixed a bug where a teacher could become the course creator while editing a course. +* Updated clone course feature to create copy of course, lessons, quizzes and learning modules. +* Changed Student dashboard to show the days remaining for a course to start. +* Changed UI for student and moderator dashboard. +* Updated documentation +* Added a feature where a moderator can create exercises. +* Added grading feature which allows a moderator to create a grading system and apply it for a course. -* Added a management command to add users to moderator group -* Renamed add_group management command to create_mod_group -* Deprecated multiple management commands: dump_user_data, load_exam, load_question_xml, results2csv === 0.7.0 (15-11-2017) === @@ -24,8 +45,8 @@ * Added a Datetimepicker to edit course Page. * Added invoke script for quickstart and docker deployment. * Added the facility to send mails to all students enrolled in a course. -* Fixed a bug that would cause issue during email activation key check -* Added comprehensive tests for views.py +* Fixed a bug that would cause issue during email activation key check. +* Added comprehensive tests for views.py. * Fixed a bug that allowed moderators to set cyclic quiz prerequisites in a course. * Added a feature that redirects to edit profile page if user has no profile. * Fixed a bug that would allow enrolled students to attempt quizzes for deactivated courses. @@ -48,7 +69,7 @@ === 0.6.0 (11-05-2017) === * Added a course code field that can be used to search a course. -* Updated the documentation to describe the course code feature +* Updated the documentation to describe the course code feature. * Fixed a bug that prevented redirection based on 'next' parameter after login. * Fixed a bug that littered residual system processes created by code evaluators. * Added the facility to allow moderators to see and download uploaded assignments. @@ -71,4 +92,3 @@ * Fixed a bug that displayed the elements of stdout testcase output as unicode. * Fixed a bug that prevented users from logging in using Google OAuth. * Added coverage reports to travis.yml. - diff --git a/README_production.rst b/README_production.rst index a9bd55b..13fb8f9 100644 --- a/README_production.rst +++ b/README_production.rst @@ -222,33 +222,3 @@ Follow these steps to deploy and run the Django Server, MySQL instance and Code invoke remove 12. You can use ``invoke --list`` to get a list of all the available commands - - -.. _add-commands: - -###################################### -Additional commands available -###################################### - -We provide several convenient commands for you to use: - -- load\_exam : load questions and a quiz from a python file. See - docs/sample\_questions.py - -- load\_questions\_xml : load questions from XML file, see - docs/sample\_questions.xml use of this is deprecated in favor of - load\_exam. - -- results2csv : Dump the quiz results into a CSV file for further - processing. - -- dump\_user\_data : Dump out relevalt user data for either all users - or specified users. - -For more information on these do this: - -:: - - $ python manage.py help [command] - -where [command] is one of the above. diff --git a/online_test/__init__.py b/online_test/__init__.py index a71c5c7..32a90a3 100644 --- a/online_test/__init__.py +++ b/online_test/__init__.py @@ -1 +1 @@ -__version__ = '0.7.0' +__version__ = '0.8.0' @@ -6,6 +6,7 @@ README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read() # allow setup.py to be run from any path os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) + def get_version(): import os data = {} @@ -24,6 +25,7 @@ install_requires = [ 'invoke==0.21.0', 'six', 'requests', + 'markdown==2.6.9', ] setup( diff --git a/yaksh/migrations/0009_auto_20180113_1124.py b/yaksh/migrations/0009_auto_20180113_1124.py new file mode 100644 index 0000000..dbbcb30 --- /dev/null +++ b/yaksh/migrations/0009_auto_20180113_1124.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2018-01-13 11:24 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import yaksh.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('yaksh', '0008_release_0_7_0'), + ] + + operations = [ + migrations.CreateModel( + name='CourseStatus', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('grade', models.CharField(blank=True, max_length=255, null=True)), + ('total_marks', models.FloatField(default=0.0)), + ], + ), + migrations.CreateModel( + name='LearningModule', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField(blank=True, default=None, null=True)), + ('order', models.IntegerField(default=0)), + ('check_prerequisite', models.BooleanField(default=True)), + ('html_data', models.TextField(blank=True, null=True)), + ('is_trial', models.BooleanField(default=False)), + ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='module_creator', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='LearningUnit', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.IntegerField()), + ('type', models.CharField(max_length=16)), + ('check_prerequisite', models.BooleanField(default=True)), + ], + ), + migrations.CreateModel( + name='Lesson', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField()), + ('html_data', models.TextField(blank=True, null=True)), + ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='LessonFile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file', models.FileField(upload_to=yaksh.models.get_file_dir)), + ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lesson', to='yaksh.Lesson')), + ], + ), + migrations.RemoveField( + model_name='quiz', + name='course', + ), + migrations.RemoveField( + model_name='quiz', + name='language', + ), + migrations.RemoveField( + model_name='quiz', + name='prerequisite', + ), + migrations.AddField( + model_name='answerpaper', + name='course', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='yaksh.Course'), + ), + migrations.AddField( + model_name='question', + name='min_time', + field=models.IntegerField(default=0, verbose_name='time in minutes'), + ), + migrations.AddField( + model_name='question', + name='solution', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='quiz', + name='creator', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='quiz', + name='is_exercise', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='quiz', + name='weightage', + field=models.FloatField(default=1.0), + ), + migrations.AddField( + model_name='learningunit', + name='lesson', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='yaksh.Lesson'), + ), + migrations.AddField( + model_name='learningunit', + name='quiz', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='yaksh.Quiz'), + ), + migrations.AddField( + model_name='learningmodule', + name='learning_unit', + field=models.ManyToManyField(related_name='learning_unit', to='yaksh.LearningUnit'), + ), + migrations.AddField( + model_name='coursestatus', + name='completed_units', + field=models.ManyToManyField(related_name='completed_units', to='yaksh.LearningUnit'), + ), + migrations.AddField( + model_name='coursestatus', + name='course', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Course'), + ), + migrations.AddField( + model_name='coursestatus', + name='current_unit', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='current_unit', to='yaksh.LearningUnit'), + ), + migrations.AddField( + model_name='coursestatus', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='course', + name='learning_module', + field=models.ManyToManyField(related_name='learning_module', to='yaksh.LearningModule'), + ), + ] diff --git a/yaksh/migrations/0010_auto_20180226_1324.py b/yaksh/migrations/0010_auto_20180226_1324.py new file mode 100644 index 0000000..b400da7 --- /dev/null +++ b/yaksh/migrations/0010_auto_20180226_1324.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2018-02-26 13:24 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('yaksh', '0009_auto_20180113_1124'), + ] + + operations = [ + migrations.AddField( + model_name='learningmodule', + name='active', + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name='lesson', + name='active', + field=models.BooleanField(default=True), + ), + migrations.AlterField( + model_name='quiz', + name='time_between_attempts', + field=models.FloatField(verbose_name='Time Between Quiz Attempts in hours'), + ), + migrations.AlterUniqueTogether( + name='answerpaper', + unique_together=set([('user', 'question_paper', 'attempt_number', 'course')]), + ), + ] diff --git a/yaksh/migrations/0011_release_0_8_0.py b/yaksh/migrations/0011_release_0_8_0.py new file mode 100644 index 0000000..41a2abd --- /dev/null +++ b/yaksh/migrations/0011_release_0_8_0.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2018-03-23 10:46 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('grades', 'default_grading_system'), + ('yaksh', '0010_auto_20180226_1324'), + ] + + operations = [ + migrations.CreateModel( + name='ArrangeTestCase', + fields=[ + ('testcase_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='yaksh.TestCase')), + ('options', models.TextField(default=None)), + ], + bases=('yaksh.testcase',), + ), + migrations.CreateModel( + name='TestCaseOrder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.TextField()), + ('answer_paper', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answer_paper', to='yaksh.AnswerPaper')), + ], + ), + migrations.RenameField( + model_name='coursestatus', + old_name='total_marks', + new_name='percentage', + ), + migrations.AddField( + model_name='course', + name='grading_system', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='grades.GradingSystem'), + ), + migrations.AddField( + model_name='questionpaper', + name='shuffle_testcases', + field=models.BooleanField(default=True, verbose_name='Shuffle testcase for each user'), + ), + migrations.AlterField( + model_name='question', + name='type', + field=models.CharField(choices=[('mcq', 'Single Correct Choice'), ('mcc', 'Multiple Correct Choices'), ('code', 'Code'), ('upload', 'Assignment Upload'), ('integer', 'Answer in Integer'), ('string', 'Answer in String'), ('float', 'Answer in Float'), ('arrange', 'Arrange in Correct Order')], max_length=24), + ), + migrations.AlterField( + model_name='quiz', + name='weightage', + field=models.FloatField(default=100, help_text='Will be considered as percentage'), + ), + migrations.AlterField( + model_name='testcase', + name='type', + field=models.CharField(choices=[('standardtestcase', 'Standard Testcase'), ('stdiobasedtestcase', 'StdIO Based Testcase'), ('mcqtestcase', 'MCQ Testcase'), ('hooktestcase', 'Hook Testcase'), ('integertestcase', 'Integer Testcase'), ('stringtestcase', 'String Testcase'), ('floattestcase', 'Float Testcase'), ('arrangetestcase', 'Arrange Testcase')], max_length=24, null=True), + ), + migrations.AddField( + model_name='testcaseorder', + name='question', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Question'), + ), + ] |