示例#1
0
    def handle(self, *args, **options):
        now = datetime.datetime.now()
        print 'started', now

        ads_with_views_lt_2 = ViewsCount.objects.filter(
            date__range=[now - datetime.timedelta(days=30), now],
            basead__ad__user__in=User.get_user_ids_with_active_plan(),
            basead__ad__is_published=True,
        ).values_list('basead').annotate(contacts_views=Sum('contacts_views')).filter(contacts_views__lt=2)

        ads_without_views = Ad.objects.filter(
            user__in=User.get_user_ids_with_active_plan(), 
            is_published=True, viewscounts__isnull=True
        ).extra(select={'contacts_views': 0}).values_list('basead_ptr', 'contacts_views')

        count = 0

        for query in (ads_with_views_lt_2, ads_without_views):
            for basead_id, contacts_views in query:
                # для 0 или 1 реальных просмотров итоговое число просмотров с учетом добавленных будет от 2 до 3
                views_to_add = random.randint(2 - contacts_views, 3 - contacts_views)
                updated_rows = ViewsCount.objects.filter(basead_id=basead_id, date=now.date(), is_fake=True).update(
                    detail_views=F('detail_views') + views_to_add,
                    contacts_views=F('contacts_views') + views_to_add,
                )
                if not updated_rows:
                    ViewsCount.objects.create(basead_id=basead_id, date=now.date(), is_fake=True, 
                                              detail_views=views_to_add, contacts_views=views_to_add)
                count += 1

        print 'finished %s, added views for %d ads' % (datetime.datetime.now(), count)
示例#2
0
    def queryset(self, request, queryset):
        if self.value() == 'plan':
            return queryset.filter(
                users__in=User.get_user_ids_with_active_plan())
        elif self.value() == 'ppk':
            return queryset.filter(
                users__in=User.get_user_ids_with_active_ppk()).distinct()
        elif self.value() == 'plan_ppk':
            ids = set(User.get_user_ids_with_active_plan()) | set(
                User.get_user_ids_with_active_ppk())
            return queryset.filter(users__in=ids).distinct()

        return queryset
示例#3
0
def create_auth(request):
    serialized = UserSerializer(data=request.data,
                                context={'request': request})
    init_data = serialized.initial_data.copy()
    init_data['password1'] = init_data['password2'] = init_data.get('password')

    form = PersonRegForm(init_data, instance=User())
    if serialized.is_valid() and form.is_valid():
        new_user = get_user_model().objects.create_user(
            email=init_data['email'],
            username=init_data['username'],
            password=init_data['password'],
            first_name=init_data['first_name'],
            last_name=init_data['last_name'],
        )
        user_registered.send(sender=MestoRegistrationView,
                             user=new_user,
                             request=request)

        return Response(UserSerializer(new_user, context={
            'request': request
        }).data,
                        status=status.HTTP_201_CREATED)
    else:
        errors = dict(form.errors.items() + serialized._errors.items())
        return Response(errors, status=status.HTTP_400_BAD_REQUEST)
示例#4
0
文件: forms.py 项目: VadymRud/nedvizh
 def save(self, commit=True):
     user = super(RegistrationForm, self).save(commit=False)
     user.username = User.make_unique_username(self.cleaned_data['email'])
     user.set_password(self.cleaned_data['password1'])
     if commit:
         user.save()
     return user
示例#5
0
    def queryset(self, request, queryset):
        if self.value() == 'bank':
            return queryset.filter(bank__isnull=False)
        if self.value() == 'import':
            return queryset.filter(user__isnull=False, xml_id__gt=0)
        elif self.value() == 'parser':
            return queryset.filter(user__isnull=True)
        elif self.value() == 'user':
            return queryset.filter(bank__isnull=True, user__isnull=False)
        elif self.value() == 'person':
            return queryset.filter(user__isnull=False,
                                   user__agencies__isnull=True)
        elif self.value() == 'agency':
            return queryset.filter(user__agencies__isnull=False)
        elif self.value() == 'export':
            return queryset.filter(international_catalog__isnull=False)
        elif self.value() == 'plan':
            from custom_user.models import User
            return queryset.filter(
                user__in=User.get_user_ids_with_active_plan(),
                addr_country='UA')
        elif self.value() == 'ppk':
            return queryset.filter(user__activityperiods__isnull=False,
                                   user__activityperiods__end=None)
        elif self.value() == 'ppk_shared':
            return queryset.filter(
                user__activityperiods__isnull=False,
                user__activityperiods__end=None,
                user__leadgeneration__dedicated_numbers=False)

        return queryset
示例#6
0
 def queryset(self):
     return super(Krysha, self).queryset().filter(
         addr_street__gt='',
         user__in=User.objects.filter(
             id__in=User.get_user_ids_with_active_ppk(),
             region__slug__in=[
                 'kievskaya-oblast', 'odesskaya-oblast',
                 'hersonskaya-oblast', 'hmelnitskaya-oblast'
             ]),
     ).prefetch_related('phones')
