Browse Source

Merge branch 'master' into 738-refatorar-proposicoes

pull/752/head
LeandroRoberto 8 years ago
parent
commit
cc09987888
  1. 2
      README.rst
  2. 14
      sapl/base/forms.py
  3. 7
      sapl/base/urls.py
  4. 162
      sapl/base/views.py
  5. 5
      sapl/materia/urls.py
  6. 27
      sapl/materia/views.py
  7. 0
      sapl/templates/email/confirma.html
  8. 2
      sapl/templates/materia/layouts.yaml
  9. 4
      sapl/templates/materia/materialegislativa_filter.html
  10. 5
      sapl/templates/materia/materialegislativa_form.html
  11. 24
      sapl/templates/painel/index.html
  12. 5
      sapl/test_urls.py

2
README.rst

@ -31,7 +31,7 @@ Instalar as seguintes dependências do sistema::
sudo apt-get install git nginx python3-dev libpq-dev graphviz-dev graphviz \
pkg-config postgresql postgresql-contrib pgadmin3 python-psycopg2 \
software-properties-common build-essential libxml2-dev libjpeg-dev \
libssl-dev libffi-dev libxslt1-dev python3-setuptools curl
libmysqlclient-dev libssl-dev libffi-dev libxslt1-dev python3-setuptools curl
sudo easy_install3 pip lxml

14
sapl/base/forms.py

@ -273,12 +273,13 @@ class AutorForm(ModelForm):
msg = _('Os emails não conferem.')
self.valida_igualdade(cd['email'], cd['confirma_email'], msg)
if qs_user.filter(email=cd['email']).exists():
raise ValidationError(_('Este email já foi cadastrado.'))
if not settings.DEBUG:
if qs_user.filter(email=cd['email']).exists():
raise ValidationError(_('Este email já foi cadastrado.'))
if qs_autor.filter(user__email=cd['email']).exists():
raise ValidationError(
_('Já existe um Autor com este email.'))
if qs_autor.filter(user__email=cd['email']).exists():
raise ValidationError(
_('Já existe um Autor com este email.'))
elif cd['action_user'] == 'A':
if not User.objects.filter(username=cd['username']).exists():
@ -390,8 +391,7 @@ class AutorForm(ModelForm):
user_old.groups.remove(grupo)
elif user_old:
user_old.groups.remove(grupo)
else:
elif user_old:
user_old.groups.remove(grupo)
return autor

7
sapl/base/urls.py

@ -3,7 +3,7 @@ from django.contrib.auth import views
from django.contrib.auth.decorators import permission_required
from django.views.generic.base import TemplateView
from sapl.base.views import AutorCrud, TipoAutorCrud
from sapl.base.views import AutorCrud, TipoAutorCrud, ConfirmarEmailView
from .apps import AppConfig
from .forms import LoginForm
@ -52,6 +52,11 @@ urlpatterns = [
RelatorioAtasView.as_view(),
name='atas'),
url(r'^email/validate/(?P<uidb64>[0-9A-Za-z_\-]+)/'
'(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})$',
ConfirmarEmailView.as_view(), name='confirmar_email'),
# todos os sublink s de sistema devem vir acima deste
url(r'^sistema/', permission_required('base.view_tabelas_auxiliares')
(TemplateView.as_view(template_name='sistema.html'))),

162
sapl/base/views.py

