From 0efc9c8c173ae7135caa405ce418e2356d3673a4 Mon Sep 17 00:00:00 2001 From: jin Date: Tue, 31 Aug 2021 16:19:06 +0900 Subject: [PATCH] Bugfix: Prof admin account do not request contest list --- .gitignore | 1 + account/migrations/0001_initial.py | 72 +++++++++++++ account/models.py | 1 + announcement/migrations/0001_initial.py | 34 ++++++ conf/migrations/0001_initial.py | 34 ++++++ contest/migrations/0001_initial.py | 91 ++++++++++++++++ contest/migrations/0002_contest_private.py | 18 ++++ contest/views/oj.py | 2 +- data/test_case/.gitkeep | 0 lecture/migrations/0001_initial.py | 64 +++++++++++ .../migrations/0002_signup_class_contest.py | 20 ++++ lecture/migrations/0003_auto_20200922_0130.py | 19 ++++ oj/settings.py | 5 + options/migrations/0001_initial.py | 23 ++++ problem/migrations/0001_initial.py | 100 ++++++++++++++++++ problem/views/oj.py | 11 +- qna/migrations/0001_initial.py | 1 + qna/migrations/0002_auto_20200922_0036.py | 25 +++++ req.txt | 1 + submission/migrations/0001_initial.py | 45 ++++++++ utils/DBTasks/migrateLecture.py | 54 ++++++++++ 21 files changed, 615 insertions(+), 6 deletions(-) create mode 100644 account/migrations/0001_initial.py create mode 100644 announcement/migrations/0001_initial.py create mode 100644 conf/migrations/0001_initial.py create mode 100644 contest/migrations/0001_initial.py create mode 100644 contest/migrations/0002_contest_private.py create mode 100644 data/test_case/.gitkeep create mode 100644 lecture/migrations/0001_initial.py create mode 100644 lecture/migrations/0002_signup_class_contest.py create mode 100644 lecture/migrations/0003_auto_20200922_0130.py create mode 100644 options/migrations/0001_initial.py create mode 100644 problem/migrations/0001_initial.py create mode 100644 qna/migrations/0001_initial.py create mode 100644 qna/migrations/0002_auto_20200922_0036.py create mode 100644 submission/migrations/0001_initial.py create mode 100644 utils/DBTasks/migrateLecture.py diff --git a/.gitignore b/.gitignore index 07e3b0f..2986685 100755 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ htmlcov/ .cache nosetests.xml coverage.xml +migrations/* # Translations *.mo # Mr Developer diff --git a/account/migrations/0001_initial.py b/account/migrations/0001_initial.py new file mode 100644 index 0000000..3409c14 --- /dev/null +++ b/account/migrations/0001_initial.py @@ -0,0 +1,72 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +import account.models +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('username', models.TextField(unique=True)), + ('realname', models.TextField(null=True)), + ('email', models.TextField(null=True)), + ('create_time', models.DateTimeField(auto_now_add=True, null=True)), + ('schoolssn', models.IntegerField(default=0)), + ('admin_type', models.TextField(default='Regular User')), + ('problem_permission', models.TextField(default='None')), + ('reset_password_token', models.TextField(null=True)), + ('reset_password_token_expire_time', models.DateTimeField(null=True)), + ('auth_token', models.TextField(null=True)), + ('two_factor_auth', models.BooleanField(default=False)), + ('tfa_token', models.TextField(null=True)), + ('session_keys', django.contrib.postgres.fields.jsonb.JSONField(default=list)), + ('open_api', models.BooleanField(default=False)), + ('open_api_appkey', models.TextField(null=True)), + ('is_disabled', models.BooleanField(default=False)), + ('is_allowed', models.BooleanField(default=False)), + ], + options={ + 'db_table': 'user', + }, + managers=[ + ('objects', account.models.UserManager()), + ], + ), + migrations.CreateModel( + name='UserProfile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('acm_problems_status', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('oi_problems_status', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('real_name', models.TextField(null=True)), + ('avatar', models.TextField(default='/public/avatar/default.png')), + ('blog', models.URLField(null=True)), + ('mood', models.TextField(null=True)), + ('github', models.TextField(null=True)), + ('school', models.TextField(null=True)), + ('major', models.TextField(null=True)), + ('language', models.TextField(null=True)), + ('accepted_number', models.IntegerField(default=0)), + ('total_score', models.BigIntegerField(default=0)), + ('submission_number', models.IntegerField(default=0)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'user_profile', + }, + ), + ] diff --git a/account/models.py b/account/models.py index 59ce40e..9358796 100755 --- a/account/models.py +++ b/account/models.py @@ -66,6 +66,7 @@ def is_super_admin(self): return self.admin_type == AdminType.SUPER_ADMIN def is_admin_role(self): + print(self.admin_type) return self.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN, AdminType.TA_ADMIN] def can_mgmt_all_problem(self): diff --git a/announcement/migrations/0001_initial.py b/announcement/migrations/0001_initial.py new file mode 100644 index 0000000..d36f32f --- /dev/null +++ b/announcement/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Announcement', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('content', utils.models.RichTextField()), + ('create_time', models.DateTimeField(auto_now_add=True)), + ('last_update_time', models.DateTimeField(auto_now=True)), + ('visible', models.BooleanField(default=True)), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'announcement', + 'ordering': ('-create_time',), + }, + ), + ] diff --git a/conf/migrations/0001_initial.py b/conf/migrations/0001_initial.py new file mode 100644 index 0000000..34eb21d --- /dev/null +++ b/conf/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='JudgeServer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('hostname', models.TextField()), + ('ip', models.TextField(null=True)), + ('judger_version', models.TextField()), + ('cpu_core', models.IntegerField()), + ('memory_usage', models.FloatField()), + ('cpu_usage', models.FloatField()), + ('last_heartbeat', models.DateTimeField()), + ('create_time', models.DateTimeField(auto_now_add=True)), + ('task_number', models.IntegerField(default=0)), + ('service_url', models.TextField(null=True)), + ('is_disabled', models.BooleanField(default=False)), + ], + options={ + 'db_table': 'judge_server', + }, + ), + ] diff --git a/contest/migrations/0001_initial.py b/contest/migrations/0001_initial.py new file mode 100644 index 0000000..5fbc5c7 --- /dev/null +++ b/contest/migrations/0001_initial.py @@ -0,0 +1,91 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('lecture', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Contest', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('description', utils.models.RichTextField()), + ('real_time_rank', models.BooleanField()), + ('password', models.TextField(null=True)), + ('lecture_contest_type', models.TextField(default='실습')), + ('rule_type', models.TextField()), + ('start_time', models.DateTimeField()), + ('end_time', models.DateTimeField()), + ('create_time', models.DateTimeField(auto_now_add=True)), + ('last_update_time', models.DateTimeField(auto_now=True)), + ('visible', models.BooleanField(default=True)), + ('allowed_ip_ranges', django.contrib.postgres.fields.jsonb.JSONField(default=list)), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('lecture', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture')), + ], + options={ + 'db_table': 'contest', + 'ordering': ('-start_time',), + }, + ), + migrations.CreateModel( + name='ContestAnnouncement', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('content', utils.models.RichTextField()), + ('visible', models.BooleanField(default=True)), + ('create_time', models.DateTimeField(auto_now_add=True)), + ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'contest_announcement', + 'ordering': ('-create_time',), + }, + ), + migrations.CreateModel( + name='OIContestRank', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('submission_number', models.IntegerField(default=0)), + ('total_score', models.IntegerField(default=0)), + ('submission_info', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'oi_contest_rank', + 'unique_together': {('user', 'contest')}, + }, + ), + migrations.CreateModel( + name='ACMContestRank', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('submission_number', models.IntegerField(default=0)), + ('accepted_number', models.IntegerField(default=0)), + ('total_time', models.IntegerField(default=0)), + ('submission_info', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'acm_contest_rank', + 'unique_together': {('user', 'contest')}, + }, + ), + ] diff --git a/contest/migrations/0002_contest_private.py b/contest/migrations/0002_contest_private.py new file mode 100644 index 0000000..bea89d4 --- /dev/null +++ b/contest/migrations/0002_contest_private.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.16 on 2020-09-22 15:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='contest', + name='private', + field=models.BooleanField(default=False), + ), + ] diff --git a/contest/views/oj.py b/contest/views/oj.py index fef1eae..3fa38f8 100755 --- a/contest/views/oj.py +++ b/contest/views/oj.py @@ -67,7 +67,7 @@ def get(self, request): #print("Lecture allow : ", lecsign[0].isallow) contest.visible = True else: - if request.user.is_super_admin() or request.user.is_semi_admin(): # 문제 접근을 위한 visible 값 수정 + if request.user.is_admin_role(): # 문제 접근을 위한 visible 값 수정 contest.visible = True else: contest.visible = False diff --git a/data/test_case/.gitkeep b/data/test_case/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/lecture/migrations/0001_initial.py b/lecture/migrations/0001_initial.py new file mode 100644 index 0000000..69e49bc --- /dev/null +++ b/lecture/migrations/0001_initial.py @@ -0,0 +1,64 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Lecture', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('description', utils.models.RichTextField()), + ('year', models.IntegerField()), + ('semester', models.IntegerField()), + ('status', models.BooleanField()), + ('password', models.TextField()), + ('isapply', models.BooleanField(default=False)), + ('isallow', models.BooleanField(default=False)), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'lecture', + }, + ), + migrations.CreateModel( + name='ta_admin_class', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('realname', models.TextField(default=None, null=True)), + ('schoolssn', models.IntegerField(default=None, null=True)), + ('lecture_isallow', models.BooleanField(default=False)), + ('code_isallow', models.BooleanField(default=False)), + ('score_isallow', models.BooleanField(default=False)), + ('lecture', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='signup_class', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.BooleanField(default=False)), + ('isallow', models.BooleanField(default=False)), + ('realname', models.TextField(default=None, null=True)), + ('schoolssn', models.IntegerField(default=None, null=True)), + ('score', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('etc', models.TextField(null=True)), + ('lecture', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture')), + ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/lecture/migrations/0002_signup_class_contest.py b/lecture/migrations/0002_signup_class_contest.py new file mode 100644 index 0000000..fa22c82 --- /dev/null +++ b/lecture/migrations/0002_signup_class_contest.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.16 on 2020-09-21 16:18 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0001_initial'), + ('lecture', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='signup_class', + name='contest', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Contest'), + ), + ] diff --git a/lecture/migrations/0003_auto_20200922_0130.py b/lecture/migrations/0003_auto_20200922_0130.py new file mode 100644 index 0000000..fe5e7a9 --- /dev/null +++ b/lecture/migrations/0003_auto_20200922_0130.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.16 on 2020-09-21 16:30 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('lecture', '0002_signup_class_contest'), + ] + + operations = [ + migrations.AlterField( + model_name='signup_class', + name='lecture', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture'), + ), + ] diff --git a/oj/settings.py b/oj/settings.py index f4bf2dd..34c13ae 100755 --- a/oj/settings.py +++ b/oj/settings.py @@ -35,6 +35,7 @@ 'rest_framework', 'django_dramatiq', 'django_dbconn_retry', + 'django_crontab', ] if production_env: @@ -56,6 +57,10 @@ 'qna', ] +CRONJOBS = [ + ('0 5 * * *', 'utils.DBTasks.migrateLecture', '>> /mnt/log/cron_log.log') +] + INSTALLED_APPS = VENDOR_APPS + LOCAL_APPS MIDDLEWARE = ( diff --git a/options/migrations/0001_initial.py b/options/migrations/0001_initial.py new file mode 100644 index 0000000..9821a9d --- /dev/null +++ b/options/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='SysOptions', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.TextField(db_index=True, unique=True)), + ('value', django.contrib.postgres.fields.jsonb.JSONField()), + ], + ), + ] diff --git a/problem/migrations/0001_initial.py b/problem/migrations/0001_initial.py new file mode 100644 index 0000000..e38f4f6 --- /dev/null +++ b/problem/migrations/0001_initial.py @@ -0,0 +1,100 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import problem.models +import utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('lecture', '0001_initial'), + ('contest', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ProblemTag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField()), + ], + options={ + 'db_table': 'problem_tag', + }, + ), + migrations.CreateModel( + name='Problem', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('_id', models.TextField(db_index=True)), + ('is_public', models.BooleanField(default=False)), + ('title', models.TextField()), + ('description', utils.models.RichTextField()), + ('input_description', utils.models.RichTextField()), + ('output_description', utils.models.RichTextField()), + ('samples', django.contrib.postgres.fields.jsonb.JSONField()), + ('test_case_id', models.TextField()), + ('test_case_score', django.contrib.postgres.fields.jsonb.JSONField()), + ('hint', utils.models.RichTextField(null=True)), + ('languages', django.contrib.postgres.fields.jsonb.JSONField()), + ('template', django.contrib.postgres.fields.jsonb.JSONField()), + ('create_time', models.DateTimeField(auto_now_add=True)), + ('last_update_time', models.DateTimeField(null=True)), + ('time_limit', models.IntegerField()), + ('memory_limit', models.IntegerField()), + ('io_mode', django.contrib.postgres.fields.jsonb.JSONField(default=problem.models._default_io_mode)), + ('spj', models.BooleanField(default=False)), + ('spj_language', models.TextField(null=True)), + ('spj_code', models.TextField(null=True)), + ('spj_version', models.TextField(null=True)), + ('spj_compile_ok', models.BooleanField(default=False)), + ('rule_type', models.TextField()), + ('visible', models.BooleanField(default=True)), + ('difficulty', models.TextField()), + ('source', models.TextField(null=True)), + ('total_score', models.IntegerField(default=0)), + ('submission_number', models.BigIntegerField(default=0)), + ('accepted_number', models.BigIntegerField(default=0)), + ('statistic_info', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('share_submission', models.BooleanField(default=False)), + ('contest', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('tags', models.ManyToManyField(to='problem.ProblemTag')), + ], + options={ + 'db_table': 'problem', + 'ordering': ('create_time',), + 'unique_together': {('_id', 'contest')}, + }, + ), + migrations.CreateModel( + name='Plag_Summary', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('summary', django.contrib.postgres.fields.jsonb.JSONField(default=list)), + ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('lecture', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='problem.Problem')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Plag_Result', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('result', django.contrib.postgres.fields.jsonb.JSONField(default=list)), + ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('lecture', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture')), + ('plag_summary', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='problem.Plag_Summary')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='problem.Problem')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/problem/views/oj.py b/problem/views/oj.py index a7d8f24..394e11e 100755 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -126,11 +126,12 @@ def get(self, request): contests = Contest.objects.get(id=request.GET.get("contest_id")) if contests.lecture: if request.user.is_admin(): - try: - signups = signup_class.objects.get(lecture=contests.lecture, user=request.user.id, isallow=True) - except signup_class.DoesNotExist: - print("Incorrect path") - return self.success(False) + return self.success(True) + # try: + # signups = signup_class.objects.get(lecture=contests.lecture, user=request.user.id, isallow=True) + # except signup_class.DoesNotExist: + # print("Incorrect path") + # return self.success(False) except Contest.DoesNotExist: return self.error("Parameter error, Contest is required") return self.success(True) diff --git a/qna/migrations/0001_initial.py b/qna/migrations/0001_initial.py new file mode 100644 index 0000000..5308b0e --- /dev/null +++ b/qna/migrations/0001_initial.py @@ -0,0 +1 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 from django.conf import settings from django.db import migrations, models import django.db.models.deletion import django.utils.timezone class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('contest', '0001_initial'), ('problem', '0001_initial'), ('submission', '0001_initial'), ] operations = [ migrations.CreateModel( name='Post', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=200)), ('content', models.TextField()), ('date_posted', models.DateTimeField(default=django.utils.timezone.now)), ('solved', models.BooleanField(default=False)), ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('contest', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), ('problem', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='problem.Problem')), ('submission', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='submission.Submission')), ], options={ 'db_table': 'qna_post', }, ), migrations.CreateModel( name='Comment', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date_posted', models.DateTimeField(default=django.utils.timezone.now)), ('content', models.TextField()), ('author', models.CharField(max_length=200)), ('post', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='qna.Post')), ], options={ 'db_table': 'qna_comment', }, ), ] \ No newline at end of file diff --git a/qna/migrations/0002_auto_20200922_0036.py b/qna/migrations/0002_auto_20200922_0036.py new file mode 100644 index 0000000..5f850d0 --- /dev/null +++ b/qna/migrations/0002_auto_20200922_0036.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:36 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('qna', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='post', + name='private', + field=models.BooleanField(default=True), + ), + migrations.AlterField( + model_name='comment', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/req.txt b/req.txt index faff933..4f59e6a 100755 --- a/req.txt +++ b/req.txt @@ -36,3 +36,4 @@ six==1.12.0 tzlocal==2.0.0 urllib3==1.24.1 XlsxWriter==1.1.5 +django-crontab diff --git a/submission/migrations/0001_initial.py b/submission/migrations/0001_initial.py new file mode 100644 index 0000000..dfd815f --- /dev/null +++ b/submission/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 2.2.16 on 2020-09-21 15:30 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import utils.shortcuts + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('problem', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('lecture', '0001_initial'), + ('contest', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Submission', + fields=[ + ('id', models.TextField(db_index=True, default=utils.shortcuts.rand_str, primary_key=True, serialize=False)), + ('create_time', models.DateTimeField(auto_now_add=True)), + ('username', models.TextField()), + ('code', models.TextField()), + ('result', models.IntegerField(db_index=True, default=6)), + ('info', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('language', models.TextField()), + ('shared', models.BooleanField(default=False)), + ('statistic_info', django.contrib.postgres.fields.jsonb.JSONField(default=dict)), + ('ip', models.TextField(null=True)), + ('contest', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')), + ('lecture', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='lecture.Lecture')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='problem.Problem')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'submission', + 'ordering': ('-create_time',), + }, + ), + ] diff --git a/utils/DBTasks/migrateLecture.py b/utils/DBTasks/migrateLecture.py new file mode 100644 index 0000000..a8a9f9c --- /dev/null +++ b/utils/DBTasks/migrateLecture.py @@ -0,0 +1,54 @@ +from django.db.models import Max + +from lecture.models import signup_class +from lecture.views.LectureAnalysis import lecDispatcher +from problem.models import Problem +from submission.models import Submission + +import datetime + +def migrate(): + year = datetime.today().year + semester = (8 > datetime.today().month >= 3) and 1 or (3 > datetime.today().month >= 1) and 3 or 2 + + try: + print("Try") + lectures = signup_class.objects.filter(isallow=True, lecture__year=year, lecture__semester=semester).select_related('lecture').order_by('lecture') + lid = -1 + total = lectures.count() + cnt = 0 + for lec in lectures: + try: + cnt += 1 + + if lid != lec.lecture_id: + lid = lec.lecture_id + + plist = Problem.objects.filter(contest__lecture=lec.lecture_id).prefetch_related('contest') + + # test + LectureInfo = lecDispatcher() + for p in plist: + LectureInfo.migrateProblem(p) + + # get Submission + sublist = Submission.objects.filter(lecture=lec.lecture_id) + + ldates = sublist.filter(user=lec.user).values('contest', 'problem').annotate( + latest_created_at=Max('create_time')) + sdata = sublist.filter(create_time__in=ldates.values('latest_created_at')).order_by('-create_time') + LectureInfo.cleanDataForScorebard() + + for submit in sdata: + LectureInfo.associateSubmission(submit) + + lec.score = LectureInfo.toDict() + lec.save() + + print("(", cnt, "/", total, ")", lec.lecture_id, lec.id, lec.user.realname, lec.user.username, + lec.lecture.title, 'Completedd') + except: + print("exception") + + except: + print("exception") \ No newline at end of file