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 \ sudo apt-get install git nginx python3-dev libpq-dev graphviz-dev graphviz \
pkg-config postgresql postgresql-contrib pgadmin3 python-psycopg2 \ pkg-config postgresql postgresql-contrib pgadmin3 python-psycopg2 \
software-properties-common build-essential libxml2-dev libjpeg-dev \ 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 sudo easy_install3 pip lxml

14
sapl/base/forms.py

@ -273,12 +273,13 @@ class AutorForm(ModelForm):
msg = _('Os emails não conferem.') msg = _('Os emails não conferem.')
self.valida_igualdade(cd['email'], cd['confirma_email'], msg) self.valida_igualdade(cd['email'], cd['confirma_email'], msg)
if qs_user.filter(email=cd['email']).exists(): if not settings.DEBUG:
raise ValidationError(_('Este email já foi cadastrado.')) if qs_user.filter(email=cd['email']).exists():
raise ValidationError(_('Este email já foi cadastrado.'))
if qs_autor.filter(user__email=cd['email']).exists(): if qs_autor.filter(user__email=cd['email']).exists():
raise ValidationError( raise ValidationError(
_('Já existe um Autor com este email.')) _('Já existe um Autor com este email.'))
elif cd['action_user'] == 'A': elif cd['action_user'] == 'A':
if not User.objects.filter(username=cd['username']).exists(): if not User.objects.filter(username=cd['username']).exists():
@ -390,8 +391,7 @@ class AutorForm(ModelForm):
user_old.groups.remove(grupo) user_old.groups.remove(grupo)
elif user_old: elif user_old:
user_old.groups.remove(grupo) user_old.groups.remove(grupo)
else: elif user_old:
user_old.groups.remove(grupo) user_old.groups.remove(grupo)
return autor 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.contrib.auth.decorators import permission_required
from django.views.generic.base import TemplateView 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 .apps import AppConfig
from .forms import LoginForm from .forms import LoginForm
@ -52,6 +52,11 @@ urlpatterns = [
RelatorioAtasView.as_view(), RelatorioAtasView.as_view(),
name='atas'), 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 # todos os sublink s de sistema devem vir acima deste
url(r'^sistema/', permission_required('base.view_tabelas_auxiliares') url(r'^sistema/', permission_required('base.view_tabelas_auxiliares')
(TemplateView.as_view(template_name='sistema.html'))), (TemplateView.as_view(template_name='sistema.html'))),

162
sapl/base/views.py

