From 078de956e59926c3a30fb157b35a3701945574cb Mon Sep 17 00:00:00 2001 From: virusdefender Date: Sun, 25 Sep 2016 17:00:52 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/migrations/0004_auto_20160925_1649.py | 65 +++++++++++ account/models.py | 19 ++-- conf/models.py | 5 +- contest/__init__.py | 0 contest/admin.py | 3 + contest/migrations/__init__.py | 0 contest/models.py | 106 ++++++++++++++++++ contest/tests.py | 3 + contest/views.py | 3 + group/__init__.py | 0 group/admin.py | 3 + group/apps.py | 7 ++ group/migrations/__init__.py | 0 group/models.py | 8 ++ group/tests.py | 3 + group/views.py | 3 + problem/__init__.py | 0 problem/admin.py | 3 + problem/migrations/__init__.py | 0 problem/models.py | 69 ++++++++++++ problem/tests.py | 3 + problem/views.py | 3 + 22 files changed, 297 insertions(+), 9 deletions(-) create mode 100644 account/migrations/0004_auto_20160925_1649.py create mode 100644 contest/__init__.py create mode 100644 contest/admin.py create mode 100644 contest/migrations/__init__.py create mode 100644 contest/models.py create mode 100644 contest/tests.py create mode 100644 contest/views.py create mode 100644 group/__init__.py create mode 100644 group/admin.py create mode 100644 group/apps.py create mode 100644 group/migrations/__init__.py create mode 100644 group/models.py create mode 100644 group/tests.py create mode 100644 group/views.py create mode 100644 problem/__init__.py create mode 100644 problem/admin.py create mode 100644 problem/migrations/__init__.py create mode 100644 problem/models.py create mode 100644 problem/tests.py create mode 100644 problem/views.py diff --git a/account/migrations/0004_auto_20160925_1649.py b/account/migrations/0004_auto_20160925_1649.py new file mode 100644 index 00000000..3b54ecfc --- /dev/null +++ b/account/migrations/0004_auto_20160925_1649.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2016-09-25 08:49 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0003_auto_20160925_1402'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='language', + field=models.CharField(blank=True, max_length=32, null=True), + ), + migrations.AddField( + model_name='userprofile', + name='major', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='userprofile', + name='time_zone', + field=models.CharField(blank=True, max_length=32, null=True), + ), + migrations.AlterField( + model_name='user', + name='auth_token', + field=models.CharField(max_length=40, null=True), + ), + migrations.AlterField( + model_name='user', + name='email', + field=models.EmailField(max_length=254, null=True), + ), + migrations.AlterField( + model_name='user', + name='open_api_appkey', + field=models.CharField(max_length=35, null=True), + ), + migrations.AlterField( + model_name='user', + name='real_name', + field=models.CharField(max_length=30, null=True), + ), + migrations.AlterField( + model_name='user', + name='reset_password_token', + field=models.CharField(max_length=40, null=True), + ), + migrations.AlterField( + model_name='user', + name='reset_password_token_create_time', + field=models.DateTimeField(null=True), + ), + migrations.AlterField( + model_name='user', + name='tfa_token', + field=models.CharField(max_length=40, null=True), + ), + ] diff --git a/account/models.py b/account/models.py index b4ce0ac1..7a86510b 100644 --- a/account/models.py +++ b/account/models.py @@ -1,4 +1,5 @@ # coding=utf-8 +from __future__ import unicode_literals from django.contrib.auth.models import AbstractBaseUser from django.db import models from jsonfield import JSONField @@ -33,8 +34,8 @@ class UserManager(models.Manager): class User(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) - real_name = models.CharField(max_length=30, blank=True, null=True) - email = models.EmailField(max_length=254, blank=True, null=True) + real_name = models.CharField(max_length=30, null=True) + email = models.EmailField(max_length=254, null=True) create_time = models.DateTimeField(auto_now_add=True, null=True) # One of UserType admin_type = models.IntegerField(default=0) @@ -43,15 +44,15 @@ class User(AbstractBaseUser): # Store user problem solution status with json string format # {"problems": {1: ProblemSolutionStatus.ACCEPTED}, "contest_problems": {20: ProblemSolutionStatus.PENDING)} problems_status = JSONField(default={}) - reset_password_token = models.CharField(max_length=40, blank=True, null=True) - reset_password_token_create_time = models.DateTimeField(blank=True, null=True) + reset_password_token = models.CharField(max_length=40, null=True) + reset_password_token_create_time = models.DateTimeField(null=True) # SSO auth token - auth_token = models.CharField(max_length=40, blank=True, null=True) + auth_token = models.CharField(max_length=40, null=True) two_factor_auth = models.BooleanField(default=False) - tfa_token = models.CharField(max_length=40, blank=True, null=True) + tfa_token = models.CharField(max_length=40, null=True) # open api key open_api = models.BooleanField(default=False) - open_api_appkey = models.CharField(max_length=35, blank=True, null=True) + open_api_appkey = models.CharField(max_length=35, null=True) is_disabled = models.BooleanField(default=False) USERNAME_FIELD = 'username' @@ -80,8 +81,10 @@ class UserProfile(models.Model): submission_number = models.IntegerField(default=0) phone_number = models.CharField(max_length=15, blank=True, null=True) school = models.CharField(max_length=200, blank=True, null=True) - + major = models.CharField(max_length=200, blank=True, null=True) student_id = models.CharField(max_length=15, blank=True, null=True) + time_zone = models.CharField(max_length=32, blank=True, null=True) + language = models.CharField(max_length=32, blank=True, null=True) def add_accepted_problem_number(self): self.accepted_problem_number = models.F("accepted_problem_number") + 1 diff --git a/conf/models.py b/conf/models.py index bd4b2abe..7eb9257b 100644 --- a/conf/models.py +++ b/conf/models.py @@ -1,5 +1,8 @@ +# coding=utf-8 from __future__ import unicode_literals from django.db import models -# Create your models here. + +class SMTPConfig(models.Model): + pass diff --git a/contest/__init__.py b/contest/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/contest/admin.py b/contest/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/contest/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/contest/migrations/__init__.py b/contest/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/contest/models.py b/contest/models.py new file mode 100644 index 00000000..c7d3b4ab --- /dev/null +++ b/contest/models.py @@ -0,0 +1,106 @@ +# coding=utf-8 +from __future__ import unicode_literals + +from django.db import models +from django.utils.timezone import now +from group.models import Group +from jsonfield import JSONField + +from account.models import User +from problem.models import AbstractProblem +from utils.models import RichTextField + + +class ContestType(object): + GROUP_CONTEST = 0 + PUBLIC_CONTEST = 1 + PASSWORD_PROTECTED_CONTEST = 2 + PASSWORD_PROTECTED_GROUP_CONTEST = 3 + + +class ContestStatus(object): + CONTEST_NOT_START = 1 + CONTEST_ENDED = -1 + CONTEST_UNDERWAY = 0 + + +class ContestRuleType(object): + ACM = 0 + OI = 1 + + +class Contest(models.Model): + title = models.CharField(max_length=40, unique=True) + description = RichTextField() + # show real time rank or cached rank + real_time_rank = models.BooleanField() + password = models.CharField(max_length=30, blank=True, null=True) + # enum of ContestType + contest_type = models.IntegerField() + # enum of ContestRuleType + rule_type = models.IntegerField() + start_time = models.DateTimeField() + end_time = models.DateTimeField() + create_time = models.DateTimeField(auto_now_add=True) + last_updated_time = models.DateTimeField(auto_now=True) + created_by = models.ForeignKey(User) + groups = models.ManyToManyField(Group) + # 是否可见 false的话相当于删除 + visible = models.BooleanField(default=True) + + @property + def status(self): + if self.start_time > now(): + # 没有开始 返回1 + return ContestStatus.CONTEST_NOT_START + elif self.end_time < now(): + # 已经结束 返回-1 + return ContestStatus.CONTEST_ENDED + else: + # 正在进行 返回0 + return ContestStatus.CONTEST_UNDERWAY + + class Meta: + db_table = "contest" + + +class ContestProblem(AbstractProblem): + contest = models.ForeignKey(Contest) + # 比如A B 或者1 2 或者 a b 将按照这个排序 + sort_index = models.CharField(max_length=30) + # 是否已经公开了题目,防止重复公开 + is_public = models.BooleanField(default=False) + + class Meta: + db_table = "contest_problem" + + +class ContestRank(models.Model): + user = models.ForeignKey(User) + contest = models.ForeignKey(Contest) + total_submission_number = models.IntegerField(default=0) + + class Meta: + abstract = True + + +class ACMContestRank(ContestRank): + total_ac_number = models.IntegerField(default=0) + # total_time is only for ACM contest total_time = ac time + none-ac times * 20 * 60 + total_time = models.IntegerField(default=0) + # {23: {"is_ac": True, "ac_time": 8999, "error_number": 2, "is_first_ac": True}} + # key is problem id + submission_info = JSONField(default={}) + + class Meta: + db_table = "acm_contest_rank" + + +class OIContestRank(ContestRank): + total_score = models.IntegerField(default=0) + # {23: {"score": 80, "total_score": 100}} + # key is problem id + submission_info = JSONField(default={}) + + class Meta: + db_table = "oi_contenst_rank" \ No newline at end of file diff --git a/contest/tests.py b/contest/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/contest/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/contest/views.py b/contest/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/contest/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/group/__init__.py b/group/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/group/admin.py b/group/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/group/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/group/apps.py b/group/apps.py new file mode 100644 index 00000000..d1471c0d --- /dev/null +++ b/group/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class GroupConfig(AppConfig): + name = 'group' diff --git a/group/migrations/__init__.py b/group/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/group/models.py b/group/models.py new file mode 100644 index 00000000..0e61de5d --- /dev/null +++ b/group/models.py @@ -0,0 +1,8 @@ +# coding=utf-8 +from __future__ import unicode_literals + +from django.db import models + + +class Group(models.Model): + pass diff --git a/group/tests.py b/group/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/group/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/group/views.py b/group/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/group/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/problem/__init__.py b/problem/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/problem/admin.py b/problem/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/problem/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/problem/migrations/__init__.py b/problem/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/problem/models.py b/problem/models.py new file mode 100644 index 00000000..6cdbd615 --- /dev/null +++ b/problem/models.py @@ -0,0 +1,69 @@ +# coding=utf-8 +from __future__ import unicode_literals + +from jsonfield import JSONField +from django.db import models + +from account.models import User +from utils.models import RichTextField + + +class ProblemTag(models.Model): + name = models.CharField(max_length=30) + + class Meta: + db_table = "problem_tag" + + +class AbstractProblem(models.Model): + title = models.CharField(max_length=50) + # HTML + description = RichTextField() + input_description = models.CharField(max_length=10000) + output_description = models.CharField(max_length=10000) + # [{input: "test", output: "123"}, {input: "test123", output: "456"}] + samples = models.TextField(blank=True) + test_case_id = models.CharField(max_length=40) + hint = RichTextField(blank=True, null=True) + create_time = models.DateTimeField(auto_now_add=True) + # we can not use auto_now here + last_update_time = models.DateTimeField(blank=True, null=True) + created_by = models.ForeignKey(User) + # ms + time_limit = models.IntegerField() + # MB + memory_limit = models.IntegerField() + # special judge related + spj = models.BooleanField(default=False) + spj_language = models.IntegerField(blank=True, null=True) + spj_code = models.TextField(blank=True, null=True) + spj_version = models.CharField(max_length=32, blank=True, null=True) + visible = models.BooleanField(default=True) + total_submit_number = models.IntegerField(default=0) + total_accepted_number = models.IntegerField(default=0) + + class Meta: + db_table = "problem" + abstract = True + + def add_submission_number(self): + self.accepted_problem_number = models.F("total_submit_number") + 1 + self.save() + + def add_ac_number(self): + self.accepted_problem_number = models.F("total_accepted_number") + 1 + self.save() + + +class Problem(AbstractProblem): + difficulty = models.IntegerField() + tags = models.ManyToManyField(ProblemTag) + source = models.CharField(max_length=200, blank=True, null=True) + + +class TestCaseScore(models.Model): + test_case_id = models.CharField(max_length=32) + score = JSONField() + + class Meta: + db_table = "test_case_score" diff --git a/problem/tests.py b/problem/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/problem/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/problem/views.py b/problem/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/problem/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.