import uuid from uuid import uuid4 from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import Group as BaseGroup from django.core.cache import cache from django.db.models import ( BooleanField, CharField, EmailField, ImageField, JSONField, QuerySet, UUIDField, ) from django.utils.translation import gettext_lazy as _ from rest_framework_simplejwt.token_blacklist.models import ( BlacklistedToken as BaseBlacklistedToken, ) from rest_framework_simplejwt.token_blacklist.models import ( OutstandingToken as BaseOutstandingToken, ) from core.abstract import NiceModel from core.models import Order, Wishlist from evibes.settings import LANGUAGE_CODE, LANGUAGES from payments.models import Balance from vibes_auth.managers import UserManager from vibes_auth.validators import validate_phone_number class User(AbstractUser, NiceModel): def get_uuid_as_path(self, *args): return str(self.uuid) + "/" + args[0] email: str = EmailField(_("email"), unique=True, help_text=_("user email address")) # type: ignore phone_number: str = CharField( # type: ignore _("phone_number"), max_length=20, unique=True, blank=True, null=True, help_text=_("user phone number"), validators=[ validate_phone_number, ], ) username = None first_name: str = CharField(_("first_name"), max_length=150, blank=True, null=True) # type: ignore last_name: str = CharField(_("last_name"), max_length=150, blank=True, null=True) # type: ignore avatar = ImageField( null=True, verbose_name=_("avatar"), upload_to=get_uuid_as_path, blank=True, help_text=_("user profile image"), ) is_verified: bool = BooleanField( # type: ignore default=False, verbose_name=_("is verified"), help_text=_("user verification status"), ) is_active: bool = BooleanField( # type: ignore _("is_active"), default=False, help_text=_("unselect this instead of deleting accounts"), ) is_subscribed: bool = BooleanField( # type: ignore verbose_name=_("is_subscribed"), help_text=_("user's newsletter subscription status"), default=False ) activation_token: uuid = UUIDField(default=uuid4, verbose_name=_("activation token")) # type: ignore language: str = CharField(choices=LANGUAGES, default=LANGUAGE_CODE, null=False, blank=False, max_length=7) # type: ignore attributes: dict = JSONField(verbose_name=_("attributes"), default=dict, blank=True, null=True) # type: ignore USERNAME_FIELD = "email" REQUIRED_FIELDS = [] # noinspection PyClassVar objects = UserManager() # type: ignore payments_balance: "Balance" user_related_wishlist: "Wishlist" orders: QuerySet["Order"] def add_to_recently_viewed(self, product_uuid): recently_viewed = self.recently_viewed if product_uuid not in recently_viewed: if not len(recently_viewed) >= 48: recently_viewed.append(product_uuid) cache.set(f"user_{self.uuid}_rv", recently_viewed) else: recently_viewed.pop(0) recently_viewed.append(product_uuid) cache.set(f"user_{self.uuid}_rv", recently_viewed) @property def recently_viewed(self): return cache.get(f"user_{self.uuid}_rv", []) def check_token(self, token): return str(token) == str(self.activation_token) def __str__(self): return self.email class Meta: swappable = "AUTH_USER_MODEL" verbose_name = _("user") verbose_name_plural = _("users") class Group(BaseGroup): class Meta: proxy = True verbose_name = _("group") verbose_name_plural = _("groups") class OutstandingToken(BaseOutstandingToken): class Meta: proxy = True verbose_name = _("outstanding token") verbose_name_plural = _("outstanding tokens") class BlacklistedToken(BaseBlacklistedToken): class Meta: proxy = True verbose_name = _("blacklisted token") verbose_name_plural = _("blacklisted tokens")