示例#7
0
    def handle(self, *args, **options):
        print '--> Start Facebook autoposting process'

        # Внимание!!! Нельзя публиковать чаще чем 1 раз в 90 минут, иначе Facebook забанит
        allow_date = datetime.datetime.now() - datetime.timedelta(minutes=91)
        facebook_autoposting = FacebookAutoposting.objects.filter(
            (Q(last_posting_at__lt=allow_date)
             | Q(last_posting_at__isnull=True))
            & Q(access_token_expires_at__gt=datetime.datetime.now(),
                is_active=True)).exclude(access_token__isnull=True)

        if facebook_autoposting.exists():
            for fb_autoposting in facebook_autoposting:
                translation.activate(fb_autoposting.language)

                print '  --> choose ad for Facebook autoposting #%d' % fb_autoposting.id
                # Выбираем одно объявление по заданным параметрам, которое еще ни разу не публиковали
                ads = Ad.objects.filter(
                    deal_type=fb_autoposting.deal_type,
                    region__id__in=fb_autoposting.region.get_children_ids(),
                    is_published=True,
                    status=1,
                    facebook_autoposting_ads__isnull=True,
                    has_photos=True,
                    price_uah__gte=fb_autoposting.min_price).order_by(
                        '-created')

                ad = ads.filter(user__in=User.get_user_ids_with_active_ppk()
                                ).first() or ads.first()

                if ad:
                    print '    --> chosen ad #%d' % ad.pk
                    graph = GraphAPI(access_token=fb_autoposting.access_token)
                    try:
                        object_id = graph.put_object(
                            parent_object=fb_autoposting.page_id,
                            connection_name='feed',
                            link=ad.get_absolute_url(),
                            message=ad.get_absolute_url(),
                            published=True)

                    except GraphAPIError as e:
                        print '    --> error while posting ad', e
                        continue

                    fb_autoposting.last_posting_at = datetime.datetime.now()
                    fb_autoposting.save()

                    FacebookAutopostingAd.objects.create(
                        facebook_autoposting=fb_autoposting,
                        basead=ad.basead_ptr,
                        page_id=object_id)
                    print '    --> success posting to Facebook and mark Ad'

        print '<-- Finish Facebook autoposting process'
示例#8
0
    def handle(self, **options):
        # translation.activate('uk')
        translation.activate('ru')

        if 'test_users' in options and options['test_users']:
            users_query = User.objects.filter(id__in=options['test_users'])

        else:
            # regions_id = Region.objects.get(id=55).get_children_ids()
            users_id = User.get_user_ids_with_active_plan() | set(
                User.get_user_ids_with_active_ppk())
            users_query = User.objects.filter(
                # email__gt='', subscribe_news=True, ads__region__in=regions_id
                # email__gt='', subscribe_news=True, ads_count__gt=0
                email__gt='',
                subscribe_news=True,
                id__in=users_id).distinct().order_by('id')

            if options['start_from_user']:
                users_query = users_query.filter(
                    id__gte=options['start_from_user'])

        # pynliner - тормоз, лучше внутрь цикла его не класть
        content = render_to_string(
            'mail/mailing/mail_about_new_services.jinja.html', {})
        content_with_inline_css = pynliner.fromString(content)

        for user in users_query:
            print 'user #%d' % user.id

            message = EmailMessage(
                u'Обновленный раздел "Услуги" + мобильные номера телефонов',
                content_with_inline_css, settings.DEFAULT_FROM_EMAIL,
                [user.email])
            message.content_subtype = 'html'
            message.send()
示例#9
0
def users_photo(request, username, photo_key):
    viewed_user = User.get_user_by_username_or_404(username)
    photo = get_object_or_404(Photo, photo_key)
    
    if photo.user != viewed_user:
        raise Http404('Object does not exist!')
    
    extra_context = {
        'viewed_user': viewed_user,
        'photo': photo,
        'viewed_username': username
    }
    
    return object_list(request,
        queryset=Thumbnail.all().filter('photo_user', viewed_user).order('-photo_date_added'),
        template_name='photo/show.html',
        extra_context=extra_context
    )
示例#10
0
def filter_user_by_plan(queryset, parameter):
    from custom_user.models import User
    if parameter == 'w-plan':
        return queryset.filter(pk__in=User.get_user_ids_with_active_plan())
    elif parameter == 'w-money-wo-plan':
        users_with_money = [
            transaction['user']
            for transaction in Transaction.objects.values('user').annotate(
                balance=models.Sum('amount')).order_by('user')
            if transaction['balance'] > 0
        ]
        return queryset.filter(pk__in=users_with_money).exclude(
            pk__in=User.get_user_ids_with_active_plan())
    elif parameter == 'wo-ads-w-plan':
        return queryset.filter(pk__in=User.get_user_ids_with_active_plan(),
                               ads_count=0)
    elif parameter == 'w-ads-wo-plan':
        return queryset.filter(ads_count__gt=0).exclude(
            pk__in=User.get_user_ids_with_active_plan())
    elif parameter == 'w-overlimit':
        users_with_overlimit = UserPlan.objects.filter(
            end__gt=datetime.datetime.now(),
            user__ads_count__gt=models.F('plan__ads_limit')).values_list(
                'user', flat=True).order_by('user')
        return queryset.filter(pk__in=users_with_overlimit)
    elif parameter == 'w-expired-plan':
        prev_month_end = datetime.date.today().replace(
            day=1) - datetime.timedelta(days=1)
        prev_month_start = prev_month_end.replace(day=1)
        users_with_plan_in_prev_month = UserPlan.objects.filter(
            start__lt=prev_month_end, end__gt=prev_month_start).exclude(
                transactions__amount=0).values_list('user', flat=True)
        user_ids_w_expired_plan = set(users_with_plan_in_prev_month) - set(
            User.get_user_ids_with_active_plan())
        return queryset.filter(pk__in=user_ids_w_expired_plan)
    elif parameter == 'w-plan-first-time':
        user_ids_w_plan_first_time = set(
            UserPlan.objects.filter(
                plan__is_active=True,
                user__in=User.get_user_ids_with_active_plan()).values(
                    'user').annotate(cnt=models.Count('user')).filter(
                        cnt=1).values_list('user', flat=True))
        return queryset.filter(pk__in=user_ids_w_plan_first_time)
    elif parameter == 'wo-any':
        return queryset.filter(transactions__isnull=True, ads__isnull=True)
    elif parameter == 'w-ppk':
        return queryset.filter(pk__in=User.get_user_ids_with_active_ppk())
