Skip to content

Commit

Permalink
Merepresenta complete profile candidate
Browse files Browse the repository at this point in the history
  • Loading branch information
lfalvarez committed Aug 3, 2018
1 parent 4c84342 commit 068ceba
Show file tree
Hide file tree
Showing 24 changed files with 570 additions and 76 deletions.
5 changes: 2 additions & 3 deletions backend_candidate/forms.py
Expand Up @@ -133,7 +133,7 @@ def _import(name):
for comp in components[1:]:
try:
mod = getattr(mod, comp)
except AttributeError:
except AttributeError as e:
raise ImportError
return mod

Expand Down Expand Up @@ -211,8 +211,7 @@ def get_candidate_profile_form_class():
if settings.THEME:
try:
PARENT_FORM_CLASS = _import(settings.THEME + ".forms.PersonalDataForm")

except ImportError:
except ImportError as e:
from votai_general_theme.forms import PersonalDataForm
PARENT_FORM_CLASS = PersonalDataForm
else:
Expand Down
7 changes: 7 additions & 0 deletions backend_candidate/models.py
Expand Up @@ -23,6 +23,13 @@ class Candidacy(models.Model):
null=True)


def get_complete_profile_url(self):
url = reverse('backend_candidate:complete_profile',
kwargs={'slug': self.candidate.election.slug,
'candidate_slug': self.candidate.slug})
return url


def is_candidate(user):
if not user.is_authenticated():
return False
Expand Down
9 changes: 9 additions & 0 deletions backend_candidate/tests/candidacy_tests.py
Expand Up @@ -267,6 +267,15 @@ def test_post_complete_12_naranja(self):
self.assertTrue(TakenPosition.objects.filter(person=self.candidate))
self.assertRedirects(response, url)

def test_candidacy_get_complete_profile_url(self):
candidacy = Candidacy.objects.create(user=self.feli,
candidate=self.candidate
)
url = reverse('backend_candidate:complete_profile',
kwargs={'slug': self.candidate.election.slug,
'candidate_slug': self.candidate.slug})
self.assertEquals(candidacy.get_complete_profile_url(), url)


class CandidacyContacts(CandidacyTestCaseBase):
def setUp(self):
Expand Down
9 changes: 5 additions & 4 deletions backend_candidate/views.py
Expand Up @@ -139,19 +139,20 @@ def get_redirect_url(self, *args, **kwargs):
return profile_url


class ProfileView(FormView):
class ProfileView(LoginRequiredMixin, FormView):
template_name = 'backend_candidate/complete_profile.html'
candidate_model = Candidate
election_model = Election

def get_form_class(self):
return get_candidate_profile_form_class()

