Browse Source

Impl feature flag (#3357)

* add load para variável de ambiente

* altera url de primeira página se SAPL_AS_SAPN = True

* add context_processor para sapl as sapn

* ajuste de identação

* refatora base.html para sapl as sapn

* remove menus do sapl em sapn

* ajusta tabelas auxiliares

* refatora norma e compilação para sapl as sapn

* impl feature flag superficial

* ajusta menu Acessar em sapl as sapn

* add orgao como fk para normas

* add órgão no cadastro de normas

* ajuste de teste redirecionamento sapl index

* ajuste de teste de url
pull/3359/head
Leandro Roberto Silva 4 years ago
committed by GitHub
parent
commit
18c54c1401
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      sapl/base/forms.py
  2. 18
      sapl/base/migrations/0044_appconfig_sapl_as_sapn.py
  3. 18
      sapl/base/migrations/0045_auto_20210301_1537.py
  4. 5
      sapl/base/models.py
  5. 7
      sapl/base/templatetags/common_tags.py
  6. 34
      sapl/base/urls.py
  7. 9
      sapl/base/views.py
  8. 19
      sapl/compilacao/migrations/0018_auto_20210227_2152.py
  9. 3
      sapl/compilacao/models.py
  10. 13
      sapl/context_processors.py
  11. 26
      sapl/norma/forms.py
  12. 20
      sapl/norma/migrations/0038_normajuridica_orgao.py
  13. 8
      sapl/norma/models.py
  14. 4
      sapl/norma/urls.py
  15. 19
      sapl/norma/views.py
  16. 5
      sapl/redireciona_urls/tests.py
  17. 95
      sapl/redireciona_urls/views.py
  18. 1
      sapl/settings.py
  19. 45
      sapl/templates/base.html
  20. 3
      sapl/templates/base/layouts.yaml
  21. 4
      sapl/templates/compilacao/subnav.html
  22. 3
      sapl/templates/compilacao/text_list__embedded.html
  23. 74
      sapl/templates/menu_tabelas_auxiliares.yaml
  24. 4
      sapl/templates/navbar.yaml
  25. 4
      sapl/templates/norma/layouts.yaml
  26. 6
      sapl/templates/norma/normajuridica_detail.html
  27. 5
      sapl/templates/norma/normajuridica_form.html
  28. 3
      sapl/templates/search/search.html
  29. 14
      sapl/test_urls.py
  30. 14
      sapl/urls.py
  31. 7
      sapl/utils.py

3
sapl/base/forms.py

@ -1611,7 +1611,8 @@ class ConfiguracoesAppForm(ModelForm):
'tramitacao_materia',
'tramitacao_documento',
'google_recaptcha_site_key',
'google_recaptcha_secret_key']
'google_recaptcha_secret_key',
'sapl_as_sapn']
def __init__(self, *args, **kwargs):
super(ConfiguracoesAppForm, self).__init__(*args, **kwargs)

18
sapl/base/migrations/0044_appconfig_sapl_as_sapn.py

@ -0,0 +1,18 @@
# Generated by Django 2.2.13 on 2021-02-28 00:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0043_auto_20210203_1442'),
]
operations = [
migrations.AddField(
model_name='appconfig',
name='sapl_as_sapn',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Utilizar SAPL com SAPN?'),
),
]

18
sapl/base/migrations/0045_auto_20210301_1537.py

@ -0,0 +1,18 @@
# Generated by Django 2.2.13 on 2021-03-01 18:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0044_appconfig_sapl_as_sapn'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='sapl_as_sapn',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Utilizar SAPL como SAPN?'),
),
]

5
sapl/base/models.py

@ -200,6 +200,11 @@ class AppConfig(models.Model):
verbose_name=_('Chave privada gerada pelo Google Recaptcha'),
max_length=256, default='')
sapl_as_sapn = models.BooleanField(
verbose_name=_(
'Utilizar SAPL como SAPN?'),
choices=YES_NO_CHOICES, default=False)
class Meta:
verbose_name = _('Configurações da Aplicação')
verbose_name_plural = _('Configurações da Aplicação')

7
sapl/base/templatetags/common_tags.py

@ -51,6 +51,13 @@ def model_verbose_name_plural(class_name):
model = get_class(class_name)
return model._meta.verbose_name_plural
@register.filter
def meta_model_value(instance, attr):
try:
return getattr(instance._meta, attr)
except:
return ''
@register.filter
def split(value, arg):

34
sapl/base/urls.py

