#ARC-25 Add pipeline for add email

remotes/origin/setup
Mukhtar 10 years ago
parent 83ae308d97
commit 678d9b4fed
  1. 60
      archilance/settings/base.py
  2. 2
      archilance/urls.py
  3. 51
      projects/templates/project_list.html
  4. 7
      requirements/base.txt
  5. 1
      templates/registration/login.html
  6. 41
      templates/registration/registration_form.html
  7. 2
      users/admin.py
  8. 38
      users/migrations/0019_auto_20160708_1653.py
  9. 17
      users/models.py
  10. 27
      users/pipeline.py
  11. 5
      users/templates/add_email_form.html
  12. 10
      users/templates/portfolio_create_form.html
  13. 6
      work_sell/templates/upload.html
  14. 2
      work_sell/urls.py
  15. 10
      work_sell/views.py

@ -31,6 +31,7 @@ DJANGO_APPS = [
THIRD_PARTY_APPS = [
'django_extensions',
'social.apps.django_app.default',
'mptt',
'registration',
'rest_framework',
@ -117,11 +118,67 @@ AUTH_PASSWORD_VALIDATORS = [
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
]
AUTHENTICATION_BACKENDS = (
'social.backends.facebook.FacebookOAuth2',
'social.backends.google.GoogleOAuth2',
'social.backends.twitter.TwitterOAuth',
'social.backends.vk.VKOAuth2',
'social.backends.odnoklassniki.OdnoklassnikiOAuth2',
'django.contrib.auth.backends.ModelBackend',
# 'guardian.backends.ObjectPermissionBackend',
)
# SOCIAL_AUTH_FACEBOOK_KEY = '222531191461451'
# SOCIAL_AUTH_FACEBOOK_SECRET = '95e88f7ef396c5b803375f8476cf2ba4'
SOCIAL_AUTH_FACEBOOK_KEY = '1030546170341186'
SOCIAL_AUTH_FACEBOOK_SECRET = '1b22e95040b209c5d2f2d7f69462bf95'
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'id,email',
}
SOCIAL_AUTH_ODNOKLASSNIKI_OAUTH2_KEY = '1247035904'
SOCIAL_AUTH_ODNOKLASSNIKI_OAUTH2_SECRET = '9AD83DB399405EEFAE7641BD'
SOCIAL_AUTH_ODNOKLASSNIKI_OAUTH2_PUBLIC_NAME = 'CBADEFFLEBABABABA'
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '499898042244-bt7v18v4f46k8qg98n1ne8u2hjtmj0cn.apps.googleusercontent.com'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 's69NCyhSlwY0OuGGT8_dFI7E'
SOCIAL_AUTH_TWITTER_KEY = 'YAe05K4IYYxHhA6J1mTOdDBjq'
SOCIAL_AUTH_TWITTER_SECRET = 'iRuYqRRaoGkCD4ip74NICb8FeZMxvM6MZ8HLMbm1jX99o7pcaL'
SOCIAL_AUTH_VK_OAUTH2_KEY = '5469025'
SOCIAL_AUTH_VK_OAUTH2_SECRET = '3Wild7HqYq6YFiLz9i7l'
SOCIAL_AUTH_VK_OAUTH2_SCOPE = [
'notify',
'friends',
'email',
]
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/'
SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/'
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
'social.pipeline.social_auth.social_user',
'social.pipeline.user.get_username',
'users.pipeline.add_email_for_user',
'users.pipeline.test_contractor',
'social.pipeline.mail.mail_validation',
'social.pipeline.user.create_user',
'social.pipeline.social_auth.associate_user',
'social.pipeline.social_auth.load_extra_data',
'social.pipeline.user.user_details',
)
FIELDS_STORED_IN_SESSION = ['user_type']
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
@ -155,6 +212,7 @@ ACCOUNT_ACTIVATION_DAYS = 7
REGISTRATION_AUTO_LOGIN = True
LOGIN_REDIRECT_URL = '/projects/'
if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'