示例#11
0
def users_page(request, username):
    viewed_user = User.get_user_by_username_or_404(username)
    
    photo = None
    fetched_photo_list = Photo.all().filter('user', viewed_user).order('-date_added').fetch(1)
    if fetched_photo_list:
        photo = fetched_photo_list[0]
    
    extra_context = {
        'viewed_user': viewed_user,
        'photo': photo,
        'viewed_username': username
    }
    
    return object_list(request,
        queryset=Thumbnail.all().filter('photo_user', viewed_user).order('-photo_date_added'),
        template_name='photo/show.html',
        extra_context=extra_context
    )
示例#12
0
 def validate(self, data):
     email = data.get("email", "")
     password = data.get("password", "")
     full_name = data.get("full_name", "")
     location = data.get("location", "")
     if User.objects.filter(email=email).exists():  # Check email already registered or not.
         mes = "Email already exist."  # Message if user already registered.
         raise exceptions.APIException(mes)  # Call message if user already registered.
     else:  # Do if user not registered.
         User_Set = User(
             full_name = full_name,
             email=email,
             location=location,
             is_active=False,
         )  # Insert value in user table according to filed name.
         User_Set.set_password(password)  # Set password for user registration.
         User_Set.save()  # Save user data into table.
         return User_Set  # Return some information according to function.
示例#13
0
    def handle(self, *args, **options):
        users_id = LeadGeneration.objects.filter(
            dedicated_numbers=True,
            user__in=User.get_user_ids_with_active_ppk()).values_list(
                'user', flat=True)

        # Уведомляем об окончании услуги Выделенный номер за день до окончания
        service_will_end_for_users = User.objects.filter(
            Q(transactions__type=80, receive_sms=True, id__in=users_id)
            & (Q(transactions__time__range=(
                datetime.datetime.now() - datetime.timedelta(days=29),
                datetime.datetime.now() -
                datetime.timedelta(days=28))))).distinct().order_by('id')
        print '--> Start beforehand notification by sms', datetime.datetime.now(
        )
        text = u'Завтра заканчивается срок действия услуги "Выделенный номер". Пополните баланс на 100 грн'
        for user in service_will_end_for_users:
            # если на балансе есть 100 грн, то за номер выделенный нлмер автоматически спишется
            if user.get_balance() < 100:
                print '  --> user #%d' % user.id
                user.send_notification(text)

        # Уведомляем об окончании услуги Выделенный номер за 7, 3 и в день окончания предоставления услуги
        service_will_end_for_users = User.objects.filter(
            Q(transactions__type=80, subscribe_info=True, id__in=users_id)
            & (Q(transactions__time__range=(
                datetime.datetime.now() - datetime.timedelta(days=23),
                datetime.datetime.now() - datetime.timedelta(days=22)))
               | Q(transactions__time__range=(
                   datetime.datetime.now() - datetime.timedelta(days=27),
                   datetime.datetime.now() - datetime.timedelta(days=26)))
               | Q(transactions__time__range=(
                   datetime.datetime.now() - datetime.timedelta(days=30),
                   datetime.datetime.now() -
                   datetime.timedelta(days=29))))).distinct().order_by('id')
        print '--> Start beforehand notification', datetime.datetime.now()

        utm = make_utm_dict(utm_campaign='ppc_notification')
        for user in service_will_end_for_users:
            print '  --> user #%d' % user.id

            translation.activate(user.language)

            # Количество дней до окончания тарифа
            days = 30 - (datetime.datetime.now() -
                         user.transactions.filter(type=80).first().time).days
            content = render_to_string(
                'ppc/mail/ppc-notification-beforehand.jinja.html', {
                    'utm': utm,
                    'ga_pixel': make_ga_pixel_dict(user, utm),
                    'days': days
                })
            content_with_inline_css = pynliner.fromString(content)

            message = EmailMessage(
                _('Заканчивается срок действия абон.платы услуги "Выделенный номер"'
                  ), content_with_inline_css, settings.DEFAULT_FROM_EMAIL,
                [user.email])
            message.content_subtype = 'html'
            message.send()

        # Уведомляем пользователей о неактивной услуге Выделенный номер
        # на следующий день после окончания услуги и через неделю
        print '--> Start afterward notification', datetime.datetime.now()
        service_ended_for_users = User.objects.filter(
            Q(transactions__type=80, subscribe_info=True)
            & (Q(transactions__time__range=(
                datetime.datetime.now() - datetime.timedelta(days=32),
                datetime.datetime.now() - datetime.timedelta(days=31)))
               | Q(transactions__time__range=(
                   datetime.datetime.now() - datetime.timedelta(days=39),
                   datetime.datetime.now() -
                   datetime.timedelta(days=38))))).distinct().order_by('id')

        for user in service_ended_for_users:
            # Если у пользователя не было транзакций за Выделенный номер за последние 7 дней
            if not user.transactions.filter(
                    type=80,
                    time__gte=(datetime.datetime.now() -
                               datetime.timedelta(days=7))).exists():
                print '  --> user #%d' % user.id

                translation.activate(user.language)

                content = render_to_string(
                    'ppc/mail/ppc-notification-afterward.jinja.html', {
                        'utm': utm,
                        'ga_pixel': make_ga_pixel_dict(user, utm)
                    })
                content_with_inline_css = pynliner.fromString(content)

                message = EmailMessage(
                    _('Закончился срок действия абон.платы услуги "Выделенный номер"'
                      ), content_with_inline_css, settings.DEFAULT_FROM_EMAIL,
                    [user.email])
                message.content_subtype = 'html'
                message.send()
