2015-06-26 07:59:53 +00:00
|
|
|
from django.contrib.auth.models import AbstractBaseUser
|
2017-09-19 11:10:50 +00:00
|
|
|
from django.conf import settings
|
2016-09-25 06:07:45 +00:00
|
|
|
from django.db import models
|
2017-10-11 13:43:29 +00:00
|
|
|
from utils.models import JSONField
|
2015-09-24 06:55:20 +00:00
|
|
|
|
2016-06-23 04:19:16 +00:00
|
|
|
|
|
|
|
class AdminType(object):
|
2017-01-26 05:45:39 +00:00
|
|
|
REGULAR_USER = "Regular User"
|
|
|
|
ADMIN = "Admin"
|
|
|
|
SUPER_ADMIN = "Super Admin"
|
2016-06-23 04:19:16 +00:00
|
|
|
|
2017-05-09 06:47:54 +00:00
|
|
|
|
2017-02-10 02:38:32 +00:00
|
|
|
class ProblemPermission(object):
|
|
|
|
NONE = "None"
|
|
|
|
OWN = "Own"
|
|
|
|
ALL = "All"
|
|
|
|
|
|
|
|
|
2015-06-29 04:43:17 +00:00
|
|
|
class UserManager(models.Manager):
|
|
|
|
use_in_migrations = True
|
|
|
|
|
|
|
|
def get_by_natural_key(self, username):
|
2017-11-02 07:29:08 +00:00
|
|
|
return self.get(**{f"{self.model.USERNAME_FIELD}__iexact": username})
|
2015-06-29 04:43:17 +00:00
|
|
|
|
|
|
|
|
2015-06-26 07:59:53 +00:00
|
|
|
class User(AbstractBaseUser):
|
2018-05-01 04:54:27 +00:00
|
|
|
username = models.TextField(unique=True)
|
|
|
|
email = models.TextField(null=True)
|
2015-10-12 10:22:24 +00:00
|
|
|
create_time = models.DateTimeField(auto_now_add=True, null=True)
|
2016-06-23 04:19:16 +00:00
|
|
|
# One of UserType
|
2018-05-01 04:54:27 +00:00
|
|
|
admin_type = models.TextField(default=AdminType.REGULAR_USER)
|
|
|
|
problem_permission = models.TextField(default=ProblemPermission.NONE)
|
|
|
|
reset_password_token = models.TextField(null=True)
|
2016-10-29 18:17:35 +00:00
|
|
|
reset_password_token_expire_time = models.DateTimeField(null=True)
|
2016-06-23 04:19:16 +00:00
|
|
|
# SSO auth token
|
2018-05-01 04:54:27 +00:00
|
|
|
auth_token = models.TextField(null=True)
|
2015-12-11 14:43:23 +00:00
|
|
|
two_factor_auth = models.BooleanField(default=False)
|
2018-05-01 04:54:27 +00:00
|
|
|
tfa_token = models.TextField(null=True)
|
2017-10-11 13:43:29 +00:00
|
|
|
session_keys = JSONField(default=list)
|
2016-02-17 01:45:35 +00:00
|
|
|
# open api key
|
2016-06-23 04:19:16 +00:00
|
|
|
open_api = models.BooleanField(default=False)
|
2018-05-01 04:54:27 +00:00
|
|
|
open_api_appkey = models.TextField(null=True)
|
2016-06-23 04:19:16 +00:00
|
|
|
is_disabled = models.BooleanField(default=False)
|
2015-06-26 07:59:53 +00:00
|
|
|
|
2017-01-23 08:01:56 +00:00
|
|
|
USERNAME_FIELD = "username"
|
2015-06-29 04:43:17 +00:00
|
|
|
REQUIRED_FIELDS = []
|
|
|
|
|
|
|
|
objects = UserManager()
|
|
|
|
|
2017-02-10 06:37:52 +00:00
|
|
|
def is_admin(self):
|
|
|
|
return self.admin_type == AdminType.ADMIN
|
|
|
|
|
2017-02-10 03:41:01 +00:00
|
|
|
def is_super_admin(self):
|
|
|
|
return self.admin_type == AdminType.SUPER_ADMIN
|
2016-09-25 06:07:45 +00:00
|
|
|
|
2017-01-26 05:45:39 +00:00
|
|
|
def is_admin_role(self):
|
2017-02-10 03:41:01 +00:00
|
|
|
return self.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN]
|
2017-01-26 05:45:39 +00:00
|
|
|
|
2017-02-10 03:41:01 +00:00
|
|
|
def can_mgmt_all_problem(self):
|
|
|
|
return self.problem_permission == ProblemPermission.ALL
|
2017-01-26 05:45:39 +00:00
|
|
|
|
2017-11-10 11:40:54 +00:00
|
|
|
def is_contest_admin(self, contest):
|
2019-03-11 03:25:10 +00:00
|
|
|
return self.is_authenticated and (contest.created_by == self or self.admin_type == AdminType.SUPER_ADMIN)
|
2017-11-10 11:40:54 +00:00
|
|
|
|
2015-06-26 07:59:53 +00:00
|
|
|
class Meta:
|
|
|
|
db_table = "user"
|
2015-10-25 07:30:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
class UserProfile(models.Model):
|
2017-11-18 00:07:03 +00:00
|
|
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
2017-10-11 13:43:29 +00:00
|
|
|
# acm_problems_status examples:
|
|
|
|
# {
|
|
|
|
# "problems": {
|
|
|
|
# "1": {
|
|
|
|
# "status": JudgeStatus.ACCEPTED,
|
|
|
|
# "_id": "1000"
|
|
|
|
# }
|
|
|
|
# },
|
|
|
|
# "contest_problems": {
|
2017-10-15 10:36:55 +00:00
|
|
|
# "1": {
|
|
|
|
# "status": JudgeStatus.ACCEPTED,
|
|
|
|
# "_id": "1000"
|
|
|
|
# }
|
2017-10-11 13:43:29 +00:00
|
|
|
# }
|
|
|
|
# }
|
|
|
|
acm_problems_status = JSONField(default=dict)
|
|
|
|
# like acm_problems_status, merely add "score" field
|
|
|
|
oi_problems_status = JSONField(default=dict)
|
2017-09-12 03:45:17 +00:00
|
|
|
|
2018-05-01 04:54:27 +00:00
|
|
|
real_name = models.TextField(null=True)
|
|
|
|
avatar = models.TextField(default=f"{settings.AVATAR_URI_PREFIX}/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)
|
2018-07-15 04:43:44 +00:00
|
|
|
language = models.TextField(null=True)
|
2017-08-20 12:32:07 +00:00
|
|
|
# for ACM
|
|
|
|
accepted_number = models.IntegerField(default=0)
|
|
|
|
# for OI
|
|
|
|
total_score = models.BigIntegerField(default=0)
|
|
|
|
submission_number = models.IntegerField(default=0)
|
2015-11-10 10:46:51 +00:00
|
|
|
|
2016-04-24 07:02:51 +00:00
|
|
|
def add_accepted_problem_number(self):
|
2017-08-20 12:32:07 +00:00
|
|
|
self.accepted_number = models.F("accepted_number") + 1
|
2016-06-23 04:19:16 +00:00
|
|
|
self.save()
|
2016-04-24 07:02:51 +00:00
|
|
|
|
|
|
|
def add_submission_number(self):
|
2016-06-23 04:19:16 +00:00
|
|
|
self.submission_number = models.F("submission_number") + 1
|
|
|
|
self.save()
|
2016-04-24 07:02:51 +00:00
|
|
|
|
2017-08-20 12:32:07 +00:00
|
|
|
# 计算总分时, 应先减掉上次该题所得分数, 然后再加上本次所得分数
|
|
|
|
def add_score(self, this_time_score, last_time_score=None):
|
|
|
|
last_time_score = last_time_score or 0
|
|
|
|
self.total_score = models.F("total_score") - last_time_score + this_time_score
|
|
|
|
self.save()
|
|
|
|
|
2015-10-25 07:30:11 +00:00
|
|
|
class Meta:
|
|
|
|
db_table = "user_profile"
|