@ -1,5 +1,6 @@
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.models import Group
from django.contrib.auth.tokens import default_token_generator
@ -8,7 +9,7 @@ from django.core.urlresolvers import reverse
from django.db.models import Count, Q
from django.http import HttpResponseRedirect
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView
from django_filters.views import FilterView
@ -21,6 +22,7 @@ from sapl.crud.base import CrudAux
from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
from sapl.parlamentares.models import Parlamentar
from sapl.sessao.models import OrdemDia, SessaoPlenaria
from sapl.utils import sapl_logger
from .forms import (CasaLegislativaForm, ConfiguracoesAppForm,
RelatorioAtasFilterSet,
@ -36,6 +38,18 @@ def get_casalegislativa():
return CasaLegislativa.objects.first()
class ConfirmarEmailView(TemplateView):
template_name = "email/confirma.html"
def get(self, request, *args, **kwargs):
uid = urlsafe_base64_decode(self.kwargs['uidb64'])
user = get_user_model().objects.get(id=uid)
user.is_active = True
user.save()
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
class TipoAutorCrud(CrudAux):
model = TipoAutor
help_path = 'tipo-autor'
@ -57,9 +71,11 @@ class AutorCrud(CrudAux):
def delete(self, *args, **kwargs):
self.object = self.get_object()
# FIXME melhorar captura de grupo de Autor, levando em conta trad
grupo = Group.objects.filter(name='Autor')[0]
self.object.user.groups.remove(grupo)
if self.object.user:
# FIXME melhorar captura de grupo de Autor, levando em conta
# trad
grupo = Group.objects.filter(name='Autor')[0]
self.object.user.groups.remove(grupo)
return CrudAux.DeleteView.delete(self, *args, **kwargs)
@ -67,50 +83,65 @@ class AutorCrud(CrudAux):
layout_key = None
form_class = AutorForm
def form_valid(self, form):
# devido a implement do form o form_valid do Crud deve ser pulado
return super(CrudAux.UpdateView, self).form_valid(form)
def post(self, request, *args, **kwargs):
if request.user.is_superuser:
self.form_class = AutorFormForAdmin
return CrudAux.UpdateView.post(self, request, *args, **kwargs)
def get(self, request, *args, **kwargs):
if request.user.is_superuser:
self.form_class = AutorFormForAdmin
return CrudAux.UpdateView.get(self, request, *args, **kwargs)
def get_success_url(self):
# FIXME try except - testar envio de emails
pk_autor = self.object.id
kwargs = {}
user = self.object.user
"""if user.is_active:
return reverse('sapl.base:autor_detail',
kwargs={'pk': pk_autor})"""
kwargs['token'] = default_token_generator.make_token(user)
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
url_base = full_url[:full_url.find('sistema') - 1]
mensagem = (
"Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " +
"criar/editar/enviar Proposições.\n" +
"Seu nome de usuário é: " +
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " +
"ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
reverse('sapl.materia:confirmar_email', kwargs=kwargs))
remetente = [settings.EMAIL_SEND_USER]
destinatario = [user.email]
send_mail(assunto, mensagem, remetente, destinatario,
fail_silently=False)
return reverse('sapl.base:autor_detail',
kwargs={'pk': pk_autor})
url_reverse = reverse('sapl.base:autor_detail',
kwargs={'pk': pk_autor})
try:
kwargs = {}
user = self.object.user
if not user:
return url_reverse
kwargs['token'] = default_token_generator.make_token(user)
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
url_base = full_url[:full_url.find('sistema') - 1]
mensagem = (
"Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " +
"criar/editar/enviar Proposições.\n" +
"Seu nome de usuário é: " +
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " +
"ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
reverse('sapl.base:confirmar_email', kwargs=kwargs))
remetente = [settings.EMAIL_SEND_USER]
destinatario = [user.email]
send_mail(assunto, mensagem, remetente, destinatario,
fail_silently=False)
except:
sapl_logger.error(
_('Erro no envio de email na edição de Autores.'))
return url_reverse
class CreateView(CrudAux.CreateView):
form_class = AutorForm
layout_key = None
def post(self, request, *args, **kwargs):
if request.user.is_superuser:
self.form_class = AutorFormForAdmin
return CrudAux.CreateView.post(self, request, *args, **kwargs)
def get(self, request, *args, **kwargs):
if request.user.is_superuser:
self.form_class = AutorFormForAdmin
@ -118,32 +149,39 @@ class AutorCrud(CrudAux):
def get_success_url(self):
pk_autor = self.object.id
# FIXME try except - testar envio de emails
kwargs = {}
user = self.object.user
kwargs['token'] = default_token_generator.make_token(user)
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
url_base = full_url[:full_url.find('sistema') - 1]
mensagem = (
"Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " +
"criar/editar/enviar Proposições.\n" +
"Seu nome de usuário é: " +
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " +
"ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
reverse('sapl.materia:confirmar_email', kwargs=kwargs))
remetente = settings.EMAIL_SEND_USER
destinatario = [user.email]
send_mail(assunto, mensagem, remetente, destinatario,
fail_silently=False)
return reverse('sapl.base:autor_detail',
kwargs={'pk': pk_autor})
url_reverse = reverse('sapl.base:autor_detail',
kwargs={'pk': pk_autor})
try:
kwargs = {}
user = self.object.user
if not user:
return url_reverse
kwargs['token'] = default_token_generator.make_token(user)
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
url_base = full_url[:full_url.find('sistema') - 1]
mensagem = (
"Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " +
"criar/editar/enviar Proposições.\n" +
"Seu nome de usuário é: " +
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " +
"ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
reverse('sapl.base:confirmar_email', kwargs=kwargs))
remetente = [settings.EMAIL_SEND_USER]
destinatario = [user.email]
send_mail(assunto, mensagem, remetente, destinatario,
fail_silently=False)
except:
sapl_logger.error(
_('Erro no envio de email na criação de Autores.'))
return url_reverse
class RelatorioAtasView(FilterView):

5
sapl/materia/urls.py

@ -3,7 +3,7 @@ from django.conf.urls import include, url
from sapl.materia.views import (AcompanhamentoConfirmarView,
AcompanhamentoExcluirView,
AcompanhamentoMateriaView, AnexadaCrud,
AutoriaCrud, ConfirmarEmailView,
AutoriaCrud,
ConfirmarProposicao, DespachoInicialCrud,
DocumentoAcessorioCrud,
DocumentoAcessorioEmLoteView,
@ -39,9 +39,6 @@ urlpatterns_materia = [
url(r'^materia/(?P<pk>[0-9]+)/ta$',
MateriaTaView.as_view(), name='materia_ta'),
url(r'^materia/confirmar/(?P<uidb64>[0-9A-Za-z_\-]+)/'
'(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})$',
ConfirmarEmailView.as_view(), name='confirmar_email'),
url(r'^materia/pesquisar-materia$',
MateriaLegislativaPesquisaView.as_view(), name='pesquisar_materia'),

27
sapl/materia/views.py

@ -106,28 +106,23 @@ class ProposicaoTaView(IntegracaoTaView):
@permission_required_for_app(app_label=apps.AppConfig.label)
def recuperar_materia(request):
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo'])
materia = MateriaLegislativa.objects.filter(tipo=tipo).last()
ano = request.GET.get('ano', '')
param = {'tipo': tipo}
param['data_apresentacao__year'] = ano if ano else datetime.now().year
materia = MateriaLegislativa.objects.filter(**param).order_by(
'tipo', 'ano', 'numero').values_list('numero', 'ano').last()
if materia:
response = JsonResponse({'numero': materia.numero + 1,
'ano': datetime.now().year})
response = JsonResponse({'numero': materia[0] + 1,
'ano': materia[1]})
else:
response = JsonResponse({'numero': 1, 'ano': datetime.now().year})
response = JsonResponse(
{'numero': 1, 'ano': ano if ano else datetime.now().year})
return response
class ConfirmarEmailView(TemplateView):
template_name = "confirma_email.html"
def get(self, request, *args, **kwargs):
uid = urlsafe_base64_decode(self.kwargs['uidb64'])
user = get_user_model().objects.get(id=uid)
user.is_active = True
user.save()
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
OrgaoCrud = CrudAux.build(Orgao, 'orgao')
StatusTramitacaoCrud = CrudAux.build(StatusTramitacao, 'status_tramitacao')
UnidadeTramitacaoCrud = CrudAux.build(UnidadeTramitacao, 'unidade_tramitacao')

0
sapl/templates/confirma_email.html → sapl/templates/email/confirma.html

2
sapl/templates/materia/layouts.yaml

@ -21,7 +21,7 @@ TipoFimRelatoria:
MateriaLegislativa:
{% trans 'Identificação Básica' %}:
- tipo numero ano
- tipo ano numero
- data_apresentacao numero_protocolo tipo_apresentacao
- texto_original
{% trans 'Outras Informações' %}:

4
sapl/templates/materia/materialegislativa_filter.html

@ -50,11 +50,11 @@
{% if m.registrovotacao_set.exists %}
<strong>Data Votação:</strong>
{% if m.registrovotacao_set.last.ordem %}
<a href="{% url 'sapl.sessao:sessaoplenaria_detail' m.registrovotacao_set.last.ordem.sessao_plenaria_id %}">
<a href="{% url 'sapl.sessao:ordemdia_list' m.registrovotacao_set.last.ordem.sessao_plenaria_id %}">
{{ m.registrovotacao_set.last.ordem.data_ordem }}
</a>
{% elif m.registrovotacao_set.last.expediente %}
<a href="{% url 'sapl.sessao:sessaoplenaria_detail' m.registrovotacao_set.last.expediente.sessao_plenaria_id %}">
<a href="{% url 'sapl.sessao:expedientemateria_list' m.registrovotacao_set.last.expediente.sessao_plenaria_id %}">
{{ m.registrovotacao_set.last.expediente.data_ordem }}
</a>
{% endif %}

5
sapl/templates/materia/materialegislativa_form.html

@ -10,9 +10,10 @@
function recuperar_numero_ano() {
var tipo = $("#id_tipo").val()
var ano = $("#id_ano").val()
if (tipo) {
$.get("/materia/recuperar-materia",{tipo: tipo},
$.get("/materia/recuperar-materia",{tipo: tipo, ano: ano},
function(data, status) {
$("#id_numero").val(data.numero);
$("#id_ano").val(data.ano);
@ -20,7 +21,7 @@
});
}
}
$("#id_tipo").change(recuperar_numero_ano);
$("#id_tipo, #id_ano").change(recuperar_numero_ano);
</script>
{% endblock %}

24
sapl/templates/painel/index.html

@ -21,6 +21,10 @@
ul, li {
list-style-type: none;
}
#sessao_plenaria, #sessao_plenaria_data, #sessao_plenaria_hora_inicio, #message, #cronometro_discurso, #cronometro_aparte, #cronometro_ordem, #relogio, #parlamentares, #votacao, #materia_legislativa_texto, #observacao_materia, #resultado_votacao{
font-family: Verdana;
}
}
</style>
</head>
@ -39,26 +43,26 @@
<h2><font color="red"><p align="center"><span id="message"></span></p></font></h2>
<font color="white"><p align="center">-----------------------------------------------</p></font>
<h3><font color="white"><p align="center">________________________________________________</p></font></h3>
<h3><font color="white"><p align="center"><span id="relogio"></span></p></font></h3>
<font color="white"><p align="center">-----------------------------------------------</p></font>
<h3><font color="white"><p align="center">________________________________________________</p></font></h3>
<h3><font color="#459170"><p align="center">Cronômetros</p></font></h3>
<h3><font color="#459170"><p style="font-family:Verdana" align="center">Cronômetros</p></font></h3>
<table style="width:100%">
<tr>
<th style="text-align:center"><font color="white">Discurso: <span id="cronometro_discurso"></span></font></th>
<th style="text-align:center; font-family:Verdana"><font color="white">Discurso: <span id="cronometro_discurso"></span></font></th>
</tr>
<tr>
<th style="text-align:center"><font color="white">Aparte: <span id="cronometro_aparte"></span></font></th>
<th style="text-align:center; font-family:Verdana"><font color="white">Aparte: <span id="cronometro_aparte"></span></font></th>
</tr>
<tr>
<th style="text-align:center"><font color="white">Questão de Ordem: <span id="cronometro_ordem"></span></font></th>
<th style="text-align:center; font-family:Verdana"><font color="white">Questão de Ordem: <span id="cronometro_ordem"></span></font></th>
</tr>
</table>
<h3><font color="white"><p align="center">-----------------------------------------------</p></font></h3>
<h3><font color="white"><p align="center">________________________________________________</p></font></h3>
<h3><font color="#459170"><p align="center">Parlamentares e Votos</p></font></h3>
<h3><font color="#459170"><p style="font-family:Verdana" align="center">Parlamentares e Votos</p></font></h3>
<table style="width:60%" align="center">
<tr>
<th style="text-align:left"><font color="white" align="left"><span id="parlamentares"></span></font></th>
@ -66,9 +70,9 @@
</tr>
</table>
<h3><font color="white"><p align="center">-----------------------------------------------</p></font></h3>
<h3><font color="white"><p align="center">________________________________________________</p></font></h3>
<h3><font color="#459170"><p align="center">Matéria em Votação</p></font></h3>
<h3><font color="#459170"><p align="center" style="font-family:Verdana">Matéria em Votação</p></font></h3>
<table style="width:100%; border:1px;">
<tr><th style="text-align:center"><font color="white"><span id="materia_legislativa_texto"></span></font></th></tr>
<tr><th style="text-align:center"><font color="white"><span id="observacao_materia"></span></font></th></tr>

5
sapl/test_urls.py

@ -159,7 +159,8 @@ apps_url_patterns_prefixs_and_users = {
'/sistema',
'/login',
'/logout',
'/ajuda'
'/ajuda',
'/email',
]},
'comissoes': {
'users': {'operador_geral': ['/sistema', '/comissao'],
@ -312,7 +313,7 @@ urls_publicas_excecoes = {
'/sistema/ajuda/',
'/ajuda/',
'/materia/confirmar/1/1',
'/email/validate/1/1',
'/materia/pesquisar-materia',
# usado na edição de matérias mas com restrição irrelevante

Loading…
Cancel
Save