示例#14
0
    def create_call_from_ringostat_json(data):
        from django.utils.dateparse import parse_datetime

        print ' call from %s to proxy %s at %s:' % (
            data['caller'], data['n_alias'], data['calldate'][:19]),
        call_time = parse_datetime(data['calldate']).replace(tzinfo=None)
        call = Call.objects.filter(uniqueid1=data['uniqueid'],
                                   call_time=call_time).first()
        if call:
            print 'already existed: Call #%d' % call.pk
            return call

        numbers = [data['n_alias']]
        if data['n_alias'][0] == '0':
            numbers.append('38%s' % data['n_alias'])

        try:
            proxynumber = ProxyNumber.objects.get(number__in=numbers)
        except ProxyNumber.DoesNotExist:
            print 'proxynumber not found'
            return
        else:
            user = proxynumber.user

        object_id = cache.get('additional_number_for_call_%s' %
                              data['uniqueid'])
        deal_type = proxynumber.deal_type

        # для создания звонка, даже если не определили куда переадресовывать
        # Иногда номер звонившего в формате '7908578862079085788620;79085788620', а иногда anonymous
        call = Call(proxynumber=proxynumber,
                    uniqueid1=data['uniqueid'],
                    call_time=call_time,
                    callerid1='38000000000' if 'anonymous' in data['caller']
                    else data['caller'].split(';')[-1])

        # определяем пользователя и тип сделки
        if object_id:
            print 'object id: %s |' % object_id,
            try:
                if proxynumber.deal_type == 'newhomes':
                    user = Newhome.objects.get(pk=object_id).user
                    deal_type = proxynumber.deal_type
                else:
                    ad = Ad.objects.get(pk=object_id)
                    deal_type = ad.deal_type
                    user = ad.user
            except (Newhome.DoesNotExist, Ad.DoesNotExist):
                print '%s %s not found |' % (proxynumber.deal_type
                                             or 'ad', object_id),

        elif not user and proxynumber.is_shared and data['connected_with']:
            '''
                Попытка найти пользователя по номеру с которым соединили, наприммер когда модератор вручную переадресовал
                А так же берем тип сделки судя по большинству объявлений пользователя
            '''
            from custom_user.models import User
            from collections import Counter
            connected_with = data['connected_with'].split('@')[0]
            user = User.objects.filter(
                phones=connected_with,
                id__in=User.get_user_ids_with_active_ppk()).first()
            if user:
                deal_type = Counter(
                    user.ads.filter(is_published=True).values_list(
                        'deal_type', flat=True)).most_common(1)[0][0]

        if not user:
            if proxynumber.is_shared:
                print 'no object id for shared number |',
            else:
                print 'dedicated number doesnt have attached user |',
        elif not user.has_active_leadgeneration():
            print 'user doesnt have active leadgeneration |',
        else:
            call.user2 = user
            call.deal_type = deal_type
            call.object_id = object_id
            call.callerid2 = data['connected_with'].split('@')[
                0]  # номер в формате '79068701187@billing/n'

            if data['disposition'] not in [
                    'NO ANSWER', 'BUSY'
            ] and call.callerid2 and data['billsec']:
                call.duration = data['billsec']

        call.save()
        print 'call #%s created' % call.pk,

        if call.duration and data.get('recording'):
            if call.download_record(data['recording']):
                print '| call record download sucessfully'
            else:
                print '|  save url of call record in cache:', data['recording']
                cache.set('call%d-record' % call.pk, data['recording'],
                          60 * 30)
        else:
            print

        return call