@ -11,7 +11,8 @@ from django.views.generic.base import RedirectView, TemplateView
from sapl.base.views import (AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_estatistica, DetailUsuarioView,
PesquisarAutorView, RecuperarSenhaEmailView, RecuperarSenhaFinalizadoView,
RecuperarSenhaConfirmaView, RecuperarSenhaCompletoView, RelatorioMateriaAnoAssuntoView)
RecuperarSenhaConfirmaView, RecuperarSenhaCompletoView, RelatorioMateriaAnoAssuntoView,
IndexView)
from sapl.settings import EMAIL_SEND_USER, MEDIA_URL, LOGOUT_REDIRECT_URL
from .apps import AppConfig
@ -35,10 +36,14 @@ app_name = AppConfig.name
admin_user = [
url(r'^sistema/usuario/$', PesquisarUsuarioView.as_view(), name='usuario'),
url(r'^sistema/usuario/create$', CreateUsuarioView.as_view(), name='user_create'),
url(r'^sistema/usuario/(?P<pk>\d+)$', DetailUsuarioView.as_view(), name='user_detail'),
url(r'^sistema/usuario/(?P<pk>\d+)/edit$', EditUsuarioView.as_view(), name='user_edit'),
url(r'^sistema/usuario/(?P<pk>\d+)/delete$', DeleteUsuarioView.as_view(), name='user_delete')
url(r'^sistema/usuario/create$',
CreateUsuarioView.as_view(), name='user_create'),
url(r'^sistema/usuario/(?P<pk>\d+)$',
DetailUsuarioView.as_view(), name='user_detail'),
url(r'^sistema/usuario/(?P<pk>\d+)/edit$',
EditUsuarioView.as_view(), name='user_edit'),
url(r'^sistema/usuario/(?P<pk>\d+)/delete$',
DeleteUsuarioView.as_view(), name='user_delete')
]
alterar_senha = [
@ -49,17 +54,23 @@ alterar_senha = [
]
recuperar_senha = [
url(r'^recuperar-senha/email/$', RecuperarSenhaEmailView.as_view(), name='recuperar_senha_email'),
url(r'^recuperar-senha/finalizado/$', RecuperarSenhaFinalizadoView.as_view(), name='recuperar_senha_finalizado'),
url(r'^recuperar-senha/email/$', RecuperarSenhaEmailView.as_view(),
name='recuperar_senha_email'),
url(r'^recuperar-senha/finalizado/$',
RecuperarSenhaFinalizadoView.as_view(), name='recuperar_senha_finalizado'),
url(r'^recuperar-senha/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$', RecuperarSenhaConfirmaView.as_view(),
name='recuperar_senha_confirma'),
url(r'^recuperar-senha/completo/$', RecuperarSenhaCompletoView.as_view(), name='recuperar_senha_completo'),
url(r'^recuperar-senha/completo/$',
RecuperarSenhaCompletoView.as_view(), name='recuperar_senha_completo'),
]
urlpatterns = [
url(r'^$', IndexView.as_view(template_name='index.html'), name='sapl_index'),
url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())),
url(r'^sistema/autor/', include(AutorCrud.get_urls())),
url(r'^sistema/autor/pesquisar-autor/', PesquisarAutorView.as_view(), name='pesquisar_autor'),
url(r'^sistema/autor/pesquisar-autor/',
PesquisarAutorView.as_view(), name='pesquisar_autor'),
url(r'^sistema/ajuda/(?P<topic>\w+)$',
HelpTopicView.as_view(), name='help_topic'),
@ -174,9 +185,10 @@ urlpatterns = [
(TemplateView.as_view(template_name='sistema.html')),
name='sistema'),
url(r'^login/$', views.LoginView.as_view(template_name= 'base/login.html', authentication_form= LoginForm),
url(r'^login/$', views.LoginView.as_view(template_name='base/login.html', authentication_form=LoginForm),
name='login'),
url(r'^logout/$', views.LogoutView.as_view(), {'next_page': LOGOUT_REDIRECT_URL}, name='logout'),
url(r'^logout/$', views.LogoutView.as_view(),
{'next_page': LOGOUT_REDIRECT_URL}, name='logout'),
url(r'^sistema/search/', SaplSearchView(), name='haystack_search'),

9
sapl/base/views.py

@ -60,7 +60,7 @@ from sapl.sessao.models import (
from sapl.settings import EMAIL_SEND_USER
from sapl.utils import (gerar_hash_arquivo, intervalos_tem_intersecao, mail_service_configured, parlamentares_ativos,
SEPARADOR_HASH_PROPOSICAO, show_results_filter_set, num_materias_por_tipo,
google_recaptcha_configured)
google_recaptcha_configured, sapl_as_sapn)
from .forms import (AlterarSenhaForm, CasaLegislativaForm, ConfiguracoesAppForm, RelatorioAtasFilterSet,
RelatorioAudienciaFilterSet, RelatorioDataFimPrazoTramitacaoFilterSet,
@ -77,6 +77,13 @@ def get_casalegislativa():
return CasaLegislativa.objects.first()
class IndexView(TemplateView):
def get(self, request, *args, **kwargs):
if sapl_as_sapn():
return redirect('/norma/pesquisar')
return TemplateView.get(self, request, *args, **kwargs)
class ConfirmarEmailView(TemplateView):
template_name = "email/confirma.html"

19
sapl/compilacao/migrations/0018_auto_20210227_2152.py

@ -0,0 +1,19 @@
# Generated by Django 2.2.13 on 2021-02-28 00:52
from django.db import migrations
import image_cropping.fields
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0017_auto_20210225_1127'),
]
operations = [
migrations.AlterField(
model_name='dispositivo',
name='imagem_cropping',
field=image_cropping.fields.ImageRatioField('imagem', '100x100', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text='O recorte de imagem é possível após a atualização.', hide_image_field=False, size_warning=True, verbose_name='Recorte de Imagem'),
),
]

3
sapl/compilacao/models.py

@ -1192,8 +1192,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
imagem = ImageCropField(
verbose_name=_('Imagem'),
upload_to=imagem_upload_path,
validators=[restringe_tipos_de_arquivo_img], null=True, blank=True)
upload_to=imagem_upload_path, null=True, blank=True)
imagem_cropping = ImageRatioField(
'imagem', '100x100', verbose_name=_('Recorte de Imagem'),

13
sapl/context_processors.py

@ -1,8 +1,10 @@
import logging
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from sapl.utils import google_recaptcha_configured as google_recaptcha_configured_utils
from sapl.utils import google_recaptcha_configured as google_recaptcha_configured_utils,\
sapl_as_sapn as sapl_as_sapn_utils
from sapl.utils import mail_service_configured as mail_service_configured_utils
@ -32,3 +34,12 @@ def google_recaptcha_configured(request):
logger.warning(_('Google Recaptcha não configurado.'))
return {'google_recaptcha_configured': False}
return {'google_recaptcha_configured': True}
def sapl_as_sapn(request):
return {
'sapl_as_sapn': sapl_as_sapn_utils(),
'nome_sistema': _('Sistema de Apoio ao Processo Legislativo')
if not sapl_as_sapn_utils()
else _('Sistema de Apoio a Publicação de Normas')
}

26
sapl/norma/forms.py

@ -1,8 +1,6 @@
import django_filters
import logging
from crispy_forms.layout import Fieldset, Layout
from django import forms
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import models
@ -10,6 +8,7 @@ from django.db.models import Q
from django.forms import ModelChoiceField, ModelForm, widgets
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
import django_filters
from sapl.base.models import Autor, TipoAutor
from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, to_row
@ -85,7 +84,7 @@ class NormaFilterSet(django_filters.FilterSet):
class Meta(FilterOverridesMetaMixin):
model = NormaJuridica
fields = ['tipo', 'numero', 'ano', 'data', 'data_vigencia',
fields = ['orgao', 'tipo', 'numero', 'ano', 'data', 'data_vigencia',
'data_publicacao', 'ementa', 'assuntos']
def __init__(self, *args, **kwargs):
@ -94,7 +93,7 @@ class NormaFilterSet(django_filters.FilterSet):
row1 = to_row([('tipo', 4), ('numero', 4), ('ano', 4)])
row2 = to_row([('data', 6), ('data_publicacao', 6)])
row3 = to_row([('ementa', 6), ('assuntos', 6)])
row4 = to_row([('data_vigencia', 12)])
row4 = to_row([('data_vigencia', 6), ('orgao', 6), ])
row5 = to_row([('o', 6), ('indexacao', 6)])
self.form.helper = SaplFormHelper()
@ -143,6 +142,7 @@ class NormaJuridicaForm(FileFieldCheckMixin, ModelForm):
fields = ['tipo',
'numero',
'ano',
'orgao',
'data',
'esfera_federacao',
'complemento',
@ -184,14 +184,18 @@ class NormaJuridicaForm(FileFieldCheckMixin, ModelForm):
'Número de norma não pode conter somente letras')
if self.instance.numero != cleaned_data['numero']:
norma = NormaJuridica.objects.filter(ano=cleaned_data['ano'],
numero=cleaned_data['numero'],
tipo=cleaned_data['tipo']).exists()
params = {
'ano': cleaned_data['ano'],
'numero': cleaned_data['numero'],
'tipo': cleaned_data['tipo'],
}
params['orgao'] = cleaned_data['orgao']
norma = NormaJuridica.objects.filter(**params).exists()
if norma:
self.logger.warning("Já existe uma norma de mesmo Tipo ({}), Ano ({}) "
"e Número ({}) no sistema."
.format(cleaned_data['tipo'], cleaned_data['ano'], cleaned_data['numero']))
raise ValidationError("Já existe uma norma de mesmo Tipo, Ano "
raise ValidationError("Já existe uma norma de mesmo Tipo, Ano, Órgão "
"e Número no sistema")
if (cleaned_data['tipo_materia'] and
cleaned_data['numero_materia'] and
@ -454,7 +458,9 @@ class NormaPesquisaSimplesForm(forms.Form):
raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e '
'Data Final devem ser preenchidos obrigatoriamente'))
elif data_inicial > data_final:
self.logger.error("Data Final ({}) menor que a Data Inicial ({}).".format(data_final, data_inicial))
raise ValidationError(_('A Data Final não pode ser menor que a Data Inicial'))
self.logger.error("Data Final ({}) menor que a Data Inicial ({}).".format(
data_final, data_inicial))
raise ValidationError(
_('A Data Final não pode ser menor que a Data Inicial'))
return cleaned_data

20
sapl/norma/migrations/0038_normajuridica_orgao.py

@ -0,0 +1,20 @@
# Generated by Django 2.2.13 on 2021-03-01 18:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('materia', '0077_auto_20210209_1047'),
('norma', '0037_auto_20210107_1408'),
]
operations = [
migrations.AddField(
model_name='normajuridica',
name='orgao',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='materia.Orgao', verbose_name='Órgão'),
),
]