@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
if not is_candidate(request.user):
raise Http404
self.user = request.user
self.election = get_object_or_404(Election, slug=self.kwargs['slug'])
self.candidate = get_object_or_404(Candidate,
self.election = get_object_or_404(self.election_model, slug=self.kwargs['slug'])
self.candidate = get_object_or_404(self.candidate_model,
slug=self.kwargs['candidate_slug'])
if not Candidacy.objects.filter(user=self.request.user, candidate=self.candidate).exists():
raise Http404
Expand Down
8 changes: 6 additions & 2 deletions backend_citizen/image_getter_from_social.py
@@ -1,4 +1,5 @@
from backend_citizen.tasks import save_image_to_user
from backend_citizen.tasks import _save_image_to_user, save_image_to_user
from django.conf import settings

def get_image_from_social(backend, strategy, details, response,
user=None, *args, **kwargs):
Expand All @@ -11,6 +12,9 @@ def get_image_from_social(backend, strategy, details, response,
ext = url.split('.')[-1]
if url:
try:
save_image_to_user.delay(url, user)
if settings.EAGER_USER_IMAGE:
_save_image_to_user(url, user)
else:
save_image_to_user.delay(url, user)
except Exception as e:
pass
10 changes: 7 additions & 3 deletions backend_citizen/tasks.py
Expand Up @@ -11,8 +11,12 @@ def image_getter(url):
return File(img_temp)


@app.task
def save_image_to_user(url, user):
def _save_image_to_user(url, user):
f = image_getter(url)
name = "profile_%s.jpg" % user.username
user.profile.image = f
user.profile.image.save(user.username, f)
user.profile.image.save(name, f)

@app.task
def save_image_to_user(url, user):
_save_image_to_user(url, user)
22 changes: 19 additions & 3 deletions merepresenta/candidatos/forms.py
Expand Up @@ -3,11 +3,11 @@
from backend_candidate.models import Candidacy
from merepresenta.models import Candidate


class CPFAndDdnForm(forms.Form):
class CPFAndDdnFormBase(forms.Form):
cpf = forms.CharField(required=True)
nascimento = forms.DateField(required=True, input_formats=['%d/%m/%Y','%d/%m/%y', '%d-%m-%Y', '%d-%m-%y',])

class CPFAndDdnForm(CPFAndDdnFormBase):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(CPFAndDdnForm, self).__init__(*args, **kwargs)
Expand All @@ -24,4 +24,20 @@ def clean(self):
return self.cleaned_data

def save(self):
return Candidacy.objects.create(user=self.user, candidate=self.candidate)
return Candidacy.objects.create(user=self.user, candidate=self.candidate)


class CPFAndDdnForm2(CPFAndDdnFormBase):
def clean(self):
cpf = self.cleaned_data['cpf']
ddn = self.cleaned_data.get('nascimento', None)
if ddn is None:
raise forms.ValidationError(u'Não encontramos o candidato')
try:
self.candidate = Candidate.objects.get(cpf=cpf, data_de_nascimento=ddn)
except Candidate.DoesNotExist:
raise forms.ValidationError(u'Não encontramos o candidato')
return self.cleaned_data

def get_candidate(self):
return self.candidate
5 changes: 5 additions & 0 deletions merepresenta/candidatos/strategy.py
@@ -1,6 +1,8 @@
from social_django.strategy import DjangoStrategy
from django.shortcuts import resolve_url
from django.contrib.auth import authenticate
from backend_candidate.models import Candidacy
from merepresenta.models import Candidate


class CandidateStrategy(DjangoStrategy):
Expand All @@ -12,6 +14,9 @@ def get_setting(self, name):

def create_user(self, *args, **kwargs):
user = super(CandidateStrategy, self).create_user(*args, **kwargs)
slug = self.session_get('facebook_slug')
c = Candidate.objects.get(slug=slug)
Candidacy.objects.create(user=user, candidate=c)
return user

def authenticate(self, backend, *args, **kwargs):
Expand Down
12 changes: 10 additions & 2 deletions merepresenta/candidatos/urls.py
Expand Up @@ -2,24 +2,32 @@
from django.conf.urls import url, include
from .views import (LoginView,
CPFAndDDNSelectView,
CPFAndDDNSelectView2,
CompleteProfileView,
complete,
auth
)


urlpatterns = [
url(r'^login/?$',
url(r'^login_after/?$',
LoginView.as_view(),
name='candidate_login'),

url(r'^cpf_e_ddn/?$',
CPFAndDDNSelectView.as_view(),
name='cpf_and_date'),
url(r'^login/?$',
CPFAndDDNSelectView2.as_view(),
name='cpf_and_date2'),
url(r'^profile/(?P<slug>[-\w]+)/(?P<candidate_slug>[-\w]+)/?$',
CompleteProfileView.as_view(),
name='merepresenta_complete_profile'),
url(r'^complete/(?P<backend>[^/]+)$',
complete,
name='candidate_social_complete'
),
url(r'^login/(?P<backend>[^/]+)/?$', auth,
url(r'^login/(?P<backend>[^/]+)/(?P<slug>[^/]+)?$', auth,
name='candidato_social_begin'),

]
59 changes: 49 additions & 10 deletions merepresenta/candidatos/views.py
Expand Up @@ -3,16 +3,22 @@
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponseNotFound, HttpResponseRedirect
from backend_candidate.models import Candidacy
from .forms import CPFAndDdnForm
from backend_candidate.views import ProfileView
from .forms import CPFAndDdnForm, CPFAndDdnForm2
from social_core.actions import do_complete, do_auth
from social_django.views import _do_login
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt
from social_django.utils import psa, STORAGE, get_strategy
from django.views.generic.base import TemplateView
from backend_candidate.models import is_candidate


from django.template.response import TemplateResponse
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from merepresenta.models import Candidate
from django.core.urlresolvers import reverse
from merepresenta.forms import PersonalDataForm

class LoginView(TemplateView):
template_name="candidatos/login.html"
Expand All @@ -37,7 +43,7 @@ def dispatch(self, *args, **kwargs):
c = Candidacy.objects.get(user=self.request.user)
election = c.candidate.election
candidate = c.candidate
url = reverse_lazy('backend_candidate:complete_profile', kwargs={'slug': election.slug, 'candidate_slug': candidate.slug})
url = reverse_lazy('merepresenta_complete_profile', kwargs={'slug': election.slug, 'candidate_slug': candidate.slug})
return HttpResponseRedirect(url)
except Candidacy.DoesNotExist:
pass
Expand All @@ -56,12 +62,29 @@ def form_valid(self, form):

def get_success_url(self):
c = Candidacy.objects.get(user=self.request.user)
election = c.candidate.election
candidate = c.candidate
url = reverse_lazy('backend_candidate:complete_profile', kwargs={'slug': election.slug, 'candidate_slug': candidate.slug})
return url
return c.get_complete_profile_url()


class CPFAndDDNSelectView2(FormView):
form_class = CPFAndDdnForm2
template_name = 'candidatos/cpf_and_ddn2.html'

def dispatch(self, *args, **kwargs):
if self.request.user.is_staff:
return HttpResponseNotFound()

if is_candidate(self.request.user):
user = self.request.user
candidacy = user.candidacies.first()
url = reverse_lazy('merepresenta_complete_profile', kwargs={'slug': candidacy.candidate.election.slug,
'candidate_slug': candidacy.candidate.slug})
return HttpResponseRedirect(url)
return super(CPFAndDDNSelectView2, self).dispatch(*args, **kwargs)

def form_valid(self, form):
self.candidate = form.get_candidate()
context = {'candidate': self.candidate}
return TemplateResponse(self.request, template='candidatos/login_with_facebook.html', context=context)

def load_strategy(request=None):
return get_strategy('merepresenta.candidatos.strategy.CandidateStrategy', STORAGE, request)
Expand All @@ -76,5 +99,21 @@ def complete(request, backend, *args, **kwargs):

@never_cache
@psa('candidate_social_complete')
def auth(request, backend):
return do_auth(request.backend)
def auth(request, backend, slug):
candidate = get_object_or_404(Candidate, slug=slug)
request.backend.strategy.session_set('facebook_slug', slug)
return do_auth(request.backend)


class CompleteProfileView(ProfileView):
candidate_model = Candidate

def get_form_class(self):
return PersonalDataForm

def get_success_url(self):
url = reverse('merepresenta_complete_profile',
kwargs={'slug': self.election.slug,
'candidate_slug': self.candidate.slug}
)
return url
63 changes: 61 additions & 2 deletions merepresenta/forms.py
Expand Up @@ -4,13 +4,72 @@
from popular_proposal.models import PopularProposal
from django.core.cache import cache
from django.conf import settings
from elections.models import Area, QuestionCategory
from elections.models import Area, QuestionCategory, PersonalData
from django.contrib.sites.models import Site
from medianaranja2.proposals_getter import ByOnlySiteProposalGetter
from merepresenta.models import MeRepresentaPopularProposal
from merepresenta.models import MeRepresentaPopularProposal, Candidate
from django.utils.safestring import mark_safe
from medianaranja2.adapters import Adapter as OriginalAdapter

GENDERS = [
('feminino', u"Feminino"),
('masculino', u"Masculino"),
('outro', u"Outro gênero"),
]
RACES = [
('BRANCA', u"Branca"),
('PRETA', u"Preta"),
('PARDA', u"Parda"),
('AMARELA', u"Amarela"),
('INDÍGENA', u"Indígena"),
]

class PersonalDataForm(forms.Form):
email = forms.EmailField(label=u"Para manter contato, quais desses e-mails você mais usa?")
gender = forms.ChoiceField(choices=GENDERS, label=u'Com qual desses gêneros você se identifica?')
lgbt = forms.BooleanField(label=u'Você se declara LGBT?')
race = forms.ChoiceField(label=u'Qual é a sua cor ou raça?', choices=RACES)
bio = forms.CharField(label=u"Escreva um pouco sobre você", widget=forms.TextInput)
candidatura_coletiva = forms.BooleanField(label=u'Você faz parte de uma Candidatura Coletiva?')
renovacao_politica = forms.CharField(label=u"Você faz parte de algum grupo de Renovação Política? Qual?")


def __init__(self, *args, **kwargs):
self.candidate = kwargs.pop('candidate')
initial = {}
if 'initial' in kwargs:
kwargs['initial'].update(initial)
else:
kwargs['initial'] = initial
personal_datas_as_dict = {}
for personal_data in self.candidate.personal_datas.all():
personal_datas_as_dict[personal_data.label] = personal_data.value

for field in self.__class__.base_fields:
candidate_has_field = hasattr(self.candidate, field)
if candidate_has_field:
value = getattr(self.candidate, field, None)
kwargs['initial'][field] = value
else:
kwargs['initial'][field] = personal_datas_as_dict.get(field, None)
super(PersonalDataForm, self).__init__(*args, **kwargs)


def save(self):

for f_name in self.cleaned_data:
if hasattr(self.candidate, f_name):
setattr(self.candidate, f_name, self.cleaned_data[f_name])
else:
personal_data, created = PersonalData.objects.get_or_create(candidate=self.candidate,
label=f_name)
personal_data.value = self.cleaned_data[f_name]
if personal_data.value is None:
personal_data.value = ''
personal_data.save()
self.candidate.save()
return self.candidate


class MeRepresentaProposalModelMultipleChoiceField(forms.ModelMultipleChoiceField):
template_name = 'merepresenta/checkbox_select.html'
Expand Down

0 comments on commit 068ceba

Please sign in to comment.