def user_login_via_otp_form_otp(request):
    ## CLEARING ALL THE MESSAGES
    system_messages = messages.get_messages(request)
    for message in system_messages:
        # This iteration is necessary
        pass
    system_messages.used = True


    # CHECKING whether the session variable exists or not
    if 'jwt_token' in request.session:
        jwt_token = request.session['jwt_token']
    else:
        messages.error(request, 'jwt_token in session not found')
        return redirect('login_register_password_namespace:user_login_via_otp_form_email')

    # CHECKING jwt token and getting the payload
    try:
        # options = {
        #     'verify_exp': True,
        # }
        payload = jwt.decode(
            jwt_token,
            settings.SECRET_KEY,
            True,
            #options=options,
        )
        #logger_custom_string.debug(settings.pp_dict(payload))
    except Exception as e:  # NoQA
        #logger_custom_string.debug(str(e))
        pass

    # FORM
    from .forms import UserLoginViaOtpFormOTP
    if request.method == 'POST':

        form = UserLoginViaOtpFormOTP(request.POST)
        if form.is_valid():
            otp_loginconfirm = form.cleaned_data.get('otp_loginconfirm')

            #COMPARE TIME LIMIT FOR OTP

            #convert payload creation time to datetime
            creation_time = datetime.datetime.fromisoformat(payload['creation_time'])
            #datetime.timedelta(minutes=1, seconds=1)
            timelimit = datetime.timedelta(seconds=10)
            current_time = datetime.datetime.now(tz=pytz.timezone('UTC'))
            timecheck = current_time - creation_time < timelimit
            timedelta = current_time - creation_time
            import traceback
            logger_custom_string.debug(settings_basic_django.pp_odir(locals(),traceback.format_stack(limit=5)))

            if current_time - creation_time > timelimit:
                form.add_error(None,"OTP expired, Click on resend OTP")
                return render(request, 'login_register_password/login_via_otp/user_login_via_otp_form_otp.html',{'form': form})

            if payload['OTP'] == otp_loginconfirm:

                # CHECK for an existing user
                try:

                    match = User.objects.get(email=payload['email'])
                    time_now = timezone.now()
                    # if we do timezone.now(), (with a comma then it will save as tuple and will give error)
                    match.last_login2=time_now
                    match.recentdate_login_via_otp=time_now
                    match.save()

                    if match.is_active:
                        login(request,match,backend='django.contrib.auth.backends.ModelBackend')
                    else:
                        messages(email, ' :not active')
                        return redirect('login_register_password_namespace:user_login_via_otp_form_email')

                    #Get ip address
                    ip = settings.get_client_ip(request)

                    # get the action type
                    action_type = ActionTypeForUserSessionLog.objects.get(action='login_by_otp')

                    # Save in the session
                    match_UserSessionLog = UserSessionLog(
                        user_email=match.email,
                        ip_address = ip,
                        user = match,
                        otp_used_for_otplogin=payload['OTP'],
                        action_type=action_type,
                        device_type=request.META['HTTP_USER_AGENT'],
                        created_time=time_now
                    )

                    match_UserSessionLog.save()
                    
                except User.DoesNotExist:
                    #we create a new user

                        ###   total length of Model_meta.get_fields(include_hidden=True):  31
                        ###   
                        ###   
                        ###   [
                        ###       "<ManyToOneRel: admin.logentry>",
                        ###       "<ManyToOneRel: custom_user.user_groups>",
                        ###       "<ManyToOneRel: custom_user.user_user_permissions>",
                        ###       "<ManyToOneRel: custom_user.usersessionlog>",
                        ###       [
                        ###           "<django.db.models.fields.AutoField: id>",
                        ###           "STR: custom_user.User.id"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: last_login>",
                        ###           "STR: custom_user.User.last_login"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.BooleanField: is_superuser>",
                        ###           "STR: custom_user.User.is_superuser"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.BooleanField: is_staff>",
                        ###           "STR: custom_user.User.is_staff"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: date_joined>",
                        ###           "STR: custom_user.User.date_joined"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: password>",
                        ###           "STR: custom_user.User.password"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: recentdate_login_via_passwd>",
                        ###           "STR: custom_user.User.recentdate_login_via_passwd"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: recentdate_login_via_otp>",
                        ###           "STR: custom_user.User.recentdate_login_via_otp"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: recentdate_password_change>",
                        ###           "STR: custom_user.User.recentdate_password_change"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: first_name>",
                        ###           "STR: custom_user.User.first_name"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: last_name>",
                        ###           "STR: custom_user.User.last_name"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.EmailField: email>",
                        ###           "STR: custom_user.User.email"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.BooleanField: is_active>",
                        ###           "STR: custom_user.User.is_active"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: recent_otp_used_for_pass_change>",
                        ###           "STR: custom_user.User.recent_otp_used_for_pass_change"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: date_of_recent_otp_used_for_pass_change>",
                        ###           "STR: custom_user.User.date_of_recent_otp_used_for_pass_change"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: otp_used_while_passlogin_create>",
                        ###           "STR: custom_user.User.otp_used_while_passlogin_create"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: date_of_otp_used_while_passlogin_create>",
                        ###           "STR: custom_user.User.date_of_otp_used_while_passlogin_create"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: first_otp_used_for_otplogin>",
                        ###           "STR: custom_user.User.first_otp_used_for_otplogin"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: date_of_first_otp_used_for_otplogin>",
                        ###           "STR: custom_user.User.date_of_first_otp_used_for_otplogin"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.TextField: about>",
                        ###           "STR: custom_user.User.about"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.CharField: location>",
                        ###           "STR: custom_user.User.location"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateField: birth_date>",
                        ###           "STR: custom_user.User.birth_date"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: modified_date>",
                        ###           "STR: custom_user.User.modified_date"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: creation_date>",
                        ###           "STR: custom_user.User.creation_date"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.DateTimeField: last_login2>",
                        ###           "STR: custom_user.User.last_login2"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.related.ManyToManyField: groups>",
                        ###           "STR: custom_user.User.groups"
                        ###       ],
                        ###       [
                        ###           "<django.db.models.fields.related.ManyToManyField: user_permissions>",
                        ###           "STR: custom_user.User.user_permissions"
                        ###       ]
                        ###   ]
                        ###   
                        ###   
                        ###   
                        ###   Lenght of c_dict[000_null_true***********************************************************************]  8
                        ###   Lenght of c_dict[001_remaining***********************************************************************]  1
                        ###   Lenght of c_dict[002_null_false_and_empty_strings****************************************************]  10
                        ###   Lenght of c_dict[003_auto_now_add__OR__auto_now******************************************************]  2
                        ###   Lenght of c_dict[004_auto_created********************************************************************]  5
                        ###   Lenght of c_dict[005_default_not_empty_string********************************************************]  5
                        ###   Total lenght of c_dict:  31
                        ###   {
                        ###       "000_null_true***********************************************************************": {
                        ###           "birth_date": {
                        ###               "000_class": "<class 'django.db.models.fields.DateField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true
                        ###           },
                        ###@@@@       "date_of_first_otp_used_for_otplogin": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###           "date_of_otp_used_while_passlogin_create": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###           "date_of_recent_otp_used_for_pass_change": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###           "last_login": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true
                        ###           },
                        ###@@@@       "recentdate_login_via_otp": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true
                        ###           },
                        ###           "recentdate_login_via_passwd": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true
                        ###           },
                        ###           "recentdate_password_change": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": true,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true
                        ###           }
                        ###       },
                        ###       "001_remaining***********************************************************************": {
                        ###@@@@       "last_login2": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true
                        ###           }
                        ###       },
                        ###       "002_null_false_and_empty_strings****************************************************": {
                        ###           "about": {
                        ###               "000_class": "<class 'django.db.models.fields.TextField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": true,
                        ###               "max_length": 500
                        ###           },
                        ###@@@@       "email": {
                        ###               "000_class": "<class 'django.db.models.fields.EmailField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": false,
                        ###               "max_length": 254,
                        ###               "unique": true
                        ###           },
                        ###           "first_name": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": true,
                        ###               "max_length": 30
                        ###           },
                        ###@@@@       "first_otp_used_for_otplogin": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": false,
                        ###               "max_length": 6
                        ###           },
                        ###           "groups": {
                        ###               "000_class": "<class 'django.db.models.fields.related.ManyToManyField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": true,
                        ###               "many_to_many": true,
                        ###               "one_to_many": false,
                        ###               "one_to_one": false,
                        ###               "remote_field": "<ManyToManyRel: custom_user.user>"
                        ###           },
                        ###           "last_name": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": true,
                        ###               "max_length": 150
                        ###           },
                        ###           "location": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": true,
                        ###               "max_length": 30
                        ###           },
                        ###           "otp_used_while_passlogin_create": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": false,
                        ###               "max_length": 6
                        ###           },
                        ###           "recent_otp_used_for_pass_change": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": false,
                        ###               "max_length": 6
                        ###           },
                        ###           "user_permissions": {
                        ###               "000_class": "<class 'django.db.models.fields.related.ManyToManyField'>",
                        ###               "001_default": "",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": true,
                        ###               "many_to_many": true,
                        ###               "one_to_many": false,
                        ###               "one_to_one": false,
                        ###               "remote_field": "<ManyToManyRel: custom_user.user>"
                        ###           }
                        ###       },
                        ###       "003_auto_now_add__OR__auto_now******************************************************": {
                        ###           "creation_date": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "003_auto_now_add": true,
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true,
                        ###               "editable": false
                        ###           },
                        ###           "modified_date": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "004_auto_now": true,
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true,
                        ###               "editable": false
                        ###           }
                        ###       },
                        ###       "004_auto_created********************************************************************": {
                        ###           "User_groups+": {
                        ###               "000_class": "<class 'django.db.models.fields.reverse_related.ManyToOneRel'>",
                        ###               "002_auto_created": true,
                        ###               "005_null": true,
                        ###               "editable": false,
                        ###               "hidden": true,
                        ###               "many_to_many": false,
                        ###               "one_to_many": true,
                        ###               "one_to_one": false,
                        ###               "remote_field": [
                        ###                   "<django.db.models.fields.related.ForeignKey: user>",
                        ###                   "STR: custom_user.User_groups.user"
                        ###               ]
                        ###           },
                        ###           "User_user_permissions+": {
                        ###               "000_class": "<class 'django.db.models.fields.reverse_related.ManyToOneRel'>",
                        ###               "002_auto_created": true,
                        ###               "005_null": true,
                        ###               "editable": false,
                        ###               "hidden": true,
                        ###               "many_to_many": false,
                        ###               "one_to_many": true,
                        ###               "one_to_one": false,
                        ###               "remote_field": [
                        ###                   "<django.db.models.fields.related.ForeignKey: user>",
                        ###                   "STR: custom_user.User_user_permissions.user"
                        ###               ]
                        ###           },
                        ###           "id": {
                        ###               "000_class": "<class 'django.db.models.fields.AutoField'>",
                        ###               "002_auto_created": true,
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": true,
                        ###               "primary_key": true,
                        ###               "unique": true
                        ###           },
                        ###           "logentry": {
                        ###               "000_class": "<class 'django.db.models.fields.reverse_related.ManyToOneRel'>",
                        ###               "002_auto_created": true,
                        ###               "005_null": true,
                        ###               "editable": false,
                        ###               "many_to_many": false,
                        ###               "one_to_many": true,
                        ###               "one_to_one": false,
                        ###               "remote_field": [
                        ###                   "<django.db.models.fields.related.ForeignKey: user>",
                        ###                   "STR: admin.LogEntry.user"
                        ###               ]
                        ###           },
                        ###           "usersessionlog": {
                        ###               "000_class": "<class 'django.db.models.fields.reverse_related.ManyToOneRel'>",
                        ###               "002_auto_created": true,
                        ###               "005_null": true,
                        ###               "editable": false,
                        ###               "many_to_many": false,
                        ###               "one_to_many": true,
                        ###               "one_to_one": false,
                        ###               "remote_field": [
                        ###                   "<django.db.models.fields.related.ForeignKey: user>",
                        ###                   "STR: custom_user.UserSessionLog.user"
                        ###               ]
                        ###           }
                        ###       },
                        ###       "005_default_not_empty_string********************************************************": {
                        ###@@@@       "date_joined": {
                        ###               "000_class": "<class 'django.db.models.fields.DateTimeField'>",
                        ###               "001_default": [
                        ###                   "datetime.datetime(2019, 10, 12, 1, 16, 2, 339774, tzinfo=<UTC>)",
                        ###                   "STR: 2019-10-12 01:16:02.339774+00:00"
                        ###               ],
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###@@@@       "is_active": {
                        ###               "000_class": "<class 'django.db.models.fields.BooleanField'>",
                        ###               "001_default": false,
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###           "is_staff": {
                        ###               "000_class": "<class 'django.db.models.fields.BooleanField'>",
                        ###               "001_default": false,
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###           "is_superuser": {
                        ###               "000_class": "<class 'django.db.models.fields.BooleanField'>",
                        ###               "001_default": false,
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": false,
                        ###               "007_blank": false
                        ###           },
                        ###           "password": {
                        ###               "000_class": "<class 'django.db.models.fields.CharField'>",
                        ###               "001_default": "pbkdf2_sha256$150000$zV7im78Gkp9T$zv2vl1sYuqtAaoWhjn7jpdHIoY2mzFKrtsN9MiR37SQ=",
                        ###               "005_null": false,
                        ###               "006_empty_strings_allowed": true,
                        ###               "007_blank": false,
                        ###               "max_length": 128
                        ###           }
                        ###       }
                        ###   }

                    time_now = timezone.now()
                    # if we do timezone.now(), (with a comma then it will save as tuple and will give error)
                    newuser = User(
                        email=payload['email'],
                        first_otp_used_for_otplogin=payload['OTP'],
                        date_of_first_otp_used_for_otplogin=time_now,
                        last_login2=time_now,
                        recentdate_login_via_otp=time_now,
                        is_active=True,
                        # we use timezone.now without brackets in default, so if dont convert to string it throws error
                        # expected string or bytes-like object @ dateparse.py in parse_datetime, line 106
                        date_joined=time_now
                        )
                    newuser.save()

                    if newuser.is_active:
                        login(request,newuser,backend='django.contrib.auth.backends.ModelBackend')
                    else:
                        messages(email, ' :not active')
                        return redirect('login_register_password_namespace:user_login_via_otp_form_email')


                    # Get the client ip:
                    ip = settings.get_client_ip(request)

                    action_type = ActionTypeForUserSessionLog.objects.get(action='login_by_otp')



                    # Save in the session
                    new_UserSessionLog = UserSessionLog(
                        user_email=newuser.email,
                        ip_address = ip,
                        user = newuser,
                        otp_used_for_otplogin=payload['OTP'],
                        action_type=action_type,
                        device_type=request.META['HTTP_USER_AGENT'],
                        created_time=time_now
                    )

                    new_UserSessionLog.save()

                messages.success(request, 'Login successful')
                return redirect('articles_namespace:articles')

            form.add_error(None,"Form Error: Wrong OTP entered")
            return render(request, 'login_register_password/login_via_otp/user_login_via_otp_form_otp.html',{'form': form})
    else:
        #logger_custom_string.debug(request.GET.get('resendotp'))
        #logger_custom_string.debug(settings.pp_dict(request.GET))
        #logger_custom_string.debug('resendotp' in request.GET)

        if 'resendotp' in request.GET:

            email = payload['email']
            # generate a random pin using crpto functions
            pin = get_random_string(length=6, allowed_chars='1234567890')
            
            # EMAIL subject and BODY
            # for BODY we use a template and render it with parameters
            subject = pin + ': To Login via OTP'
            # We to create the email body. So we create a template and pass the required arguments.
            # render_to_string will render the template with the context values
            message = render_to_string('login_register_password/login_via_otp/email/login_otp_sendemail.html', {
                'email': email,
                'pin': pin
            })

            # USING CELERY TASK for sending email Asynchronously
            #match.email_user(subject, message). This will delay the response 
            # So will do this task asynchronously using celery
            # We have created a celery task. Using it we will send the email.
            # The code does not have to wait till the email is sent
            send_email_task.delay(email,subject,message)

            #USING MESSAGES to inform the user in the next page about email is being sent
            #we want to inform the user on the next page that email is being sent for OTP
            #For this we use messages
            messages.success(request, 'Email is being sent please check')

            payload = {
                'email': email,
                'OTP': pin,
                'creation_time': str(datetime.datetime.now(tz=pytz.timezone('UTC')).isoformat())
            }

            jwt_token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
            # USING SESSION to make data available to next view.
            #For the next page we want to send some data which we dont want to display.
            request.session['jwt_token'] = jwt_token
            #logger_custom_string.debug(jwt_token)

        else:
            # Want to check no one access this page directy. But only through the user_login_via_otp_form_email pages
            try:
                prev_url = request.META['HTTP_REFERER']

                # we want to get the url from namespace . We use reverse. But this give relative url not the full url with domain
                login_form_email_url_reverse = reverse("login_register_password_namespace:user_login_via_otp_form_email")
                # to get the full url we have to use do the below
                login_form_email_url_reverse_full = request.build_absolute_uri(login_form_email_url_reverse)

                #logger_custom_string.debug(prev_url)
                #logger_custom_string.debug(login_form_email_url_reverse_full)
                if prev_url != login_form_email_url_reverse_full:
                    #logger_custom_string.debug(prev_url != login_form_email_url_reverse_full)
                    return redirect('login_register_password_namespace:user_login_via_otp_form_email')
            except Exception as e:
                messages.error(request, str(e))
                #logger_custom_string.debug(str(e))
                return redirect('login_register_password_namespace:user_login_via_otp_form_email')

        form = UserLoginViaOtpFormOTP(initial={'otp_loginconfirm': payload['OTP']})
    return render(request, 'login_register_password/login_via_otp/user_login_via_otp_form_otp.html',{'form': form})
