class Submission(Model): VERDICT_CHOICES = [(v.value, v.name) for v in VerdictResult] user = models.ForeignKey(get_user_model(), models.CASCADE) problem = models.ForeignKey(Problem, models.CASCADE) submit_time = models.DateTimeField(auto_now_add=True) code = models.TextField() lang = models.SmallIntegerField(choices=[(t.value, t.name) for t in LanguageEnum]) time = models.IntegerField(help_text='In ms', default=0) memory = models.IntegerField(help_text='In KB', default=0) verdict = models.SmallIntegerField(choices=VERDICT_CHOICES, default=VerdictResult.PENDING) desc = models.TextField(blank=True) outputs = JSONField(default=list, blank=True) job_id = models.CharField(max_length=50, help_text='The job id in RQ', null=True, blank=True) contest = models.ForeignKey(Contest, models.SET_NULL, null=True, blank=True) def __str__(self): return f'{self.user.username}: {self.problem.title}'
def __init__(self, expression, *paths, **kwargs): from django_mysql.models.fields import JSONField exprs = [expression] for path in paths: if not hasattr(path, 'resolve_expression'): path = Value(path) exprs.append(path) # kwarg validation - for Python 2 compat if list(kwargs.keys()) not in ([], ['output_field']): raise TypeError( 'Only supported keyword argument is "output_field"', ) if 'output_field' in kwargs: if len(paths) > 1: raise TypeError( "output_field won't work with more than one path, as a " "JSON Array will be returned", ) output_field = kwargs['output_field'] else: output_field = JSONField() super(JSONExtract, self).__init__(*exprs, output_field=output_field)
def __init__(self, expression, path=None): from django_mysql.models.fields import JSONField exprs = [expression] if path is not None: if not hasattr(path, 'resolve_expression'): path = Value(path) exprs.append(path) super(JSONKeys, self).__init__(*exprs, output_field=JSONField())
def __init__(self, expression, *paths): from django_mysql.models.fields import JSONField exprs = [expression] for path in paths: if not hasattr(path, 'resolve_expression'): path = Value(path) exprs.append(path) super(JSONExtract, self).__init__(*exprs, output_field=JSONField())
class PromotionCode(DateTimeModel): value = models.CharField(_('프로모션 코드'), max_length=32, unique=True) extra = JSONField(default=dict, blank=True) is_active = models.BooleanField(_('활성화 상태'), default=True) allow_quantity = models.PositiveSmallIntegerField(_('허용 사용 개수'), default=1) expired_at = models.DateTimeField(_('만료일시'), null=True, blank=True) def __str__(self): return self.value def add_to_user(self, user): from accounts.models import UserPromotionCode count = UserPromotionCode.objects.filter(user=user).count() if count >= settings.MAX_USER_PROMOTION_CODE_NUMBER: raise drf_exc.ValidationError({ 'detail': _('더이상 사용할 수 없습니다.'), 'code': 'exceeded', }) if self.users.filter(user__pk=user.pk).exists(): raise drf_exc.ValidationError({ 'detail': _('이미 사용 중입니다.'), 'code': 'duplicated' }) if not self.is_available: raise drf_exc.ValidationError({ 'detail': _('없거나 유효하지 않습니다.'), 'code': 'unavailable' }) return UserPromotionCode.objects.create( user=user, code=self, ) @property def is_available(self): result = self.allow_quantity == 0 result |= 0 < self.allow_quantity and self.users.count( ) < self.allow_quantity result &= not (self.expired_at and self.expired_at <= timezone.now()) return self.is_active and result @classmethod def check_available_value(cls, value): try: obj = cls.objects.get(value=value) except cls.DoesNotExist: return False return obj.is_available @property def reward_coin(self) -> Decimal: return Decimal(self.extra.get('lineup_coin', '0.0'))
class Auction(models.Model): id = models.BigAutoField(primary_key=True) isActive = models.BooleanField(default=True) auc = models.IntegerField() item = models.IntegerField() owner = models.CharField(max_length=60) ownerRealm = models.CharField(max_length=60) bid = models.CharField(max_length=255) # Buyout can be NULL (only BID) buyout = models.CharField(max_length=255, null=True) quantity = models.IntegerField() timeLeft = models.CharField(max_length=20) rand = models.IntegerField() seed = models.CharField(max_length=60) context = models.IntegerField() # Additional data bonusLists = JSONField(null=True) modifiers = JSONField(null=True) petSpeciesId = models.IntegerField(null=True) petBreadId = models.IntegerField(null=True) petLevel = models.IntegerField(null=True) petQualityId = models.IntegerField(null=True) def save(self, force_insert=False, force_update=False, using=None, update_fields=None): realm = Realm.objects.filter(name=self.ownerRealm).first() if realm: super(Auction, self).save() else: return class Meta: db_table = 'auction' indexes = [ models.Index(fields=['ownerRealm', 'auc']), models.Index(fields=['ownerRealm', 'owner']), models.Index(fields=['ownerRealm']) ]
class Problem(Model): CHECKER_TYPE_CHOICES = [(t.value, t.name) for t in CheckerType] title = models.CharField(max_length=50) description = models.TextField(blank=True) input_desc = models.TextField(blank=True) output_desc = models.TextField(blank=True) time_limit = models.IntegerField(default=2000, help_text='In ms') memory_limit = models.IntegerField(default=262144, help_text='In KB') note = models.TextField(blank=True) sample_inputs = JSONField(default=list) sample_outputs = JSONField(default=list) checker_type = models.SmallIntegerField(choices=CHECKER_TYPE_CHOICES) checker_code = models.TextField(blank=True) visible = models.BooleanField(default=False, db_index=True) def __str__(self): return self.title @property def sj_name(self): return f'sj_{self.id}'
def __init__(self, expression, *paths, output_field=None): from django_mysql.models.fields import JSONField exprs = [expression] for path in paths: if not hasattr(path, 'resolve_expression'): path = Value(path) exprs.append(path) if output_field is not None: if len(paths) > 1: raise TypeError( "output_field won't work with more than one path, as a " "JSON Array will be returned", ) else: output_field = JSONField() super(JSONExtract, self).__init__(*exprs, output_field=output_field)
def __init__(self, expression, data): from django_mysql.models.fields import JSONField if not data: raise ValueError('"data" cannot be empty') exprs = [expression] for path, value in data.items(): if not hasattr(path, "resolve_expression"): path = Value(path) exprs.append(path) if not hasattr(value, "resolve_expression"): value = JSONValue(value) exprs.append(value) super().__init__(*exprs, output_field=JSONField())
class User(AbstractUser, DateTimeModel): open_statuses = ( ( 'private', _('비공개'), ), ( 'public', _('공개'), ), ) levels = ( ( 'associate', _('준회원'), ), ( 'corporate', _('기업회원'), ), ( 'regular', _('정회원'), ), ( 'author', _('작가회원'), ), ) signup_routes = ( ( 'lineup', _('라인업 직접가입'), ), ( 'steem', _('스팀 계정'), ), ) id = models.BigAutoField(primary_key=True) uid = models.UUIDField(default=uuid4, unique=True, editable=False) nickname = models.CharField(max_length=50, null=True, blank=False) image = models.ImageField(null=True, blank=True, upload_to=_image_upload_to) level = models.CharField(_('등급'), max_length=40, choices=levels) is_verified = models.BooleanField(_('인증여부'), default=False) open_status = models.CharField(_('상태'), max_length=40, choices=open_statuses) signup_route = models.CharField(_('가입경로'), max_length=40, choices=signup_routes, default='lineup') notification_settings = JSONField(default=default_notification_settings) recommended_code = models.CharField( _('추천인 코드'), max_length=8, unique=True, editable=False, default=_default_recommended_code, ) invited_by = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_('추천인'), on_delete=models.SET_NULL, null=True, blank=True, ) perm_group_names = namedtuple('PERM_GROUP_NAMES', ( 'associate', 'corporate', 'regular', 'author', ))( associate='associate-user-permission-group', corporate='corporate-user-permission-group', regular='regular-user-permission-group', author='author-user-permission-group', ) class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL' @property def image_url(self): try: return self.image.url except Exception: pass try: social = self.social_auth.filter(provider='steemconnect').first() return social.extra_data['account']['json_metadata']['profile'][ 'profile_image'] except (AttributeError, KeyError): return def update_model_permissions(self): try: group_name = getattr(self.perm_group_names, self.level) except AttributeError: # todo: error logging return self group, _ = Group.objects.get_or_create(name=group_name) self.groups.clear() self.groups.add(group) return self @property def is_available_behaviour(self): return self.is_active and not self.is_staff @classmethod def make_temp_username(cls, email): while True: username = f"{email.split('@')[0]}_{uuid4().hex[:3]}" if not cls.objects.filter(username=username).exists(): return username def create_lineup_wallet(self): from currencies import models as cr_models if self.is_staff or not self.is_active: return symbol = cr_models.Symbol.objects \ .get(code=settings.SERVICE_TOKEN_SYMBOL) obj, __ = cr_models.Wallet.objects.get_or_create( user=self, symbol=symbol, defaults={ 'deposit_address': uuid4().hex, 'withdraw_address': uuid4().hex, }, ) return self def create_bezant_wallet(self, password: str): from currencies import models as cr_models from currencies.tasks import create_bezant_wallet address = create_bezant_wallet(password) symbol = cr_models.Symbol.objects.get(code='bznt') cr_models.Wallet.objects.get_or_create( user=self, symbol=symbol, defaults={ 'default_address': address, }, ) return self @property def notification_tokens(self): return tuple([ o[0] for o in self.notificationtoken_set.values_list('token').all() ]) @property def display_name(self): return self.nickname or self.username def link_inviter(self, inviter): self.invited_by = inviter self.save()
class Notification(Model): uid = models.UUIDField(unique=True, default=uuid4, editable=False) kinds = ( ('following_new_post', _('팔로잉하는 작가의 새 게시물')), ('new_vote_user_voted', _('내가 보팅한 글에 타인의 새 보팅')), ('new_comment_user_commented', _('내가 댓글단 글에 타인의 새 댓글')), ('new_comment_user_posted', _('내가 쓴 글에 타인의 새 댓글')), ('liked_my_post', _('내 포스트에 좋아요를 받았을 때')), ('my_new_follower', _('누군가 나를 팔로잉 했을 때')), ) user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='notifications', on_delete=models.CASCADE) trigger = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='triggered_notifications', on_delete=models.CASCADE) kind = models.CharField(_('종류'), max_length=40, choices=kinds) extra = JSONField(default=dict) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ('-created_at', ) @classmethod def notify_following_new_post(cls, post): from . import tasks user_lookups = Q(user__is_active=True) user_lookups &= Q(target__is_active=True) followers = post.user.follower_set.select_related('user').filter( user_lookups) cls.objects.bulk_create([ cls( user=f.user, trigger=post.user, kind='following_new_post', content_object=post, ) for f in followers ]) user = post.user objs = [None for __ in range(followers.count())] tokens = [] for i, f in enumerate(followers): objs[i] = cls( user=f.user, trigger=post.user, kind='following_new_post', content_object=post, ) if f.user.notification_settings.get('following_new_post', False): tokens.extend(f.user.notification_tokens) cls.objects.bulk_create(objs) tasks.push_notification.delay( tuple(frozenset(tokens)), _(f'{user.display_name}님이 새 포스팅을 게시했습니다.'), ) @classmethod def notify_new_comment_user_commented(cls, comment): from accounts.models import User target_pks = comment.post.comment_set.values_list('user__pk') user_lookups = Q(is_active=True) user_lookups &= Q(pk__in=target_pks) qs = User.objects.filter(user_lookups).exclude(pk=comment.user.pk) cls.objects.bulk_create([ cls( user=u, trigger=comment.user, kind='new_comment_user_commented', content_object=comment, ) for u in qs ]) cls.notify_new_comment_user_posted(comment) @classmethod def notify_new_comment_user_posted(cls, comment): from . import tasks if comment.user == comment.post.user: return user = comment.post.user cls.objects.create( user=user, trigger=comment.user, kind='new_comment_user_posted', content_object=comment, ) if user.notification_settings.get('new_comment_user_posted', False): tasks.push_notification.delay( user.notification_tokens, _(f'{comment.user.display_name}님이 댓글을 남겼습니다.'), ) @classmethod def notify_likes_user_liked(cls, like): from accounts.models import User target_pks = like.post.like_set.values_list('user__pk') user_lookups = Q(is_active=True) user_lookups &= Q(pk__in=target_pks) qs = User.objects.filter(user_lookups).exclude(pk=like.user.pk) cls.objects.bulk_create([ cls( user=u, trigger=like.user, kind='new_vote_user_voted', content_object=like, ) for u in qs ]) @classmethod def notify_liked_my_post(cls, like): from . import tasks user = like.post.user obj = cls( user=user, trigger=like.user, kind='liked_my_post', content_object=like, ) obj.save() if user.notification_settings.get('liked_my_post', False): tasks.push_notification.delay( user.notification_tokens, _(f'{like.user.display_name}님이 회원님의 포스팅을 좋아합니다.'), ) @classmethod def notify_my_new_follower(cls, follower): from . import tasks user = follower.target obj = cls( user=user, trigger=follower.user, kind='my_new_follower', content_object=follower, ) obj.save() if user.notification_settings.get('my_new_follower', False): tasks.push_notification.delay( user.notification_tokens, _(f'{follower.user.display_name}님이 회원님을 팔로우 했습니다.'), )
class ConnectedRealm(models.Model): realms = JSONField() status = models.BooleanField(blank=True, default=True) class Meta: db_table = 'connected_realm'
class TestCase(Model): problem = models.OneToOneField(Problem, models.CASCADE) inputs = JSONField(default=list) expected_outputs = JSONField(default=list)