@ -9,12 +9,14 @@ from .views import HomeTemplateView, TestChatTemplateView
urlpatterns = [
url(r'^$', HomeTemplateView.as_view()),
url('', include('social.apps.django_app.urls', namespace='social')),
url(r'^chattest$', TestChatTemplateView.as_view()),
url(r'^work_sell/', include('work_sell.urls')),
url(r'^test/$', TemplateView.as_view(template_name='test.html'), name='test'),
url(r'^projects/', include('projects.urls')),
url(r'^chat/', include('chat.urls')),
url(r'^specializations/', include('specializations.urls')),
url(r'^users/', include('registration.backends.default.urls')),
url(r'^users/', include('users.urls')),
url(r'^admin/', admin.site.urls),

@ -12,33 +12,26 @@
<div class="filter clearfix">
<div class="triangle1"></div>
<div class="titleF1 disTab">
<div class="col-lg-3">Тип работ:</div>
<div class="col-lg-3">Специализации:</div>
<div class="col-lg-3"></div>
<div class="col-lg-3"></div>
<div class="col-lg-3"></div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-1" style="width: 100%">
</div>
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-2" style="width: 100%">
</div>
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-3" style="width: 100%">
</div>
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-4" style="width: 100%">
</div>
</div>
<div class="searchF1">
<div class="col-lg-6">
<input type="text" class="searchInp box-sizing" placeholder="Ключевые слова" name="search">
@ -67,30 +60,28 @@
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab">
<div class="col-lg-3">Тип работ:</div>
<div class="col-lg-3">Специализации:</div>
<div class="col-lg-3"></div>
<div class="col-lg-3">Классификация здания</div>
<div class="col-lg-3">Вид строительства</div>
<div class="col-lg-3">Местоположение</div>
<div class="col-lg-3"></div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
<option></option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
</div>

@ -1,8 +1,10 @@
Django==1.9.6
Momoko==2.2.3
Pillow==3.2.0
PyJWT==1.4.0
Werkzeug==0.11.10
backports-abc==0.4
defusedxml==0.4.1
django-appconf==1.0.2
django-compressor==2.0
django-debug-toolbar==1.4
@ -17,12 +19,16 @@ djangorestframework==3.3.3
djangorestframework-filters==0.8.0
fake-factory==0.5.7
jsonschema==2.5.1
oauthlib==1.1.2
psycopg2==2.6.1
pydash==3.4.3
python-dateutil==2.5.3
python-social-auth==0.2.19
python3-openid==3.0.10
rcssmin==1.0.6
redis==2.10.5
requests==2.10.0
requests-oauthlib==0.6.1
rjsmin==1.0.12
six==1.10.0
sorl-thumbnail==12.3
@ -30,3 +36,4 @@ sqlparse==0.1.19
tornado==4.3

@ -5,6 +5,7 @@
<p class="titleScore">Вход на сайт</p>
</div>
<div class="form-regestration">
{{ form.errors }}
<form method="post">{% csrf_token %}
<div class="col-lg-12 select-reg">
<input type="text" name="{{ form.username.name }}" class="box-sizing email-reg" placeholder="Электронная почта">

@ -1,5 +1,6 @@
{% extends 'partials/base.html' %}
{% block content %}
{% include 'partials/header.html' %}
<div class="col-lg-12">
<p class="titleScore">Регистрация </p>
</div>
@ -14,6 +15,9 @@
{% endif %}
</div>
<div class="col-lg-12 select-reg">
<input type="text" name="{{ form.username.name }}" class="box-sizing email-reg" placeholder="Nickname">
</div>
<div class="col-lg-12 select-reg">
<input type="text" name="{{ form.email.name }}" class="box-sizing email-reg" placeholder="Электронная почта">
</div>
<div class="col-lg-12 select-reg">
@ -26,6 +30,43 @@
<div class="col-lg-12 select-reg">
<button class="reg-sub">Зарегистрироваться</button>
</div>
<div class="col-lg-12">
<div class="col-xs-12 text-center">
<div class="btn-group" role="group">
<div class="pull-left -social -fb">
<a href="{% url 'social:begin' 'facebook' %}?user_type=contractor">
<img src="http://nepesh.com/static/img/social/fb.png" alt="fb">
</a>
</div>
<div class="pull-left -social -tw">
<a href="{% url 'social:begin' 'twitter' %}">
<img src="http://nepesh.com/static/img/social/tw.png" alt="tw">
</a>
</div>
<div class="pull-left -social -gplus">
<a href="{% url 'social:begin' 'google-oauth2' %}">
<img src="http://nepesh.com/static/img/social/gplus.png" alt="gplus">
</a>
</div>
<div class="pull-left -social -vk">
<a href="{% url 'social:begin' 'vk-oauth2' %}">
<img src="http://nepesh.com/static/img/social/vk.png" alt="vk">
</a>
</div>
<div class="pull-left -social -ok">
<a href="{% url 'social:begin' 'odnoklassniki-oauth2' %}">
<img src="http://nepesh.com/static/img/social/ok.gif" alt="yt">
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-12 select-reg">
<div class="check-reg">
<label><input type="checkbox" name="check-reg"><span></span></label>

@ -5,7 +5,7 @@ from .models import User, Team, ContractorFinancialInfo
class UserAdmin(admin.ModelAdmin):
readonly_fields = ('pk',)
list_display = ('email', 'get_groups', 'cro', 'is_active',)
list_display = ('username', 'email', 'get_groups', 'cro', 'is_active',)
def get_groups(self, obj):
return ', '.join(g.name for g in obj.groups.all())

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-07-08 13:53
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
import django.utils.timezone
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('users', '0018_auto_20160630_1846'),
]
operations = [
# migrations.RemoveField(
# model_name='user',
# name='nickname',
# ),
# migrations.AddField(
# model_name='user',
# name='data_joined',
# field=models.DateTimeField(default=django.utils.timezone.now),
# ),
# migrations.AddField(
# model_name='user',
# name='username',
# field=models.CharField(default=datetime.datetime(2016, 7, 8, 13, 53, 51, 625003, tzinfo=utc), max_length=50, unique=True),
# preserve_default=False,
# ),
migrations.AlterField(
model_name='user',
name='date_of_birth',
field=models.DateTimeField(blank=True, null=True),
),
]

