# -*- coding: utf-8 -*- import random, string from django.db import models from django.core.validators import email_re from django.db.models import Q from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin from django.core.mail import send_mail from django.utils import timezone from django.utils.translation import ugettext as _ from django.db.models.signals import post_save from django.db.models.loading import get_model #custom functions from functions.form_check import translit_with_separator """ from django.contrib.auth.hashers import check_password from hashlib import md5 from django.contrib.auth import get_user_model from django.db.models import get_model """ class UserManager(BaseUserManager): """ Creates and saves a User with the given email, first_name, last_name and password. """ def create_user(self, email, first_name, last_name, password=None, **extra_fields): now = timezone.now() if not email: raise ValueError('Вы должни ввести электронную почту') user= self.model( email = UserManager.normalize_email(email), first_name = first_name,last_name = last_name, username = UserManager.normalize_email(email), is_staff=False, is_active=False, is_superuser=False, last_login=now, date_joined=now, **extra_fields ) user.set_password(password) user.save(using=self._db) return user def create_social_user(self, username, first_name, last_name, password=None, **extra_fields): now = timezone.now() # generate random password digits = random.sample(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'), 4) chars = random.sample(string.lowercase[:], 4) password = chars + digits random.shuffle(password) password = ''.join(password) user= self.model(first_name=first_name, last_name=last_name, username=username, is_staff=False, is_active=True, is_superuser=False, last_login=now, date_joined=now, **extra_fields) check = True if email_re.match(username) else False if check: user.email = UserManager.normalize_email(username) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, username, first_name, last_name, password, **extra_fields): if not username: raise ValueError('Вы должни ввести электронную почту') username = UserManager.normalize_email(username) user = self.create_user( email = username, first_name = first_name,last_name = last_name, password = password, **extra_fields ) user.is_staff = True user.is_active = True user.is_superuser = True user.is_admin = True user.save(using=self._db) return user def safe_get(self, **kwargs): model = self.model try: return model.objects.get(**kwargs) except: return None class User(AbstractBaseUser, PermissionsMixin): """ Implementing a fully featured User model with admin-compliant permissions. stored main data about users Email, first name, last name and password are required. Other fields are optional. """ catalog = '/user/' email = models.EmailField( verbose_name = u'Email', max_length = 255, #unique = True, db_index = True, ) username = models.CharField(verbose_name='Email', max_length=255, unique=True, db_index=True) first_name = models.CharField(verbose_name='First name', max_length=255) last_name = models.CharField(verbose_name='Last name', max_length=255) rating = models.IntegerField(default=100)# добавить индекс в базе url = models.SlugField(blank=True)#, unique=True, null=True) # is_active = models.BooleanField(default=0) # СДЕЛАТЬ проверку на емейле is_staff = models.BooleanField(default=0) is_admin = models.BooleanField(default=0) date_joined = models.DateTimeField(auto_now_add=True) date_registered = models.DateTimeField(blank=True, null=True)# date_modified = models.DateTimeField(auto_now=True) #relations organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True, unique=True, on_delete=models.PROTECT) translator = models.ForeignKey('translator.Translator', verbose_name='Переводчик', blank=True, null=True, unique=True, on_delete=models.PROTECT, related_name='user') company = models.ForeignKey('company.Company', blank=True, null=True, related_name='users') position = models.CharField(verbose_name='Должность', max_length=255, blank=True) objects = UserManager() USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['first_name', 'last_name'] class Meta: ordering=['-rating'] def is_organiser(self): return bool(self.organiser) def get_full_name(self): """ Returns the first_name plus the last_name, with a space in between. """ return u'%s %s'%(self.first_name, self.last_name) def set_url(self, st): """ """ self.url = translit_with_separator(u'%s'%st) def __unicode__(self): return self.email def get_short_name(self): "Returns the short name for the user." return self.first_name def email_user(self, subject, message, from_email=None): """ Sends an email to this User. """ send_mail(subject, message, from_email, [self.email]) def has_perm(self, perm, obj=None): return True def has_module_perms(self, app_label): return True def get_expositions_number(self): # 1 query return self.exposition_users.all().count() def get_conferences_number(self): # 1 query return self.conference_users.all().count() def get_seminars_number(self): # 1 query return self.seminar_users.all().count() def get_webinars_number(self): # 1 query return self.webinar_users.all().count() def get_events_number(self): # 4 query n = self.get_expositions_number() + self.get_conferences_number() + self.get_seminars_number() + self.get_webinars_number() return n def get_permanent_url(self): if self.url: return '/%s/'%self.url #return self.catalog+self.url+'/' return '/%d/'%self.id #return self.catalog+str(self.id)+'/' def get_translator_url(self): if self.url: return '/translators/%s/'%self.url return '/translators/%d/'%self.id def get_expos(self): """ return information about expos and them related data by 1 query """ return self.exposition_users.language().select_related('country', 'city', 'place').all() def get_confs(self): """ return information about confs and them related data by 1 query """ return self.conference_users.language().select_related('country', 'city', 'place').all() def get_seminars(self): """ return information about seminars and them related data by 1 query """ return self.seminar_users.language().select_related('country', 'city').all() def remove_from_calendar(self, data): expo = data['expo'] conf = data['conf'] seminar = data['seminar'] webinar = data['webinar'] calendar = self.calendar if expo: calendar.expositions.remove(*expo) if conf: calendar.conferences.remove(*conf) if seminar: calendar.seminars.remove(*seminar) if webinar: calendar.webinars.remove(*webinar) class Profile(models.Model): """ stores additional information about users """ user = models.OneToOneField(User) country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, on_delete=models.PROTECT, related_name='users') city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, on_delete=models.PROTECT) about_company = models.TextField(verbose_name=_(u'Описание компании'), blank=True) phone = models.BigIntegerField(verbose_name=_(u'Телефон'), blank=True, null=True) show_phone = models.NullBooleanField(verbose_name=_(u'Показывать телефон'), blank=True, null=True, default=1) web_page = models.URLField(verbose_name='Вебсайт',blank=True) about = models.TextField(verbose_name='О себе', blank=True) avatar = models.ImageField(verbose_name='Фото', upload_to='accounts/avatar/', blank=True) skype = models.CharField(blank=True, max_length=255) facebook = models.URLField(verbose_name=_(u'Facebook'), blank=True, max_length=255) twitter = models.URLField(verbose_name=_(u'Twitter'), blank=True,max_length=255) linkedin = models.URLField(verbose_name=_(u'LinkedIn'), blank=True, max_length=255) vk = models.URLField(verbose_name=_(u'В контакте'), blank=True, max_length=255) # meta title = models.CharField(max_length=255, blank=True) descriptions = models.CharField(max_length=255, blank=True) keywords = models.CharField(max_length=255, blank=True) class Calendar(models.Model): """ Store information about events, which user can add to own calendar every user has one calendar """ user = models.OneToOneField(User) expositions = models.ManyToManyField('exposition.Exposition', null=True) conferences = models.ManyToManyField('conference.Conference', null=True) seminars = models.ManyToManyField('seminar.Seminar', null=True) webinars = models.ManyToManyField('webinar.Webinar', null=True) def get_expos(self): # 1 query return list(self.expositions.language().all()) def get_confs(self): # 1 query return list(self.conferences.language().all()) def get_seminars(self): # 1 query return list(self.seminars.language().all()) def get_webinars(self): # 1 query return list(self.webinars.language().all()) def get_events(self): # 4 query events = self.get_expos() + self.get_confs() + self.get_seminars() + self.get_webinars() return events def check_in_calendar(self, event): """ check if event in calendar 1 query """ event_type = event.event_type if event_type == 'expo': return event in self.get_expos() elif event_type == 'conf': return event in self.get_confs() elif event_type == 'seminar': return event in self.get_seminars() elif event_type == 'webinar': return event in self.get_webinars() def events_by_month(self, day): exp = list(self.expositions.filter((Q(data_begin__month=day.month) & Q(data_begin__year=day.year))\ | (Q(data_end__month=day.month) & Q(data_end__year=day.year)))) con = list(self.conferences.filter((Q(data_begin__month=day.month) & Q(data_begin__year=day.year))\ | (Q(data_end__month=day.month) & Q(data_end__year=day.year)))) sem = list(self.seminars.filter((Q(data_begin__month=day.month) & Q(data_begin__year=day.year))\ | (Q(data_end__month=day.month) & Q(data_end__year=day.year)))) web = list(self.webinars.filter(Q(data_begin__month=day.month)&Q(data_begin__year=day.year))) return exp+con+sem+web class EventFilter(models.Model): user = models.OneToOneField(User) theme = models.ManyToManyField('theme.Theme', null=True) tag = models.ManyToManyField('theme.Tag', null=True) area = models.ManyToManyField('country.Area', null=True) country = models.ManyToManyField('country.Country', null=True) city = models.ManyToManyField('city.City', null=True) fr = models.DateField(blank=True, null=True) to = models.DateField(blank=True, null=True) def get_queryset(self): Exposition = get_model('exposition', 'Exposition') qs = Exposition.enable.upcoming() themes = self.theme.all() tags = self.tag.all() countries = self.country.all() areas = self.area.all() cities = self.city.all() if themes.count(): qs = qs.filter(theme__in=list(themes)) if tags.count(): qs = qs.filter(tag__in=list(tags)) if cities.count(): qs = qs.filter(city__in=list(cities)) if areas.count(): qs = qs.filter(country__area__in=list(areas)) if countries.count(): qs = qs.filter(country__in=list(countries)) return qs.order_by('data_begin') def calculate_rating(user): user_rating_fields = {'position': 5, 'company': 5, 'url': 10} profile_rating_fields = {'country': 5, 'city': 5, 'phone': 10, 'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5, 'web_page': 10, 'avatar': 20, 'about': 15} ''' TODO: доделать "Отметки на выставках, за каждую", "Подписка на рассылку", "Добавление фото, за каждую", "Добавление компании, за каждую опубликованную" ''' # base rating rating = 100 for key, value in user_rating_fields.iteritems(): if getattr(user, key): rating += value for key, value in profile_rating_fields.iteritems(): if getattr(user.profile, key): rating += value user.rating = rating # call to prevent recursion post_save.disconnect(create_user_inf, sender=User) user.save() post_save.connect(create_user_inf, sender=User) def create_user_inf(sender, instance, created, **kwargs): if created: Calendar.objects.create(user=instance) Profile.objects.create(user=instance) EventFilter.objects.create(user=instance) calculate_rating(instance) def post_profile(sender, instance, created, **kwargs): user = instance.user calculate_rating(user) post_save.connect(create_user_inf, sender=User) post_save.connect(post_profile, sender=Profile)