@ -1,5 +1,6 @@
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.contrib.auth.tokens import default_token_generator 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.db.models import Count, Q
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.encoding import force_bytes 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.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django_filters.views import FilterView 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.materia.models import MateriaLegislativa, TipoMateriaLegislativa
from sapl.parlamentares.models import Parlamentar from sapl.parlamentares.models import Parlamentar
from sapl.sessao.models import OrdemDia, SessaoPlenaria from sapl.sessao.models import OrdemDia, SessaoPlenaria
from sapl.utils import sapl_logger
from .forms import (CasaLegislativaForm, ConfiguracoesAppForm, from .forms import (CasaLegislativaForm, ConfiguracoesAppForm,
RelatorioAtasFilterSet, RelatorioAtasFilterSet,
@ -36,6 +38,18 @@ def get_casalegislativa():
return CasaLegislativa.objects.first() 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): class TipoAutorCrud(CrudAux):
model = TipoAutor model = TipoAutor
help_path = 'tipo-autor' help_path = 'tipo-autor'
@ -57,9 +71,11 @@ class AutorCrud(CrudAux):
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
# FIXME melhorar captura de grupo de Autor, levando em conta trad if self.object.user:
grupo = Group.objects.filter(name='Autor')[0] # FIXME melhorar captura de grupo de Autor, levando em conta
self.object.user.groups.remove(grupo) # trad
grupo = Group.objects.filter(name='Autor')[0]
self.object.user.groups.remove(grupo)
return CrudAux.DeleteView.delete(self, *args, **kwargs) return CrudAux.DeleteView.delete(self, *args, **kwargs)
@ -67,50 +83,65 @@ class AutorCrud(CrudAux):
layout_key = None layout_key = None
form_class = AutorForm 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): def get(self, request, *args, **kwargs):
if request.user.is_superuser: if request.user.is_superuser:
self.form_class = AutorFormForAdmin self.form_class = AutorFormForAdmin
return CrudAux.UpdateView.get(self, request, *args, **kwargs) return CrudAux.UpdateView.get(self, request, *args, **kwargs)
def get_success_url(self): def get_success_url(self):
# FIXME try except - testar envio de emails
pk_autor = self.object.id pk_autor = self.object.id
kwargs = {} url_reverse = reverse('sapl.base:autor_detail',
user = self.object.user kwargs={'pk': pk_autor})
try:
"""if user.is_active: kwargs = {}
return reverse('sapl.base:autor_detail', user = self.object.user
kwargs={'pk': pk_autor})"""
if not user:
kwargs['token'] = default_token_generator.make_token(user) return url_reverse
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta" kwargs['token'] = default_token_generator.make_token(user)
full_url = self.request.get_raw_uri() kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
url_base = full_url[:full_url.find('sistema') - 1] assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
mensagem = ( url_base = full_url[:full_url.find('sistema') - 1]
"Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " + mensagem = (
"criar/editar/enviar Proposições.\n" + "Este e-mail foi utilizado para fazer cadastro no " +
"Seu nome de usuário é: " + "SAPL com o perfil de Autor. Agora você pode " +
self.request.POST['username'] + "\n" "criar/editar/enviar Proposições.\n" +
"Caso você não tenha feito este cadastro, por favor " + "Seu nome de usuário é: " +
"ignore esta mensagem. Caso tenha, clique " + self.request.POST['username'] + "\n"
"no link abaixo\n" + url_base + "Caso você não tenha feito este cadastro, por favor " +
reverse('sapl.materia:confirmar_email', kwargs=kwargs)) "ignore esta mensagem. Caso tenha, clique " +
remetente = [settings.EMAIL_SEND_USER] "no link abaixo\n" + url_base +
destinatario = [user.email] reverse('sapl.base:confirmar_email', kwargs=kwargs))
send_mail(assunto, mensagem, remetente, destinatario, remetente = [settings.EMAIL_SEND_USER]
fail_silently=False) destinatario = [user.email]
return reverse('sapl.base:autor_detail', send_mail(assunto, mensagem, remetente, destinatario,
kwargs={'pk': pk_autor}) fail_silently=False)
except:
sapl_logger.error(
_('Erro no envio de email na edição de Autores.'))
return url_reverse
class CreateView(CrudAux.CreateView): class CreateView(CrudAux.CreateView):
form_class = AutorForm form_class = AutorForm
layout_key = None 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): def get(self, request, *args, **kwargs):
if request.user.is_superuser: if request.user.is_superuser:
self.form_class = AutorFormForAdmin self.form_class = AutorFormForAdmin
@ -118,32 +149,39 @@ class AutorCrud(CrudAux):
def get_success_url(self): def get_success_url(self):
pk_autor = self.object.id pk_autor = self.object.id
# FIXME try except - testar envio de emails url_reverse = reverse('sapl.base:autor_detail',
kwargs = {} kwargs={'pk': pk_autor})
user = self.object.user try:
kwargs['token'] = default_token_generator.make_token(user) kwargs = {}
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk)) user = self.object.user
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri() if not user:
url_base = full_url[:full_url.find('sistema') - 1] return url_reverse
mensagem = ( kwargs['token'] = default_token_generator.make_token(user)
"Este e-mail foi utilizado para fazer cadastro no " + kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
"SAPL com o perfil de Autor. Agora você pode " + assunto = "SAPL - Confirmação de Conta"
"criar/editar/enviar Proposições.\n" + full_url = self.request.get_raw_uri()
"Seu nome de usuário é: " + url_base = full_url[:full_url.find('sistema') - 1]
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " + mensagem = (
"ignore esta mensagem. Caso tenha, clique " + "Este e-mail foi utilizado para fazer cadastro no " +
"no link abaixo\n" + url_base + "SAPL com o perfil de Autor. Agora você pode " +
reverse('sapl.materia:confirmar_email', kwargs=kwargs)) "criar/editar/enviar Proposições.\n" +
remetente = settings.EMAIL_SEND_USER "Seu nome de usuário é: " +
destinatario = [user.email] self.request.POST['username'] + "\n"
send_mail(assunto, mensagem, remetente, destinatario, "Caso você não tenha feito este cadastro, por favor " +
fail_silently=False) "ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
return reverse('sapl.base:autor_detail', reverse('sapl.base:confirmar_email', kwargs=kwargs))
kwargs={'pk': pk_autor}) 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): 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, from sapl.materia.views import (AcompanhamentoConfirmarView,
AcompanhamentoExcluirView, AcompanhamentoExcluirView,
AcompanhamentoMateriaView, AnexadaCrud, AcompanhamentoMateriaView, AnexadaCrud,
AutoriaCrud, ConfirmarEmailView, AutoriaCrud,
ConfirmarProposicao, DespachoInicialCrud, ConfirmarProposicao, DespachoInicialCrud,
DocumentoAcessorioCrud, DocumentoAcessorioCrud,
DocumentoAcessorioEmLoteView, DocumentoAcessorioEmLoteView,
@ -39,9 +39,6 @@ urlpatterns_materia = [
url(r'^materia/(?P<pk>[0-9]+)/ta$', url(r'^materia/(?P<pk>[0-9]+)/ta$',
MateriaTaView.as_view(), name='materia_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$', url(r'^materia/pesquisar-materia$',
MateriaLegislativaPesquisaView.as_view(), name='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) @permission_required_for_app(app_label=apps.AppConfig.label)
def recuperar_materia(request): def recuperar_materia(request):
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo']) 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: if materia:
response = JsonResponse({'numero': materia.numero + 1, response = JsonResponse({'numero': materia[0] + 1,
'ano': datetime.now().year}) 'ano': materia[1]})
else: else:
response = JsonResponse({'numero': 1, 'ano': datetime.now().year}) response = JsonResponse(
{'numero': 1, 'ano': ano if ano else datetime.now().year})
return response 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') OrgaoCrud = CrudAux.build(Orgao, 'orgao')
StatusTramitacaoCrud = CrudAux.build(StatusTramitacao, 'status_tramitacao') StatusTramitacaoCrud = CrudAux.build(StatusTramitacao, 'status_tramitacao')
UnidadeTramitacaoCrud = CrudAux.build(UnidadeTramitacao, 'unidade_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: MateriaLegislativa:
{% trans 'Identificação Básica' %}: {% trans 'Identificação Básica' %}:
- tipo numero ano - tipo ano numero
- data_apresentacao numero_protocolo tipo_apresentacao - data_apresentacao numero_protocolo tipo_apresentacao
- texto_original - texto_original
{% trans 'Outras Informações' %}: {% trans 'Outras Informações' %}:

4
sapl/templates/materia/materialegislativa_filter.html

@ -50,11 +50,11 @@
{% if m.registrovotacao_set.exists %} {% if m.registrovotacao_set.exists %}
<strong>Data Votação:</strong> <strong>Data Votação:</strong>
{% if m.registrovotacao_set.last.ordem %} {% 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 }} {{ m.registrovotacao_set.last.ordem.data_ordem }}
</a> </a>
{% elif m.registrovotacao_set.last.expediente %} {% 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 }} {{ m.registrovotacao_set.last.expediente.data_ordem }}
</a> </a>
{% endif %} {% endif %}

5
sapl/templates/materia/materialegislativa_form.html

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

24
sapl/templates/painel/index.html

@ -21,6 +21,10 @@
ul, li { ul, li {
list-style-type: none; 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> </style>
</head> </head>
@ -39,26 +43,26 @@
<h2><font color="red"><p align="center"><span id="message"></span></p></font></h2> <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> <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%"> <table style="width:100%">
<tr> <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>
<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>
<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> </tr>
</table> </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"> <table style="width:60%" align="center">
<tr> <tr>
<th style="text-align:left"><font color="white" align="left"><span id="parlamentares"></span></font></th> <th style="text-align:left"><font color="white" align="left"><span id="parlamentares"></span></font></th>
@ -66,9 +70,9 @@
</tr> </tr>
</table> </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;"> <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="materia_legislativa_texto"></span></font></th></tr>
<tr><th style="text-align:center"><font color="white"><span id="observacao_materia"></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', '/sistema',
'/login', '/login',
'/logout', '/logout',
'/ajuda' '/ajuda',
'/email',
]}, ]},
'comissoes': { 'comissoes': {
'users': {'operador_geral': ['/sistema', '/comissao'], 'users': {'operador_geral': ['/sistema', '/comissao'],
@ -312,7 +313,7 @@ urls_publicas_excecoes = {
'/sistema/ajuda/', '/sistema/ajuda/',
'/ajuda/', '/ajuda/',
'/materia/confirmar/1/1', '/email/validate/1/1',
'/materia/pesquisar-materia', '/materia/pesquisar-materia',
# usado na edição de matérias mas com restrição irrelevante # usado na edição de matérias mas com restrição irrelevante

Loading…
Cancel
Save