@ -8,17 +8,19 @@ from specializations.models import Specialization
class UserManager(BaseUserManager):
def create_user(self, email, password=None):
def create_user(self, username, email, password=None, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
if not email:
raise ValueError('Users must have an email address')
user = self.model(email=UserManager.normalize_email(email),)
user = self.model(username=username,
email=UserManager.normalize_email(email),)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
user = self.create_user(email, password)
def create_superuser(self, username, password):
user = self.create_user(username, "admin@exampletest.com", password)
user.is_superuser = True
user.save(using=self._db)
return user
@ -81,13 +83,14 @@ class User(AbstractBaseUser, PermissionsMixin):
('busy', 'Занят'),
)
nickname = models.CharField(max_length=50, blank=True,null=True)
username = models.CharField(max_length=50, unique=True)
first_name = models.CharField(max_length=255, blank=True)
last_name = models.CharField(max_length=255, blank=True)
patronym = models.CharField(max_length=255, blank=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(default=timezone.now)
data_joined = models.DateTimeField(default=timezone.now)
last_time_visit = models.DateTimeField(default=timezone.now)
contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True)
contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES)
@ -97,7 +100,7 @@ class User(AbstractBaseUser, PermissionsMixin):
gender = models.CharField(max_length=30, choices=GENDERS, blank=True)
cro = models.BooleanField(default=False)
website = models.CharField(max_length=255, blank=True)
date_of_birth = models.DateTimeField()
date_of_birth = models.DateTimeField(null=True,blank=True)
avatar = models.ImageField(upload_to='users/avatars/', blank=True)
phone = models.CharField(max_length=30, blank=True, null=True)
@ -121,7 +124,7 @@ class User(AbstractBaseUser, PermissionsMixin):
def get_profile_image(self):
return self.avatar
USERNAME_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
objects = UserManager()
contractor_objects = ContractorUserManager()