示例#16
0
    def handle(self, *args, **options):
        print '--> Start Vk autoposting process'

        # Внимание!!! Нельзя публиковать чаще чем 1 раз в 90 минут, иначе Vk забанит
        allow_date = datetime.datetime.now() - datetime.timedelta(minutes=91)
        vkontakte_autoposting = VkAutoposting.objects.filter(
            (Q(last_posting_at__lt=allow_date)
             | Q(last_posting_at__isnull=True)) & Q(is_active=True))

        # access token
        response = requests.get('https://oauth.vk.com/access_token',
                                params={
                                    'client_id': settings.VK_APP_ID,
                                    'client_secret':
                                    settings.VK_APP_SECRET_KEY,
                                    'v': 5.62,
                                    'grant_type': 'client_credentials'
                                })

        access_token = response.json()['access_token']

        if vkontakte_autoposting.exists():
            for vk_autoposting in vkontakte_autoposting:
                translation.activate(vk_autoposting.language)

                print '  --> choose ad for Vk autoposting #%d' % vk_autoposting.id
                # Выбираем одно объявление по заданным параметрам, которое еще ни разу не публиковали
                ads = Ad.objects.filter(
                    deal_type=vk_autoposting.deal_type,
                    region__id__in=vk_autoposting.region.get_children_ids(),
                    is_published=True,
                    status=1,
                    vk_autoposting_ads__isnull=True,
                    has_photos=True).order_by('-created')

                ad = ads.filter(user__in=User.get_user_ids_with_active_ppk()
                                ).first() or ads.first()

                if ad:
                    print '    --> chosen ad #%d' % ad.pk
                    vk_session = vk_api.VkApi(
                        login=settings.VK_APP_LOGIN,
                        password=settings.VK_APP_PASSWORD,
                        token=access_token,
                        config_filename=os.path.join(settings.VAR_ROOT,
                                                     'vk_config.json'))

                    try:
                        vk_session.authorization()
                    except vk_api.AuthorizationError as e:
                        print '    --> error while posting ad', e.message
                        continue

                    vk = vk_session.get_api()
                    response = vk.wall.post(owner_id='-%s' %
                                            vk_autoposting.page_id,
                                            attachments=ad.get_absolute_url(),
                                            signed=0,
                                            from_group=1,
                                            guid=ad.pk,
                                            message=ad.get_absolute_url())

                    vk_autoposting.last_posting_at = datetime.datetime.now()
                    vk_autoposting.save()

                    VkAutopostingAd.objects.create(
                        vk_autoposting=vk_autoposting,
                        basead=ad.basead_ptr,
                        page_id=response['post_id'])
                    print '    --> success posting to Vk and mark Ad'

        print '<-- Finish Vk autoposting process'