8
sapl/norma/models.py

@ -8,7 +8,7 @@ import reversion
from sapl.base.models import Autor
from sapl.compilacao.models import TextoArticulado
from sapl.materia.models import MateriaLegislativa
from sapl.materia.models import MateriaLegislativa, Orgao
from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES,
restringe_tipos_de_arquivo_txt,
texto_upload_path,
@ -151,6 +151,9 @@ class NormaJuridica(models.Model):
materia = models.ForeignKey(
MateriaLegislativa, blank=True, null=True,
on_delete=models.PROTECT, verbose_name=_('Matéria'))
orgao = models.ForeignKey(
Orgao, blank=True, null=True,
on_delete=models.PROTECT, verbose_name=_('Órgão'))
numero = models.CharField(
max_length=8,
verbose_name=_('Número'))
@ -247,8 +250,9 @@ class NormaJuridica(models.Model):
if numero_norma.isnumeric():
numero_norma = '{0:,}'.format(int(self.numero)).replace(',', '.')
return _('%(tipo)s%(numero)s, de %(data)s') % {
return _('%(tipo)s%(orgao_sigla)s%(numero)s, de %(data)s') % {
'tipo': self.tipo,
'orgao_sigla': f'-{self.orgao.sigla}' if self.orgao else '',
'numero': numero_norma,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y").lower()}

4
sapl/norma/urls.py

@ -1,3 +1,4 @@
from django.conf import settings
from django.conf.urls import include, url
from sapl.norma.views import (AnexoNormaJuridicaCrud, AssuntoNormaCrud,
@ -7,8 +8,10 @@ from sapl.norma.views import (AnexoNormaJuridicaCrud, AssuntoNormaCrud,
recuperar_numero_norma, AutoriaNormaCrud,
PesquisarAssuntoNormaView)
from .apps import AppConfig
app_name = AppConfig.name
@ -37,5 +40,4 @@ urlpatterns = [
url(r'^norma/recuperar-norma$', recuperar_norma, name="recuperar_norma"),
url(r'^norma/recuperar-numero-norma$', recuperar_numero_norma,
name="recuperar_numero_norma"),
]

19
sapl/norma/views.py

@ -7,6 +7,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from django.http import HttpResponse, JsonResponse
from django.http.response import HttpResponseRedirect
from django.shortcuts import redirect
from django.template import RequestContext, loader
from django.urls import reverse
from django.urls.base import reverse_lazy
@ -25,7 +26,9 @@ from sapl.base.models import AppConfig
from sapl.compilacao.views import IntegracaoTaView
from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux,
MasterDetailCrud, make_pagination)
from sapl.utils import show_results_filter_set, get_client_ip
from sapl.materia.models import Orgao
from sapl.utils import show_results_filter_set, get_client_ip,\
sapl_as_sapn
from .forms import (AnexoNormaJuridicaForm, NormaFilterSet, NormaJuridicaForm,
NormaPesquisaSimplesForm, NormaRelacionadaForm,
@ -35,8 +38,6 @@ from .models import (AnexoNormaJuridica, AssuntoNorma, NormaJuridica, NormaRelac
# LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '')
TipoNormaCrud = CrudAux.build(
TipoNormaJuridica, 'tipo_norma_juridica',
list_field_names=['sigla', 'descricao', 'equivalente_lexml'])
@ -273,6 +274,11 @@ class NormaCrud(Crud):
norma_id=kwargs['pk'],
ano=timezone.now().year,
horario_acesso=timezone.now())
if not 'display' in request.GET and not request.user.has_perm('norma.change_normajuridica') and \
self.get_object().texto_articulado.exists():
return redirect(reverse('sapl.norma:norma_ta',
kwargs={'pk': self.kwargs['pk']}))
return super().get(request, *args, **kwargs)
class DeleteView(Crud.DeleteView):
@ -450,9 +456,14 @@ def recuperar_norma(request):
def recuperar_numero_norma(request):
tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo'])
ano = request.GET.get('ano', '')
orgao = request.GET.get('orgao', '')
param = {'tipo': tipo,
'ano': ano if ano else timezone.now().year
'ano': ano if ano else timezone.now().year,
}
if orgao:
param['orgao'] = Orgao.objects.get(pk=orgao)
norma = NormaJuridica.objects.filter(**param).order_by(
'tipo', 'ano', 'numero').values_list('numero', flat=True)
if norma:

5
sapl/redireciona_urls/tests.py

@ -1,5 +1,6 @@
from django.urls import reverse
from django.test import TestCase
from django.urls import reverse
MovedPermanentlyHTTPStatusCode = 301
EMPTY_STRING = ''
@ -11,7 +12,7 @@ class RedirecionaURLsTests(TestCase):
response = self.client.get(reverse(
'sapl.redireciona_urls:redireciona_sapl_index')
)
url_e = reverse('sapl_index')
url_e = reverse('sapl.base:sapl_index')
self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode)
self.assertEqual(response.url, url_e)

95
sapl/redireciona_urls/views.py

@ -76,13 +76,14 @@ class RedirecionaSAPLIndex(RedirectView):
logger = logging.getLogger(__name__)
def get_redirect_url(self):
url_pattern = 'sapl_index'
url_pattern = 'sapl.base:sapl_index'
username = self.request.user.username
try:
self.logger.info("user=" + username + ". Tentando obter url.")
url = reverse(url_pattern)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(url_pattern)
url = has_iframe(url, self.request)
@ -105,17 +106,20 @@ class RedirecionaParlamentar(RedirectView):
if pk_parlamentar:
try:
kwargs = {'pk': pk_parlamentar}
self.logger.debug("user=" + username + ". Tentando obter url correspondente.")
self.logger.debug("user=" + username +
". Tentando obter url correspondente.")
url = reverse(parlamentar_detail, kwargs=kwargs)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(parlamentar_detail, kwargs=kwargs)
else:
try:
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(parlamentar_list)
except NoReverseMatch:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(parlamentar_list)
numero_legislatura = self.request.GET.get(
@ -143,17 +147,20 @@ class RedirecionaComissao(RedirectView):
kwargs = {'pk': pk_comissao}
try:
self.logger.debug("user=" + username + ". Tentando obter url correspondente.")
self.logger.debug("user=" + username +
". Tentando obter url correspondente.")
url = reverse(comissao_detail, kwargs=kwargs)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(comissao_detail)
else:
try:
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(comissao_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(comissao_list)
url = has_iframe(url, self.request)
@ -176,17 +183,20 @@ class RedirecionaComposicaoComissao(RedirectView):
kwargs = {'pk': pk_comissao}
try:
self.logger.debug("user=" + username + ". Tentando obter url correspondente.")
self.logger.debug("user=" + username +
". Tentando obter url correspondente.")
url = reverse(comissao_detail, kwargs=kwargs)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(comissao_detail)
else:
try:
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(comissao_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(comissao_list)
url = has_iframe(url, self.request)
@ -208,17 +218,20 @@ class RedirecionaPautaSessao(RedirectView):
if pk_sessao_plenaria:
kwargs = {'pk': pk_sessao_plenaria}
try:
self.logger.debug("user=" + username + ". Tentando obter url correspondente.")
self.logger.debug("user=" + username +
". Tentando obter url correspondente.")
url = reverse(pauta_sessao_detail, kwargs=kwargs)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(pauta_sessao_detail)
else:
try:
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(pauta_sessao_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(pauta_sessao_list)
data_sessao_plenaria = self.request.GET.get(
@ -255,10 +268,12 @@ class RedirecionaSessaoPlenaria(RedirectView):
if pk_sessao_plenaria:
kwargs = {'pk': pk_sessao_plenaria}
try:
self.logger.debug("user=" + username + ". Tentando obter url correspondente.")
self.logger.debug("user=" + username +
". Tentando obter url correspondente.")
url = reverse(sessao_plenaria_detail, kwargs=kwargs)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(sessao_plenaria_detail)
else:
@ -266,7 +281,8 @@ class RedirecionaSessaoPlenaria(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(sessao_plenaria_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(sessao_plenaria_list)
year = self.request.GET.get(
@ -309,7 +325,8 @@ class RedirecionaRelatoriosList(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(relatorios_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(relatorios_list)
url = has_iframe(url, self.request)
@ -328,7 +345,8 @@ class RedirecionaRelatoriosMateriasEmTramitacaoList(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(relatorio_materia_por_tramitacao)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(relatorio_materia_por_tramitacao)
year = self.request.GET.get(
@ -396,7 +414,8 @@ class RedirecionaMateriaLegislativaList(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(materialegislativa_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(materialegislativa_list)
tipo_materia = self.request.GET.get(
@ -475,7 +494,8 @@ class RedirecionaMesaDiretoraView(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(parlamentar_mesa_diretora)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(parlamentar_mesa_diretora)
url = has_iframe(url, self.request)
@ -509,12 +529,14 @@ class RedirecionaNormasJuridicasTextoIntegral(RedirectView):
url = EMPTY_STRING
username = self.request.user.username
try:
self.logger.debug("user=" + username + ". Tentando obter NormaJuridica com pk={}.".format(kwargs['norma_id']))
self.logger.debug(
"user=" + username + ". Tentando obter NormaJuridica com pk={}.".format(kwargs['norma_id']))
norma = NormaJuridica.objects.get(pk=kwargs['norma_id'])
if norma:
url = norma.texto_integral.url
except Exception as e:
self.logger.error("user=" + username + ". Erro ao obter NormaJuridica com pk={}. ".format(kwargs['norma_id']) + str(e))
self.logger.error(
"user=" + username + ". Erro ao obter NormaJuridica com pk={}. ".format(kwargs['norma_id']) + str(e))
raise e
url = has_iframe(url, self.request)
@ -535,7 +557,8 @@ class RedirecionaNormasJuridicasList(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(norma_juridica_pesquisa)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(norma_juridica_pesquisa)
tipo_norma = self.request.GET.get(
@ -598,7 +621,8 @@ class RedirecionaHistoricoTramitacoesList(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(historico_tramitacoes)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(historico_tramitacoes)
inicio_intervalo_data_tramitacao = self.request.GET.get(
@ -660,7 +684,8 @@ class RedirecionaAtasList(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(pesquisar_atas)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(pesquisar_atas)
inicio_intervalo_data_ata = self.request.GET.get(
@ -699,7 +724,8 @@ class RedirecionaPresencaParlamentares(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(presenca_sessao)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(presenca_sessao)
inicio_intervalo_data_presenca_parlamentar = self.request.GET.get(
@ -736,7 +762,8 @@ class RedirecionaMateriasPorAutor(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(relatorio_materia_por_autor)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(relatorio_materia_por_autor)
url = has_iframe(url, self.request)
@ -758,7 +785,8 @@ class RedirecionaMateriasPorAnoAutorTipo(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(relatorio_materia_por_ano_autor_tipo)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(relatorio_materia_por_ano_autor_tipo)
if ano:
@ -785,10 +813,12 @@ class RedirecionaReuniao(RedirectView):
if pk_reuniao:
kwargs = {'pk': pk_reuniao}
try:
self.logger.debug("user=" + username + ". Tentando obter url correspondente (pk={}).".format(kwargs['pk']))
self.logger.debug(
"user=" + username + ". Tentando obter url correspondente (pk={}).".format(kwargs['pk']))
url = reverse(reuniao_detail, kwargs=kwargs)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(reuniao_detail)
else:
@ -796,7 +826,8 @@ class RedirecionaReuniao(RedirectView):
self.logger.debug("user=" + username + ". Tentando obter url.")
url = reverse(reuniao_list)
except NoReverseMatch as e:
self.logger.error("user=" + username + ". Erro ao obter url. " + str(e))
self.logger.error("user=" + username +
". Erro ao obter url. " + str(e))
raise UnknownUrlNameError(reuniao_list)
year = self.request.GET.get(

1
sapl/settings.py

@ -196,6 +196,7 @@ TEMPLATES = [
'sapl.context_processors.parliament_info',
'sapl.context_processors.mail_service_configured',
'sapl.context_processors.google_recaptcha_configured',
'sapl.context_processors.sapl_as_sapn',
],
'debug': DEBUG

45
sapl/templates/base.html

@ -34,6 +34,7 @@
<body>
<div class="page fadein">
{% if not sapl_as_sapn or user.is_authenticated%}
{% if not request|has_iframe %}
{% block navigation %}
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
@ -42,7 +43,8 @@
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
{% block sections_navbar %} {% navbar 'navbar.yaml' %}{% endblock sections_navbar %}
{% block sections_navbar %} {% navbar 'navbar.yaml' %} {% endblock sections_navbar %}
<ul class="nav navbar-nav justify-content-end" id="autenticacao">
<li class="nav-item dropdown pesquisa">
@ -64,7 +66,7 @@
</a>
<ul class="dropdown-menu">
<li class="dropdown-item"><a>{{user.username}}</a></li>
{% if 'parlamentares.can_vote' in request.user.get_all_permissions %}
{% if not sapl_as_sapn and 'parlamentares.can_vote' in request.user.get_all_permissions %}
<li class="dropdown-item"><a href="" onclick="window.open('{% url 'sapl.painel:voto_individual' %}','Voto Individual','width=1000, height=800, scrollbars=yes')";>
Votar Matéria
</a></li>
@ -80,7 +82,29 @@
</div>
</nav>
{% endblock navigation %}
{% else %}
<div class="btn-cancel-iframe">
<a href="?iframe=0" target="_blank"><i class="fa fa-2x fa-arrows-alt"></i></a>
</div>
<header class="masthead">
<div class="container">
<div class="hidden-print">
{% subnav %}
</div>
</div>
</header>
{% endif %}
{% else %}
<div class="container">
<div class="row justify-content-end px-3">
{% if sapl_as_sapn and not user.is_authenticated%}
<small><a href="{% url 'sapl.base:login' %}">Acessar</a></small>
{% endif %}
</div>
</div>
{% endif %}
{% if not request|has_iframe %}
{# Header #}
{% block main_header %}
<header class="masthead">
@ -90,7 +114,7 @@
<img src="{% if logotipo %}{{ MEDIA_URL }}{{ logotipo }}{% else %}{% webpack_static 'img/logo.png' %}{% endif %}"
alt="Logo" class="img-responsive" >
<span class="vcenter">{% if nome %}{{ nome }}{% else %}{% trans 'Câmara/Assembléia não configurada'%}{% endif %}
<br/><small>{% trans 'Sistema de Apoio ao Processo Legislativo' %}</small>
<br/><small>{{nome_sistema}}</small>
</span>
</a>
</div>
@ -100,17 +124,6 @@
</div>
</header>
{% endblock main_header %}
{% else %}
<div class="btn-cancel-iframe">
<a href="?iframe=0" target="_blank"><i class="fa fa-2x fa-arrows-alt"></i></a>
</div>
<header class="masthead">
<div class="container">
<div class="hidden-print">
{% subnav %}
</div>
</div>
</header>
{% endif %}
{# Main content #}
@ -205,6 +218,7 @@
<br>
<a href="{{endereco_web}}" class="url">{% trans 'Site' %}</a> |
<a href="mailto:{{email}}" class="email">{% trans 'Fale Conosco' %}</a>
</small>
</address>
{% else %}
@ -214,6 +228,9 @@
<a href="{% url 'sapl.base:casalegislativa_list' %}">Favor configurar clicando aqui</a>
{% endif %}
{% endif %}
</div>
</div>
</div>

3
sapl/templates/base/layouts.yaml

@ -13,8 +13,7 @@ CasaLegislativa:
AppConfig:
{% trans 'Configurações Gerais' %}:
- esfera_federacao
- documentos_administrativos
- esfera_federacao documentos_administrativos sapl_as_sapn
#{% trans 'Módulo Parlamentares' %}:

4
sapl/templates/compilacao/subnav.html

@ -4,7 +4,9 @@
<ul class="nav nav-tabs justify-content-end">
{%if object %}
<li class="nav-item">
{% if request.GET.back_type == 'history' and object.content_object %}
{% if object.content_object|meta_model_value:'model_name' == 'normajuridica' %}
<a class="nav-link" href="{% url object|urldetail_content_type:object.content_object object.content_object.pk %}?display" title="{% trans 'Dados Complementares '%}">{% trans 'Dados Complementares '%}</a>
{% elif request.GET.back_type == 'history' and object.content_object %}
<a class="nav-link" href="javascript:window.history.back()" title="{% trans 'Voltar para '%}{{object}}">{% trans 'Voltar para '%}{{object}}</a>
{% elif object.content_object%}
<a class="nav-link" href="{% url object|urldetail_content_type:object.content_object object.content_object.pk %}" title="{% trans 'Voltar para '%}{{object}}">{% trans 'Voltar para '%}{{object}}</a>

3
sapl/templates/compilacao/text_list__embedded.html

@ -6,6 +6,9 @@
{% if object_list %}
{% if 'print' not in request.GET %}
<div class="actions btn-group" role="group">
{% if sapl_as_sapn %}
<a href="{% url 'sapl.norma:norma_pesquisa' %}" class="btn btn-outline-primary" >{% trans 'Fazer nova pesquisa' %}</a>
{% endif %}
<a href="{% if 'compilacao' not in request.resolver_match.namespace %}{% url 'sapl.compilacao:ta_text' object_list.0.ta_id %}{% else %}{{request.path}}{% endif %}?print" class="btn btn-outline-primary" id="btn_impressao">{% trans 'Preparar para impressão' %}</a>
</div>
{% endif %}

74
sapl/templates/menu_tabelas_auxiliares.yaml

@ -17,6 +17,7 @@
- title: {% trans 'Tipo de Autor' %}
url: sapl.base:tipoautor_list
css_class: btn btn-link
{% if not sapl_as_sapn%}
- title: {% trans 'Módulo Parlamentares' %}
css_class: head_title
children:
@ -137,6 +138,40 @@
- title: {% trans 'Configuração Etiqueta Materia Legislativa' %}
url: sapl.materia:configEtiquetaMateriaLegislativaCrud
css_class: btn btn-link
- title: {% trans 'Módulo Sessão Plenária' %}
css_class: head_title
children:
- title: {% trans 'Tipo de Sessão Plenária' %}
url: sapl.sessao:tiposessaoplenaria_list
css_class: btn btn-link
- title: {% trans 'Tipo de Resultado da Votação' %}
url: sapl.sessao:tiporesultadovotacao_list
css_class: btn btn-link
- title: {% trans 'Tipo de Expediente' %}
url: sapl.sessao:tipoexpediente_list
css_class: btn btn-link
- title: {% trans 'Tipo de Retirada de Pauta' %}
url: sapl.sessao:tiporetiradapauta_list
css_class: btn btn-link
- title: {% trans 'Ordenação do Resumo' %}
url: sapl.sessao:resumo_ordenacao
css_class: btn btn-link
- title: {% trans 'Tipo de Justificativa' %}
url: sapl.sessao:tipojustificativa_list
css_class: btn btn-link
- title: {% trans 'Módulo Administrativo' %}
css_class: head_title
children:
- title: {% trans 'Tipo de Documento' %}
url: sapl.protocoloadm:tipodocumentoadministrativo_list
css_class: btn btn-link
- title: {% trans 'Status de Tramitação' %}
url: sapl.protocoloadm:statustramitacaoadministrativo_list
css_class: btn btn-link
- title: {% trans 'Apagar Protocolos' %}
url: sapl.protocoloadm:apaga_protocolos_view
css_class: btn btn-link
{% endif %}
- title: {% trans 'Módulo Normas Jurídicas' %}
css_class: head_title
children:
@ -152,6 +187,12 @@
- title: {% trans 'Adicionar Assunto de Norma Jurídica' %}
url: sapl.norma:assuntonorma_create
css_class: btn btn-link
{% if sapl_as_sapn %}
- title: {% trans 'Órgão' %}
url: sapl.materia:orgao_list
css_class: btn btn-link
{% endif %}
- title: {% trans 'Módulo Textos Articulados' %}
css_class: head_title
children:
@ -170,27 +211,6 @@
- title: {% trans 'Tipos de Vides' %}
url: sapl.compilacao:tipovide_list
css_class: btn btn-link
- title: {% trans 'Módulo Sessão Plenária' %}
css_class: head_title
children:
- title: {% trans 'Tipo de Sessão Plenária' %}
url: sapl.sessao:tiposessaoplenaria_list
css_class: btn btn-link
- title: {% trans 'Tipo de Resultado da Votação' %}
url: sapl.sessao:tiporesultadovotacao_list
css_class: btn btn-link
- title: {% trans 'Tipo de Expediente' %}
url: sapl.sessao:tipoexpediente_list
css_class: btn btn-link
- title: {% trans 'Tipo de Retirada de Pauta' %}
url: sapl.sessao:tiporetiradapauta_list
css_class: btn btn-link
- title: {% trans 'Ordenação do Resumo' %}
url: sapl.sessao:resumo_ordenacao
css_class: btn btn-link
- title: {% trans 'Tipo de Justificativa' %}
url: sapl.sessao:tipojustificativa_list
css_class: btn btn-link
- title: {% trans 'Módulo LexML' %}
css_class: head_title
children:
@ -200,15 +220,3 @@
- title: {% trans 'Publicador' %}
url: sapl.lexml:lexmlpublicador_list
css_class: btn btn-link
- title: {% trans 'Módulo Administrativo' %}
css_class: head_title
children:
- title: {% trans 'Tipo de Documento' %}
url: sapl.protocoloadm:tipodocumentoadministrativo_list
css_class: btn btn-link
- title: {% trans 'Status de Tramitação' %}
url: sapl.protocoloadm:statustramitacaoadministrativo_list
css_class: btn btn-link
- title: {% trans 'Apagar Protocolos' %}
url: sapl.protocoloadm:apaga_protocolos_view
css_class: btn btn-link

4
sapl/templates/navbar.yaml

@ -2,7 +2,7 @@
- title: {% trans 'Início' %}
url: '/'
{% if not sapl_as_sapn %}
- title: {% trans 'Institucional' %}
children:
- title: {% trans 'Mesa Diretora' %}
@ -66,7 +66,7 @@
- title: {% trans 'Excluir Tramitação em Lote' %}
url: sapl.materia:excluir_tramitacao_em_lote
check_permission: materia.list_tramitacao {% comment %} FIXME transformar para checagens de menu_[funcionalidade]{% endcomment%}
{% endif %}
- title: {% trans 'Normas Jurídicas' %}
children:
- title: {% trans 'Pesquisar Normas Jurídicas' %}

4
sapl/templates/norma/layouts.yaml

@ -14,7 +14,7 @@ TipoNormaJuridica:
NormaJuridica:
{% trans 'Identificação Básica' %}:
- tipo numero ano
- orgao tipo:5 numero:2 ano:2
- data esfera_federacao complemento
- materia
- data_publicacao veiculo_publicacao data_vigencia pagina_inicio_publicacao pagina_fim_publicacao
@ -32,7 +32,7 @@ AnexoNormaJuridica:
NormaJuridicaCreate:
{% trans 'Identificação Básica' %}:
- tipo ano numero
- orgao tipo:5 numero:2 ano:2
- data esfera_federacao complemento
- tipo_materia numero_materia ano_materia
- data_publicacao veiculo_publicacao data_vigencia pagina_inicio_publicacao pagina_fim_publicacao

6
sapl/templates/norma/normajuridica_detail.html

@ -132,7 +132,7 @@
{% endif %}
</div>
{% endif %}
{% if object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
{% if not sapl_as_sapn and object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
<hr />
<div class="row">
<div class="col-sm-12">
@ -146,13 +146,13 @@
{% block webpack_loader_js %}
{{ block.super }}
{% if object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
{% if not sapl_as_sapn and object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
{% render_bundle 'compilacao' 'js' %}
{% endif %}
{% endblock %}
{% block extra_js %}
{% if object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
{% if not sapl_as_sapn and object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
<script language="Javascript">
window.onload = function () {
$.get("{% url 'sapl.compilacao:ta_text' object.texto_articulado.first.id %}?embedded",

5
sapl/templates/norma/normajuridica_form.html

@ -37,16 +37,17 @@
function recuperar_norma() {
var tipo = $("#id_tipo").val();
var ano = $("#id_ano").val();
var orgao = $("#id_orgao").val();
if (tipo) {
$.get("/norma/recuperar-numero-norma", { tipo: tipo, ano: ano },
$.get("/norma/recuperar-numero-norma", { tipo: tipo, ano: ano , orgao: orgao },
(data, status) => {
$("#id_numero").val(data.numero);
$("#id_ano").val(data.ano);
});
}
}
var fields = ["#id_tipo", "#id_ano"];
var fields = ["#id_tipo", "#id_ano", "#id_orgao"];
for (i = 0; i < fields.length; i++) {
$(fields[i]).change(recuperar_norma);
}

3
sapl/templates/search/search.html

@ -12,6 +12,8 @@
</div>
</div>
{% if not sapl_as_sapn %}
<div class="row">
<div class="col-md-8">
<h3> Em quais tipos de documento deseja pesquisar?</h3>
@ -25,6 +27,7 @@
{{ form.models }}
</div>
</div>
{% endif %}
<div class="row">
<div class="col-md-12">

14
sapl/test_urls.py

@ -1,4 +1,3 @@
import pytest
from django.apps import apps
from django.contrib.auth import get_user_model
from django.contrib.auth.management import _get_all_permissions
@ -6,6 +5,7 @@ from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from django.utils.translation import ugettext_lazy as _
import pytest
from sapl.crud.base import PermissionRequiredForAppCrudMixin
from sapl.rules.apps import AppConfig, update_groups
@ -13,6 +13,7 @@ from scripts.lista_urls import lista_urls
from .settings import SAPL_APPS
pytestmark = pytest.mark.django_db
sapl_appconfs = [apps.get_app_config(n[5:]) for n in SAPL_APPS]
@ -159,7 +160,9 @@ apps_url_patterns_prefixs_and_users = {
'/recuperar-senha',
'/sapl',
'/XSLT',
]},
],
'exact': ['/']
},
'comissoes': {
'users': {'operador_geral': ['/sistema', '/comissao'],
'operador_comissoes': ['/comissao']},
@ -276,12 +279,19 @@ def test_urlpatterns(url_item, admin_client):
if app_name in apps_url_patterns_prefixs_and_users:
prefixs = apps_url_patterns_prefixs_and_users[app_name]['prefixs']
exacts = apps_url_patterns_prefixs_and_users[app_name].get(
'exact', [])
isvalid = False
for prefix in prefixs:
if url.startswith(prefix):
isvalid = True
break
if not isvalid:
for exact in exacts:
if url == exact:
isvalid = True
break
assert isvalid, """
O prefixo da url (%s) não está no padrão de sua app (%s).

14
sapl/urls.py

@ -36,9 +36,9 @@ import sapl.redireciona_urls.urls
import sapl.relatorios.urls
import sapl.sessao.urls
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='index.html'),
name='sapl_index'),
urlpatterns = []
urlpatterns += [
url(r'^message$', TemplateView.as_view(template_name='base.html')),
url(r'^admin/', admin.site.urls),
@ -54,17 +54,21 @@ urlpatterns = [
url(r'', include(sapl.relatorios.urls)),
url(r'', include(sapl.audiencia.urls)),
# name='sapl_index'),
# must come at the end
# so that base /sistema/ url doesn't capture its children
url(r'', include(sapl.base.urls)),
url(r'', include(sapl.api.urls)),
url(r'^favicon\.ico$', RedirectView.as_view(url='/static/sapl/img/favicon.ico', permanent=True)),
url(r'^favicon\.ico$', RedirectView.as_view(
url='/static/sapl/img/favicon.ico', permanent=True)),
url(r'', include(sapl.redireciona_urls.urls)),
path("robots.txt", TemplateView.as_view(template_name="robots.txt", content_type="text/plain")),
path("robots.txt", TemplateView.as_view(
template_name="robots.txt", content_type="text/plain")),
]

7
sapl/utils.py

@ -6,6 +6,7 @@ from operator import itemgetter
import os
import platform
import re
import sys
import tempfile
from time import time
from unicodedata import normalize as unicodedata_normalize
@ -27,6 +28,7 @@ from django.db import models
from django.db.models import Q
from django.forms import BaseForm
from django.forms.widgets import SplitDateTimeWidget
from django.urls.base import clear_url_caches
from django.utils import six, timezone
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
@ -1019,6 +1021,11 @@ def google_recaptcha_configured():
return not AppConfig.attr('google_recaptcha_site_key') == ''
def sapl_as_sapn():
from sapl.base.models import AppConfig
return AppConfig.attr('sapl_as_sapn')
def timing(f):
@wraps(f)
def wrap(*args, **kw):

Loading…
Cancel
Save