@ -0,0 +1,27 @@
from django.shortcuts import redirect, render_to_response
from social.pipeline.partial import partial
@partial
def test_contractor(backend, details, response, is_new=False, *args, **kwargs):
import code; code.interact(local=dict(globals(), **locals()))
@partial
def add_email_for_user(backend, details, response, is_new=False, *args, **kwargs):
data = backend.strategy.request_data()
if details.get('contractor') is None:
return render_to_response('add_email_form.html')
else:
return {'contractor': details.get('contractor')}
@partial
def require_email(strategy, details, user=None, is_new=False, *args, **kwargs):
if kwargs.get('ajax') or user and user.email:
return
elif is_new and not details.get('email'):
email = strategy.request_data().get('email')
if email:
details['email'] = email
else:
return redirect('require_email')

@ -0,0 +1,5 @@
<h1>Введите свой email</h1>
<form method="post">
<input type="text" name="contractor">
<input type="submit" value="Send">
</form>

@ -40,10 +40,10 @@
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Бюджет{{ portfolio_form.budget.errors.as_text }}</p>
<div class="row">
<div class="col-lg-8">
<div class="col-lg-6">
<input type="text" class="box-sizing" name="{{ form.budget.html_name }}" value="{{ form.budget.value }}">
</div>
<div class="col-lg-4">
<div class="col-lg-6">
{{ portfolio_form.currency}}
</div>
</div>
@ -52,10 +52,10 @@
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Срок выполнения{{ portfolio_form.budget.errors.as_text }}</p>
<div class="row">
<div class="col-lg-8">
<div class="col-lg-6">
<input type="text" class="box-sizing" name="{{ form.budget.html_name }}" value="{{ form.budget.value }}">
</div>
<div class="col-lg-4">
<div class="col-lg-6">
{{ portfolio_form.term_type }}
</div>
</div>
@ -73,7 +73,7 @@
</div>
<div class="polsF1 polsF2 disTab">
<input type="text" name="{{ portfolio_form.user.html_name }}" value="{{ request.user.pk }}" />
<input type="hidden" name="{{ portfolio_form.user.html_name }}" value="{{ request.user.pk }}" />
</div>
<div class="polsF1 polsF2 disTab">

@ -0,0 +1,6 @@
{% extends 'partials/base.html' %}
{% block content %}
<h1>Upload Files</h1>
{% endblock %}

@ -6,6 +6,7 @@ from .views import (
WorkSellCreateView,
WorkSellUpdateView,
WorkSellDeleteView,
UploadView,
work_sell_create,
)
@ -14,6 +15,7 @@ app_name = 'work_sell'
urlpatterns = [
urls.url(r'^$', WorkSellsView.as_view(), name='list'),
urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'),
urls.url(r'^upload/$', UploadView.as_view(), name='upload'),
urls.url(r'^(?P<pk>\d+)/edit/$',WorkSellUpdateView.as_view(), name='edit'),
urls.url(r'^(?P<pk>\d+)/delete/$',WorkSellDeleteView.as_view(), name='delete'),
urls.url(r'^test/$', work_sell_create, name='test'),

@ -2,7 +2,8 @@ import json
from django.shortcuts import render
from django.core.urlresolvers import reverse
from django.http import JsonResponse, HttpResponse
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView, TemplateView
from django.views.generic import ListView, DetailView, CreateView, View,\
UpdateView, DeleteView, TemplateView
from projects.models import BuildingClassfication, ConstructionType
from .models import WorkSell
@ -75,6 +76,13 @@ class WorkSellDeleteView(DeleteView):
return reverse('work_sell:list')
class UploadView(View):
template_name = 'upload.html'
def get(self, request, *args, **kwargs):
return render(request,self.template_name)
class JSONResponseMixin(object):
def render_to_json_response(self, context, **response_kwargs):
return JsonResponse(

Loading…
Cancel
Save