示例#17
0
文件: views.py 项目: VadymRud/nedvizh
def realtors(request):
    title = _(u'Риелторы агентства')
    agency = request.own_agency
    if not agency:
        raise Http404

    # клик по кнопке "Показать статистику"
    if 'show-stats' in request.GET:
        return HttpResponseRedirect(
            reverse('agency_admin:stats') + '?%s' %
            urllib.urlencode({'realtor': request.GET.getlist('realtor')}, True)
        )

    if request.method == 'POST':
        add_form = AddRealtorForm(request.POST, request.FILES, agency=agency)
        if add_form.is_valid():
            with db_transaction.atomic():
                agency_realtor = Realtor.objects.filter(
                    is_admin=True, user=request.user).get()

                try:
                    user = User.objects.get(
                        email__iexact=add_form.cleaned_data['email'])
                except User.DoesNotExist:
                    user = add_form.save(commit=False)
                    user.username = User.make_unique_username(
                        add_form.cleaned_data['email'])
                    password = ''.join(
                        random.choice(string.digits) for i in xrange(8))
                    user.set_password(password)
                    user.save()
                    phone, created = Phone.objects.get_or_create(
                        number=add_form.cleaned_data['phone'])
                    UserPhone(user=user, phone=phone, order=1).save()
                else:
                    password = None

                new_realtor = Realtor(agency=agency_realtor.agency,
                                      user=user,
                                      is_active=False,
                                      confirmation_key=uuid.uuid4().hex)
                new_realtor.save()
                new_realtor.send_mail(password)
                new_realtor.send_message()

            add_form = AddRealtorForm(agency=agency)
            messages.info(
                request,
                _(u'Рилетор добавлен.<br/>Риелтору отправлено личное сообщений с ссылкой для подтверждения'
                  ),
                extra_tags='modal-dialog-w400 modal-success')
            return HttpResponseRedirect(reverse('agency_admin:realtors'))
        else:
            add_form.set_required()

    else:
        add_form = AddRealtorForm(agency=agency)
        add_form.set_required()

    # удаляем неугодных
    if 'delete' in request.GET:
        agency.realtors.filter(pk=request.GET['delete']).delete()

    # риелторы агентства
    realtors = agency.realtors.prefetch_related('user__phones').order_by(
        '-is_admin', 'pk')

    form = RieltorFilterForm(request.GET)
    if form.is_valid():
        if form.cleaned_data['search']:
            q = form.cleaned_data['search']
            search_filter = Q(user__first_name__icontains=q) | Q(
                user__last_name__icontains=q) | Q(user__email__icontains=q)
            realtors = realtors.filter(search_filter)

    paginator = HandyPaginator(realtors, 5, request=request)

    # статистика просмотров и входов
    for i, realtor in enumerate(paginator.current_page.object_list):
        try:
            paginator.current_page.object_list[i].stats = Stat.objects.filter(user=realtor.user).order_by().values('user')\
                .annotate(ad_views=Sum('ad_views'), ad_contacts_views=Sum('ad_contacts_views'), entrances=Sum('entrances'))[0]
        except IndexError:
            paginator.current_page.object_list[i].stats = None

    return render(request, 'agency/realtors.jinja.html', locals())