diff --git a/.gitignore b/.gitignore index 65adbb56b..cb6cce48e 100644 --- a/.gitignore +++ b/.gitignore @@ -87,8 +87,7 @@ target/ *.sublime-workspace .ipynb_checkpoints/ *.ipynb -.vscode/ - +.vscode/* # specific to this project whoosh_index diff --git a/sapl/api/forms.py b/sapl/api/forms.py index 94bc80de4..c36a0c11f 100644 --- a/sapl/api/forms.py +++ b/sapl/api/forms.py @@ -1,3 +1,5 @@ +import logging + from django.db.models import Q from django.forms.fields import CharField, MultiValueField from django.forms.widgets import MultiWidget, TextInput @@ -124,6 +126,7 @@ class AutorSearchForFieldFilterSet(AutorChoiceFilterSet): class AutoresPossiveisFilterSet(FilterSet): + logger = logging.getLogger(__name__) data_relativa = DateFilter(method='filter_data_relativa') tipo = MethodFilter() @@ -135,9 +138,12 @@ class AutoresPossiveisFilterSet(FilterSet): return queryset def filter_tipo(self, queryset, value): + try: + self.logger.debug("Tentando obter TipoAutor correspondente à pk {}.".format(value)) tipo = TipoAutor.objects.get(pk=value) except: + self.logger.error("TipoAutor(pk={}) inexistente.".format(value)) raise serializers.ValidationError(_('Tipo de Autor inexistente.')) qs = queryset.filter(tipo=tipo) diff --git a/sapl/api/views.py b/sapl/api/views.py index 3ec527646..b8cafc1dd 100644 --- a/sapl/api/views.py +++ b/sapl/api/views.py @@ -1,4 +1,4 @@ - +import logging from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django.http import Http404 @@ -124,6 +124,7 @@ class AutorListView(ListAPIView): qualquer atributo destes models podem ser passados para busca """ + logger = logging.getLogger(__name__) TR_AUTOR_CHOICE_SERIALIZER = 1 TR_AUTOR_SERIALIZER = 3 @@ -138,6 +139,7 @@ class AutorListView(ListAPIView): @property def tr(self): + username = self.request.user.username try: tr = int(self.request.GET.get ('tr', AutorListView.TR_AUTOR_CHOICE_SERIALIZER)) @@ -145,7 +147,8 @@ class AutorListView(ListAPIView): if tr not in (AutorListView.TR_AUTOR_CHOICE_SERIALIZER, AutorListView.TR_AUTOR_SERIALIZER): return AutorListView.TR_AUTOR_CHOICE_SERIALIZER - except: + except Exception as e: + self.logger.error('user=' + username + '. ' + str(e)) return AutorListView.TR_AUTOR_CHOICE_SERIALIZER return tr @@ -161,6 +164,7 @@ class AutorListView(ListAPIView): class AutoresProvaveisListView(ListAPIView): + logger = logging.getLogger(__name__) permission_classes = (IsAuthenticatedOrReadOnly,) queryset = Autor.objects.all() @@ -171,14 +175,16 @@ class AutoresProvaveisListView(ListAPIView): serializer_class = ChoiceSerializer def get_queryset(self): + params = {'content_type__isnull': False} - + username = self.request.user.username tipo = '' try: tipo = int(self.request.GET.get('tipo', '')) if tipo: params['id'] = tipo - except: + except Exception as e: + self.logger.error('user= ' + username + '. ' + str(e)) pass tipos = TipoAutor.objects.filter(**params) diff --git a/sapl/audiencia/forms.py b/sapl/audiencia/forms.py index 4bd265b72..ab2f2a6e7 100755 --- a/sapl/audiencia/forms.py +++ b/sapl/audiencia/forms.py @@ -1,3 +1,5 @@ +import logging + from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import transaction @@ -11,7 +13,7 @@ from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.utils import timezone class AudienciaForm(forms.ModelForm): - + logger = logging.getLogger(__name__) data_atual = timezone.now() tipo = forms.ModelChoiceField(required=True, @@ -62,6 +64,7 @@ class AudienciaForm(forms.ModelForm): def clean(self): + cleaned_data = super(AudienciaForm, self).clean() if not self.is_valid(): return cleaned_data @@ -72,6 +75,7 @@ class AudienciaForm(forms.ModelForm): if materia and ano_materia and tipo_materia: try: + self.logger.debug("Tentando obter MateriaLegislativa %s nº %s/%s." % (tipo_materia, materia, ano_materia)) materia = MateriaLegislativa.objects.get( numero=materia, ano=ano_materia, @@ -79,14 +83,19 @@ class AudienciaForm(forms.ModelForm): except ObjectDoesNotExist: msg = _('A matéria %s nº %s/%s não existe no cadastro' ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) + self.logger.error('A MateriaLegislativa %s nº %s/%s não existe no cadastro' + ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) raise ValidationError(msg) else: + self.logger.info("MateriaLegislativa %s nº %s/%s obtida com sucesso." % (tipo_materia, materia, ano_materia)) cleaned_data['materia'] = materia else: campos = [materia, tipo_materia, ano_materia] if campos.count(None) + campos.count('') < len(campos): msg = _('Preencha todos os campos relacionados à Matéria Legislativa') + self.logger.error('Algum campo relacionado à MatériaLegislativa %s nº %s/%s \ + não foi preenchido.' % (tipo_materia, materia, ano_materia)) raise ValidationError(msg) if not cleaned_data['numero']: @@ -102,7 +111,9 @@ class AudienciaForm(forms.ModelForm): if self.cleaned_data['hora_inicio'] and self.cleaned_data['hora_fim']: if (self.cleaned_data['hora_fim'] < self.cleaned_data['hora_inicio']): - msg = _('A hora de fim não pode ser anterior a hora de início') + msg = _('A hora de fim ({}) não pode ser anterior a hora ' + 'de início({})'.format(self.cleaned_data['hora_fim'], self.cleaned_data['hora_inicio'])) + self.logger.error('Hora de fim anterior à hora de início.') raise ValidationError(msg) return cleaned_data diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 7d6705687..4ba3c6255 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -1,4 +1,6 @@ import django_filters +import logging + from crispy_forms.bootstrap import FieldWithButtons, InlineRadios, StrictButton from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row @@ -53,7 +55,7 @@ def get_roles(): class UsuarioCreateForm(ModelForm): - + logger = logging.getLogger(__name__) username = forms.CharField(required=True, label="Nome de usuário", max_length=30) firstname = forms.CharField(required=True, label="Nome", max_length=30) @@ -81,6 +83,7 @@ class UsuarioCreateForm(ModelForm): data = self.cleaned_data if data['password1'] != data['password2']: + self.logger.error('Erro de validação. Senhas informadas ({}, {}) são diferentes.'.format(data['password1'], data['password2'])) raise ValidationError('Senhas informadas são diferentes') return data @@ -113,8 +116,8 @@ class UsuarioCreateForm(ModelForm): class UsuarioEditForm(ModelForm): + logger = logging.getLogger(__name__) # ROLES = [(g.id, g.name) for g in Group.objects.all().order_by('name')] - ROLES = [] password1 = forms.CharField(required=False, widget=forms.PasswordInput, label='Senha') @@ -155,17 +158,19 @@ class UsuarioEditForm(ModelForm): data = self.cleaned_data if data['password1'] and data['password1'] != data['password2']: + self.logger.error('Erro de validação. Senhas informadas ({}, {}) são diferentes.'.format(data['password1'], data['password2'])) raise ValidationError('Senhas informadas são diferentes') return data class SessaoLegislativaForm(ModelForm): - + logger = logging.getLogger(__name__) class Meta: model = SessaoLegislativa exclude = [] def clean(self): + cleaned_data = super(SessaoLegislativaForm, self).clean() if not self.is_valid(): @@ -179,7 +184,7 @@ class SessaoLegislativaForm(ModelForm): data_inicio_leg = legislatura.data_inicio data_fim_leg = legislatura.data_fim pk = self.initial['id'] if self.initial else None - # Queries para verificar se existem Sessões Legislativas no período selecionado no form + # Queries para verificar se existem Sessões Legislativas no período selecionado no form # Caso onde a data_inicio e data_fim são iguais a de alguma sessão já criada primeiro_caso = Q(data_inicio=data_inicio, data_fim=data_fim) # Caso onde a data_inicio está entre o início e o fim de uma Sessão já existente @@ -209,20 +214,29 @@ class SessaoLegislativaForm(ModelForm): ult = 0 if numero <= ult and flag_edit: + self.logger.error('O número da SessaoLegislativa ({}) é menor ou igual ' + 'que o de Sessões Legislativas passadas ({})'.format(numero, ult)) raise ValidationError('O número da Sessão Legislativa não pode ser menor ou igual ' 'que o de Sessões Legislativas passadas') if data_inicio < data_inicio_leg or \ data_inicio > data_fim_leg: + self.logger.error('A data de início ({}) da SessaoLegislativa está compreendida ' + 'fora da data início ({}) e fim ({}) da Legislatura ' + 'selecionada'.format(data_inicio, data_inicio_leg, data_fim_leg)) raise ValidationError('A data de início da Sessão Legislativa deve estar compreendida ' 'entre a data início e fim da Legislatura selecionada') if data_fim > data_fim_leg or \ data_fim < data_inicio_leg: + self.logger.error('A data de fim ({}) da SessaoLegislativa está compreendida ' + 'fora da data início ({}) e fim ({}) da Legislatura ' + 'selecionada.'.format(data_fim, data_inicio_leg, data_fim_leg)) raise ValidationError('A data de fim da Sessão Legislativa deve estar compreendida ' 'entre a data início e fim da Legislatura selecionada') if data_inicio > data_fim: + self.logger.error('Data início ({}) superior à data fim ({}).'.format(data_inicio, data_fim)) raise ValidationError('Data início não pode ser superior à data fim') data_inicio_intervalo = cleaned_data['data_inicio_intervalo'] @@ -230,6 +244,8 @@ class SessaoLegislativaForm(ModelForm): if data_inicio_intervalo and data_fim_intervalo and \ data_inicio_intervalo > data_fim_intervalo: + self.logger.error('Data início de intervalo ({}) superior à ' + 'data fim de intervalo ({}).'.format(data_inicio_intervalo, data_fim_intervalo)) raise ValidationError('Data início de intervalo não pode ser ' 'superior à data fim de intervalo') @@ -238,6 +254,10 @@ class SessaoLegislativaForm(ModelForm): data_inicio_intervalo < data_inicio_leg or \ data_inicio_intervalo > data_fim or \ data_inicio_intervalo > data_fim_leg: + self.logger.error('A data de início do intervalo ({}) não está compreendida entre ' + 'as datas de início ({}) e fim ({}) tanto da Legislatura quanto da ' + 'própria Sessão Legislativa ({} e {}).' + .format(data_inicio_intervalo, data_inicio_leg, data_fim_leg, data_inicio, data_fim)) raise ValidationError('A data de início do intervalo deve estar compreendida entre ' 'as datas de início e fim tanto da Legislatura quanto da ' 'própria Sessão Legislativa') @@ -246,6 +266,10 @@ class SessaoLegislativaForm(ModelForm): data_fim_intervalo > data_fim_leg or \ data_fim_intervalo < data_inicio or \ data_fim_intervalo < data_inicio_leg: + self.logger.error('A data de fim do intervalo ({}) não está compreendida entre ' + 'as datas de início ({}) e fim ({}) tanto da Legislatura quanto da ' + 'própria Sessão Legislativa ({} e {}).' + .format(data_fim_intervalo, data_inicio_leg, data_fim_leg, data_inicio, data_fim)) raise ValidationError('A data de fim do intervalo deve estar compreendida entre ' 'as datas de início e fim tanto da Legislatura quanto da ' 'própria Sessão Legislativa') @@ -290,6 +314,8 @@ class TipoAutorForm(ModelForm): class AutorForm(ModelForm): + logger = logging.getLogger(__name__) + senha = forms.CharField( max_length=20, label=_('Senha'), @@ -437,6 +463,7 @@ class AutorForm(ModelForm): def valida_igualdade(self, texto1, texto2, msg): if texto1 != texto2: + self.logger.error('Textos diferentes. ("{}" e "{}")'.format(texto1, texto2)) raise ValidationError(msg) return True @@ -450,6 +477,8 @@ class AutorForm(ModelForm): cd = self.cleaned_data if 'action_user' not in cd or not cd['action_user']: + self.logger.error('Não Informado se o Autor terá usuário ' + 'vinculado para acesso ao Sistema.') raise ValidationError(_('Informe se o Autor terá usuário ' 'vinculado para acesso ao Sistema.')) @@ -459,6 +488,10 @@ class AutorForm(ModelForm): self.instance.user, get_user_model().USERNAME_FIELD) != cd['username']: if 'status_user' not in cd or not cd['status_user']: + self.logger.error('Foi trocado ou removido o usuário deste Autor ({}), ' + 'mas não foi informado como se deve proceder ' + 'com o usuário que está sendo desvinculado? ({})' + .format(cd['username'], get_user_model().USERNAME_FIELD)) raise ValidationError( _('Foi trocado ou removido o usuário deste Autor, ' 'mas não foi informado como se deve proceder ' @@ -475,6 +508,7 @@ class AutorForm(ModelForm): if cd['action_user'] == 'A': param_username = {get_user_model().USERNAME_FIELD: cd['username']} if not User.objects.filter(**param_username).exists(): + self.logger.error('Não existe usuário com username "%s". ' % cd['username']) raise ValidationError( _('Não existe usuário com username "%s". ' 'Para utilizar esse username você deve selecionar ' @@ -483,11 +517,13 @@ class AutorForm(ModelForm): if cd['action_user'] != 'N': if 'username' not in cd or not cd['username']: + self.logger.error('Username não informado.') raise ValidationError(_('O username deve ser informado.')) param_username = { 'user__' + get_user_model().USERNAME_FIELD: cd['username']} if qs_autor.filter(**param_username).exists(): + self.logger.error('Já existe um Autor para este usuário ({}).'.format(cd['username'])) raise ValidationError( _('Já existe um Autor para este usuário.')) @@ -497,6 +533,7 @@ class AutorForm(ModelForm): ainda assim para renderizar um message.danger no topo do form. """ if 'tipo' not in cd or not cd['tipo']: + self.logger.error('Tipo do Autor não selecionado.') raise ValidationError( _('O Tipo do Autor deve ser selecionado.')) @@ -504,16 +541,21 @@ class AutorForm(ModelForm): if not tipo.content_type: if 'nome' not in cd or not cd['nome']: + self.logger.error('Nome do Autor não informado.') raise ValidationError( _('O Nome do Autor deve ser informado.')) else: if 'autor_related' not in cd or not cd['autor_related']: + self.logger.error('Registro de %s não escolhido para ser ' + 'vinculado ao cadastro de Autor' % tipo.descricao) raise ValidationError( _('Um registro de %s deve ser escolhido para ser ' 'vinculado ao cadastro de Autor') % tipo.descricao) if not tipo.content_type.model_class().objects.filter( pk=cd['autor_related']).exists(): + self.logger.error('O Registro definido (%s-%s) não está na base ' + 'de %s.' % (cd['autor_related'], cd['q'], tipo.descricao)) raise ValidationError( _('O Registro definido (%s-%s) não está na base de %s.' ) % (cd['autor_related'], cd['q'], tipo.descricao)) @@ -523,6 +565,8 @@ class AutorForm(ModelForm): content_type_id=cd['tipo'].content_type_id) if qs_autor_selected.exists(): autor = qs_autor_selected.first() + self.logger.error('Já existe um autor Cadastrado para ' + '%s' % autor.autor_related) raise ValidationError( _('Já existe um autor Cadastrado para %s' ) % autor.autor_related) @@ -993,6 +1037,7 @@ class LoginForm(AuthenticationForm): class ConfiguracoesAppForm(ModelForm): + logger = logging.getLogger(__name__) mostrar_brasao_painel = forms.BooleanField( help_text=_('Sugerimos fortemente que faça o upload de imagens com ' @@ -1031,9 +1076,12 @@ class ConfiguracoesAppForm(ModelForm): casa = CasaLegislativa.objects.first() if not casa: - raise ValidationError("Não há casa legislativa relacionada") + self.logger.error('Não há casa legislativa relacionada.') + raise ValidationError("Não há casa legislativa relacionada.") if (not bool(casa.logotipo) and mostrar_brasao_painel): + self.logger.error('Não há logitipo configurado para esta ' + 'CasaLegislativa ({}).'.format(casa)) raise ValidationError("Não há logitipo configurado para esta " "Casa legislativa.") @@ -1042,6 +1090,8 @@ class ConfiguracoesAppForm(ModelForm): class RecuperarSenhaForm(PasswordResetForm): + logger = logging.getLogger(__name__) + def __init__(self, *args, **kwargs): row1 = to_row( [('email', 12)]) @@ -1065,6 +1115,8 @@ class RecuperarSenhaForm(PasswordResetForm): if not email_existente: msg = 'Não existe nenhum usuário cadastrado com este e-mail.' + self.logger.error('Não existe nenhum usuário cadastrado com este e-mail ({}).' + .format(self.data['email'])) raise ValidationError(msg) return self.cleaned_data @@ -1087,6 +1139,7 @@ class NovaSenhaForm(SetPasswordForm): class AlterarSenhaForm(Form): + logger = logging.getLogger(__name__) username = forms.CharField(widget=forms.HiddenInput()) @@ -1130,6 +1183,7 @@ class AlterarSenhaForm(Form): new_password2 = data['new_password2'] if new_password1 != new_password2: + self.logger.error("'Nova Senha' ({}) diferente de 'Confirmar Senha' ({})".format(new_password1, new_password2)) raise ValidationError("'Nova Senha' diferente de 'Confirmar Senha'") # TODO: colocar mais regras como: tamanho mínimo, @@ -1137,6 +1191,7 @@ class AlterarSenhaForm(Form): # TODO: senha atual igual a senha anterior, etc if len(new_password1) < 6: + self.logger.error('A senha informada ({}) não tem o mínimo de 6 caracteres.'.format(new_password1)) raise ValidationError("A senha informada deve ter no mínimo 6 caracteres") username = data['username'] @@ -1144,13 +1199,17 @@ class AlterarSenhaForm(Form): user = User.objects.get(username=username) if user.is_anonymous(): + self.logger.error('Não é possível alterar senha de usuário anônimo ({}).'.format(username)) raise ValidationError("Não é possível alterar senha de usuário anônimo") if not user.check_password(old_password): + self.logger.error('Senha atual informada ({}) não confere ' + 'com a senha armazenada.'.format(old_password)) raise ValidationError("Senha atual informada não confere " "com a senha armazenada") if user.check_password(new_password1): + self.logger.error('Nova senha ({}) igual à senha anterior.'.format(new_password1)) raise ValidationError("Nova senha não pode ser igual à senha anterior") return self.cleaned_data diff --git a/sapl/base/views.py b/sapl/base/views.py index 2ce1abf92..bb6dda168 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1,4 +1,5 @@ import os +import logging from django.contrib.auth import get_user_model from django.contrib.auth.mixins import PermissionRequiredMixin @@ -146,6 +147,7 @@ class AutorCrud(CrudAux): return CrudAux.DeleteView.delete(self, *args, **kwargs) class UpdateView(CrudAux.UpdateView): + logger = logging.getLogger(__name__) layout_key = None form_class = AutorForm @@ -164,10 +166,13 @@ class AutorCrud(CrudAux): return CrudAux.UpdateView.get(self, request, *args, **kwargs) def get_success_url(self): + username = self.request.user.username pk_autor = self.object.id url_reverse = reverse('sapl.base:autor_detail', kwargs={'pk': pk_autor}) + try: + self.logger.debug('user=' + username + '. Enviando email na edição de Autores.') kwargs = {} user = self.object.user @@ -194,12 +199,13 @@ class AutorCrud(CrudAux): destinatario = [user.email] send_mail(assunto, mensagem, remetente, destinatario, fail_silently=False) - except: - print( - _('Erro no envio de email na edição de Autores.')) + except Exception as e: + self.logger.error('user=' + username + '. Erro no envio de email na edição de Autores. ' + str(e)) + return url_reverse class CreateView(CrudAux.CreateView): + logger = logging.getLogger(__name__) form_class = AutorForm layout_key = None @@ -214,10 +220,14 @@ class AutorCrud(CrudAux): return CrudAux.CreateView.get(self, request, *args, **kwargs) def get_success_url(self): + username = self.request.user.username pk_autor = self.object.id url_reverse = reverse('sapl.base:autor_detail', kwargs={'pk': pk_autor}) + try: + self.logger.debug('user=' + username + '. Enviando email na criação de Autores.') + kwargs = {} user = self.object.user @@ -244,9 +254,11 @@ class AutorCrud(CrudAux): destinatario = [user.email] send_mail(assunto, mensagem, remetente, destinatario, fail_silently=False) - except: + except Exception as e: print( _('Erro no envio de email na criação de Autores.')) + self.logger.error('user=' + username + '. Erro no envio de email na criação de Autores. ' + str(e)) + return url_reverse @@ -276,11 +288,13 @@ class RelatorioAtasView(FilterView): class RelatorioPresencaSessaoView(FilterView): + logger = logging.getLogger(__name__) model = SessaoPlenaria filterset_class = RelatorioPresencaSessaoFilterSet template_name = 'base/RelatorioPresencaSessao_filter.html' def get_context_data(self, **kwargs): + context = super(RelatorioPresencaSessaoView, self).get_context_data(**kwargs) context['title'] = _('Presença dos parlamentares nas sessões') @@ -289,7 +303,6 @@ class RelatorioPresencaSessaoView(FilterView): if not self.filterset.form.is_valid(): return context - # ===================================================================== # if 'salvar' not in self.request.GET: where = context['object_list'].query.where _range = where.children[0].rhs @@ -323,6 +336,8 @@ class RelatorioPresencaSessaoView(FilterView): total_sessao = context['object_list'].count() + username = self.request.user.username + # Completa o dicionario as informacoes parlamentar/sessao/ordem parlamentares_presencas = [] for i, p in enumerate(parlamentares_qs): @@ -332,12 +347,18 @@ class RelatorioPresencaSessaoView(FilterView): 'ordemdia_porc': 0 }) try: + self.logger.debug('user=' + username + '. Tentando obter presença do parlamentar (pk={}).'.format(p.id)) sessao_count = presenca_sessao.get(parlamentar_id=p.id)[1] - except ObjectDoesNotExist: + except ObjectDoesNotExist as e: + self.logger.error('user=' + username + '. Erro ao obter presença do parlamentar (pk={}). Definido como 0. '.format(p.id) + str(e)) sessao_count = 0 try: + # Presenças de cada Ordem do Dia + self.logger.info('user=' + username + '. Tentando obter PresencaOrdemDia para o parlamentar pk={}.'.format(p.id)) ordemdia_count = presenca_ordem.get(parlamentar_id=p.id)[1] except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Erro ao obter PresencaOrdemDia para o parlamentar pk={}. ' + 'Definido como 0.'.format(p.id)) ordemdia_count = 0 parlamentares_presencas[i].update({ @@ -847,12 +868,17 @@ class CasaLegislativaCrud(CrudAux): class HelpTopicView(TemplateView): + logger = logging.getLogger(__name__) def get_template_names(self): + + username = self.request.user.username topico = self.kwargs['topic'] try: + self.logger.debug('user=' + username + '. Tentando obter template %s.html.' % topico) get_template('ajuda/%s.html' % topico) - except TemplateDoesNotExist: + except TemplateDoesNotExist as e: + self.logger.error('user=' + username + '. Erro ao obter template {}.html. Template não existe. '.format(topico) + str(e)) raise Http404() return ['ajuda/%s.html' % topico] diff --git a/sapl/comissoes/forms.py b/sapl/comissoes/forms.py index 94d9b081f..7d230a7d4 100644 --- a/sapl/comissoes/forms.py +++ b/sapl/comissoes/forms.py @@ -1,3 +1,5 @@ +import logging + from django import forms from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError @@ -14,7 +16,7 @@ from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar class ComposicaoForm(forms.ModelForm): comissao = forms.CharField(required=False, label='Comissao', widget=forms.HiddenInput()) - + logger = logging.getLogger(__name__) class Meta: model = Composicao exclude = [] @@ -39,6 +41,9 @@ class ComposicaoForm(forms.ModelForm): comissao_id=comissao_pk) if intersecao_periodo: + self.logger.error('O período informado ({} a {})' + 'choca com períodos já ' + 'cadastrados para esta comissão'.format(periodo.data_inicio, periodo.data_fim)) raise ValidationError('O período informado ' 'choca com períodos já ' 'cadastrados para esta comissão') @@ -48,6 +53,7 @@ class ComposicaoForm(forms.ModelForm): class PeriodoForm(forms.ModelForm): + logger = logging.getLogger(__name__) class Meta: model = Periodo exclude = [] @@ -62,8 +68,10 @@ class PeriodoForm(forms.ModelForm): data_fim = cleaned_data['data_fim'] if data_fim and data_fim < data_inicio: + self.logger.error('A Data Final ({}) é menor que ' + 'a Data Inicial({}).'.format(data_fim, data_inicio)) raise ValidationError('A Data Final não pode ser menor que ' - 'a Data Inicial') + 'a Data Inicial') # Evita NoneType exception se não preenchida a data_fim if not data_fim: @@ -74,6 +82,9 @@ class PeriodoForm(forms.ModelForm): ) if not legislatura: + self.logger.error('O período informado ({} a {})' + 'não está contido em uma única ' + 'legislatura existente'.format(data_inicio, data_fim)) raise ValidationError('O período informado ' 'deve estar contido em uma única ' 'legislatura existente') @@ -85,6 +96,7 @@ class PeriodoForm(forms.ModelForm): class ParticipacaoCreateForm(forms.ModelForm): + logger = logging.getLogger(__name__) parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) class Meta: @@ -135,7 +147,9 @@ class ParticipacaoCreateForm(forms.ModelForm): data_desligamento = cleaned_data['data_desligamento'] if data_desligamento and \ - data_designacao > data_desligamento: + data_designacao > data_desligamento: + self.logger.error('Data de designação ({}) superior ' + 'à data de desligamento ({})'.format(data_designacao, data_desligamento)) raise ValidationError(_('Data de designação não pode ser superior ' 'à data de desligamento')) @@ -144,6 +158,7 @@ class ParticipacaoCreateForm(forms.ModelForm): if cleaned_data['cargo'].nome in cargos_unicos: msg = _('Este cargo é único para esta Comissão.') + self.logger.error('Este cargo ({}) é único para esta Comissão.'.format(cleaned_data['cargo'].nome)) raise ValidationError(msg) return cleaned_data @@ -190,6 +205,7 @@ class ParticipacaoCreateForm(forms.ModelForm): class ParticipacaoEditForm(forms.ModelForm): + logger = logging.getLogger(__name__) parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) nome_parlamentar = forms.CharField(required=False, label='Parlamentar') @@ -219,6 +235,8 @@ class ParticipacaoEditForm(forms.ModelForm): if data_desligamento and \ data_designacao > data_desligamento: + self.logger.error('Data de designação ({}) superior ' + 'à data de desligamento ({})'.format(data_designacao, data_desligamento)) raise ValidationError(_('Data de designação não pode ser superior ' 'à data de desligamento')) @@ -229,6 +247,8 @@ class ParticipacaoEditForm(forms.ModelForm): if cleaned_data['cargo'].nome in cargos_unicos: msg = _('Este cargo é único para esta Comissão.') + self.logger.error('Este cargo ({}) é único para esta Comissão (id={}).' + .format(cleaned_data['cargo'].nome, composicao_id)) raise ValidationError(msg) return cleaned_data @@ -236,6 +256,7 @@ class ParticipacaoEditForm(forms.ModelForm): class ComissaoForm(forms.ModelForm): + logger = logging.getLogger(__name__) class Meta: model = Comissao fields = '__all__' @@ -260,37 +281,50 @@ class ComissaoForm(forms.ModelForm): return self.cleaned_data if len(self.cleaned_data['nome']) > 100: - msg = _('Nome da Comissão deve ter no máximo 50 caracteres.') + msg = _('Nome da Comissão informado ({}) tem mais de 50 caracteres.'.format(self.cleaned_data['nome'])) + self.logger.error('Nome da Comissão deve ter no máximo 50 caracteres.') raise ValidationError(msg) if (self.cleaned_data['data_extincao'] and self.cleaned_data['data_extincao'] < self.cleaned_data['data_criacao']): msg = _('Data de extinção não pode ser menor que a de criação') + self.logger.error('Data de extinção ({}) não pode ser menor que a de criação ({}).' + .format(self.cleaned_data['data_extincao'],self.cleaned_data['data_criacao'])) raise ValidationError(msg) if (self.cleaned_data['data_final_prevista_temp'] and self.cleaned_data['data_final_prevista_temp'] < self.cleaned_data['data_criacao']): msg = _('Data Prevista para Término não pode ser menor que a de criação') + self.logger.error('Data Prevista para Término ({}) não pode ser menor que a de criação ({}).' + .format(self.cleaned_data['data_final_prevista_temp'], self.cleaned_data['data_criacao'])) raise ValidationError(msg) if (self.cleaned_data['data_prorrogada_temp'] and self.cleaned_data['data_prorrogada_temp'] < self.cleaned_data['data_criacao']): msg = _('Data Novo Prazo não pode ser menor que a de criação') + self.logger.error('Data Novo Prazo ({}) não pode ser menor que a de criação ({}).' + .format(self.cleaned_data['data_prorrogada_temp'], self.cleaned_data['data_criacao'])) raise ValidationError(msg) if (self.cleaned_data['data_instalacao_temp'] and self.cleaned_data['data_instalacao_temp'] < self.cleaned_data['data_criacao']): msg = _('Data de Instalação não pode ser menor que a de criação') + self.logger.error('Data de Instalação ({}) não pode ser menor que a de criação ({}).' + .format(self.cleaned_data['data_instalacao_temp'], self.cleaned_data['data_criacao'])) raise ValidationError(msg) if (self.cleaned_data['data_final_prevista_temp'] and self.cleaned_data['data_instalacao_temp'] and self.cleaned_data['data_final_prevista_temp'] < self.cleaned_data['data_instalacao_temp']): - msg = _('Data Prevista para Término não pode ser menor que a de Instalação') + msg = _('Data Prevista para Término não pode ser menor que a de Instalação.') + self.logger.error('Data Prevista para Término ({}) não pode ser menor que a de Instalação ({}).' + .format(self.cleaned_data['data_final_prevista_temp'], self.cleaned_data['data_instalacao_temp'])) raise ValidationError(msg) if (self.cleaned_data['data_prorrogada_temp'] and self.cleaned_data['data_instalacao_temp'] and self.cleaned_data['data_prorrogada_temp'] < self.cleaned_data['data_instalacao_temp']): - msg = _('Data Novo Prazo não pode ser menor que a de Instalação') + msg = _('Data Novo Prazo não pode ser menor que a de Instalação.') + self.logger.error('Data Novo Prazo ({}) não pode ser menor que a de Instalação ({}).' + .format(self.cleaned_data['data_prorrogada_temp'], self.cleaned_data['data_instalacao_temp'])) raise ValidationError(msg) return self.cleaned_data @@ -317,6 +351,7 @@ class ComissaoForm(forms.ModelForm): class ReuniaoForm(ModelForm): + logger = logging.getLogger(__name__) comissao = forms.ModelChoiceField(queryset=Comissao.objects.all(), widget=forms.HiddenInput()) @@ -326,6 +361,7 @@ class ReuniaoForm(ModelForm): def clean(self): super(ReuniaoForm, self).clean() + if not self.is_valid(): return self.cleaned_data @@ -334,6 +370,8 @@ class ReuniaoForm(ModelForm): if (self.cleaned_data['hora_fim'] < self.cleaned_data['hora_inicio']): msg = _('A hora de término da reunião não pode ser menor que a de início') + self.logger.error("A hora de término da reunião ({}) não pode ser menor que a de início ({})." + .format(self.cleaned_data['hora_fim'], self.cleaned_data['hora_inicio'])) raise ValidationError(msg) return self.cleaned_data diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index 78e639168..743eaa58f 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -1,3 +1,4 @@ +import logging from django.core.urlresolvers import reverse from django.db.models import F @@ -102,13 +103,18 @@ class ComposicaoCrud(MasterDetailCrud): return {'comissao': comissao} class ListView(MasterDetailCrud.ListView): + logger = logging.getLogger(__name__) template_name = "comissoes/composicao_list.html" paginate_by = None def take_composicao_pk(self): + + username = self.request.user.username try: + self.logger.debug('user=' + username + '. Tentando obter pk da composição.') return int(self.request.GET['pk']) - except: + except Exception as e: + self.logger.error('user=' + username + '. Erro ao obter pk da composição. Retornado 0. ' + str(e)) return 0 def get_context_data(self, **kwargs): @@ -193,12 +199,17 @@ class ReuniaoCrud(MasterDetailCrud): list_field_names = ['data', 'nome', 'tema'] class ListView(MasterDetailCrud.ListView): + logger = logging.getLogger(__name__) paginate_by = 10 def take_reuniao_pk(self): + + username = self.request.user.username try: + self.logger.debug('user=' + username + '. Tentando obter pk da reunião.') return int(self.request.GET['pk']) - except: + except Exception as e: + self.logger.error('user=' + username + '. Erro ao obter pk da reunião. Retornado 0. ' + str(e)) return 0 def get_context_data(self, **kwargs): diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index 6cf1911d6..765cd6fa2 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -1,6 +1,7 @@ from collections import OrderedDict from datetime import timedelta import sys +import logging from braces.views import FormMessagesMixin from django import forms @@ -650,6 +651,7 @@ class NotaMixin(DispositivoSuccessUrlMixin): class NotasCreateView(NotaMixin, CreateView): + logger = logging.getLogger(__name__) template_name = 'compilacao/ajax_form.html' form_class = NotaForm permission_required = 'compilacao.add_nota' @@ -662,6 +664,8 @@ class NotasCreateView(NotaMixin, CreateView): return super(NotasCreateView, self).get(request, *args, **kwargs) def post(self, request, *args, **kwargs): + + username = request.user.username self.object = None try: ta_id = kwargs.pop('ta_id') @@ -679,7 +683,9 @@ class NotasCreateView(NotaMixin, CreateView): else: return self.form_invalid(form) except Exception as e: + self.logger.error("user=" + username + ". " + str(e)) print(e) + self.logger.error("user=" + username + ". Error post.") return HttpResponse("error post") @@ -756,7 +762,7 @@ class PublicacaoMixin(CompMixin): messages.error(request, _( 'A funcionalidade de %s está desativada para %s.') % ( TipoTextoArticulado._meta.get_field( - 'publicacao_func').verbose_name, + 'publicacao_func').verbose_name, ta.tipo_ta.descricao)) return redirect(reverse('sapl.compilacao:ta_text', kwargs={'ta_id': self.kwargs['ta_id']})) @@ -1469,6 +1475,8 @@ class ActionDragAndMoveDispositivoAlteradoMixin(ActionsCommonsMixin): class ActionDeleteDispositivoMixin(ActionsCommonsMixin): + logger = logging.getLogger(__name__) + def json_delete_item_dispositivo(self, context): return self.json_delete_bloco_dispositivo(context, bloco=False) @@ -1516,6 +1524,7 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): return data def remover_dispositivo(self, base, bloco): + username = self.request.user.username base_ordem = base.ordem if base.dispositivo_subsequente or base.dispositivo_substituido: p = base.dispositivo_substituido @@ -1541,6 +1550,7 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): p.dispositivos_filhos_set.add(d) p.save() except Exception as e: + self.logger.error("user=" + username + '. ' + str(e)) print(e) base.delete() else: @@ -1575,6 +1585,8 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): dispositivo_pai=base).first() if not anterior: + self.logger.error("user=" + username + ". Não é possível excluir este Dispositivo (id={}) sem" + " excluir toda a sua estrutura!!!".format(base.ta_id)) raise Exception( _('Não é possível excluir este Dispositivo sem' ' excluir toda a sua estrutura!!!')) @@ -1594,6 +1606,9 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): for candidato in parents: if candidato == base: + self.logger.error("user=" + username + ". Não é possível excluir este " + "Dispositivo ({}) sem " + "excluir toda a sua estrutura!!!".format(candidato)) raise Exception( _('Não é possível excluir este ' 'Dispositivo sem ' @@ -1629,7 +1644,9 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): d.rotulo = d.rotulo_padrao() break else: - + self.logger.error("user=" + username + ". Não é possível excluir este " + "Dispositivo ({}) sem excluir toda " + "a sua estrutura!!!".format(candidato)) raise Exception( _('Não é possível excluir este ' 'Dispositivo sem ' @@ -1675,7 +1692,8 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): profundidade=profundidade_base) irmao.rotulo = irmao.rotulo_padrao() irmao.save() - except: + except Exception as e: + self.logger.error("user=" + username + "." + str(e)) break irmaos = pai_base.dispositivos_filhos_set.\ @@ -1792,7 +1810,8 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): dr.rotulo = dr.rotulo_padrao() try: dr.save(clean=base != dr) - except: + except Exception as e: + self.logger.error("user=" + username + ". " + str(e)) break # Pode não ser religavável @@ -1836,6 +1855,8 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): class ActionDispositivoCreateMixin(ActionsCommonsMixin): + logger = logging.getLogger(__name__) + def allowed_inserts(self, _base=None): request = self.request try: @@ -2090,6 +2111,8 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): return result except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) print(e) return {} @@ -2097,7 +2120,6 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): def json_set_dvt(self, context): # Dispositivo de Vigência do Texto Original e de Dpts Alterados dvt = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) - if dvt.auto_inserido: dvt = dvt.dispositivo_pai @@ -2136,8 +2158,11 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): 'com sucesso!!!')) return data - except: + except Exception as e: data = {} + username = self.request.user.username + self.logger.error("user=" + username + ". Ocorreu um erro ({}) na atualização do " + "Dispositivo de Vigência".format(str(e))) self.set_message(data, 'success', _('Ocorreu um erro na atualização do ' @@ -2154,8 +2179,9 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): def json_add_next( self, context, local_add='json_add_next', create_auto_inserts=True): + try: - + dp_auto_insert = None base = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) tipo = TipoDispositivo.objects.get(pk=context['tipo_pk']) @@ -2425,6 +2451,8 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): return data except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) print(e) return {} @@ -2432,6 +2460,7 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, ActionDeleteDispositivoMixin, ActionDispositivoCreateMixin): + logger = logging.getLogger(__name__) def render_to_json_response(self, context, **response_kwargs): @@ -2698,6 +2727,8 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, _('Dispositivo de Revogação adicionado com sucesso.')) except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) print(e) data.update({'pk': ndp.pk, @@ -3094,7 +3125,7 @@ class DispositivoEdicaoBasicaView(CompMixin, FormMessagesMixin, UpdateView): 'as alterações no Dispositivo') permission_required = 'compilacao.change_dispositivo_edicao_avancada' - + logger = logging.getLogger(__name__) @property def cancel_url(self): return reverse_lazy( @@ -3136,7 +3167,9 @@ class DispositivoEdicaoBasicaView(CompMixin, FormMessagesMixin, UpdateView): d.set_numero_completo([d.dispositivo0, ] + numero) d.rotulo = d.rotulo_padrao() - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". Ocorreu erro ({}) na atualização do rótulo.".format(str(e))) return True, JsonResponse({'message': str( _('Ocorreu erro na atualização do rótulo'))}, safe=False) return True, JsonResponse({ @@ -3194,6 +3227,7 @@ class DispositivoDefinidorVigenciaView(CompMixin, FormMessagesMixin, FormView): permission_required = ('compilacao.change_dispositivo_edicao_avancada', 'compilacao.change_dispositivo_de_vigencia_global') + logger = logging.getLogger(__name__) def get_form_kwargs(self): kwargs = FormView.get_form_kwargs(self) @@ -3238,7 +3272,9 @@ class DispositivoDefinidorVigenciaView(CompMixin, FormMessagesMixin, FormView): d = Dispositivo.objects.get(pk=item) self.object.dispositivos_vigencias_set.add(d) return self.form_valid(form) - except: + except Exception as e: + username = request.user.username + self.logger.error("user=" + username + ". " + str(e)) return self.form_invalid(form) else: return self.form_invalid(form) @@ -3253,6 +3289,7 @@ class DispositivoEdicaoAlteracaoView(CompMixin, FormMessagesMixin, UpdateView): 'as alterações no Dispositivo') permission_required = 'compilacao.change_dispositivo_registros_compilacao' + logger = logging.getLogger(__name__) @property def cancel_url(self): @@ -3276,7 +3313,9 @@ class DispositivoEdicaoAlteracaoView(CompMixin, FormMessagesMixin, UpdateView): try: with transaction.atomic(): return self.form_valid(form) - except: + except Exception as e: + username = request.user.username + self.logger.error("user=" + username + ". " + str(e)) return self.form_invalid(form) else: return self.form_invalid(form) diff --git a/sapl/crud/base.py b/sapl/crud/base.py index 162668c76..e720b36cd 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -1,4 +1,4 @@ - +import logging from braces.views import FormMessagesMixin from compressor.utils.decorators import cached_property from crispy_forms.bootstrap import FieldWithButtons, StrictButton @@ -102,6 +102,7 @@ variáveis do crud: class SearchMixin(models.Model): search = models.TextField(blank=True, default='') + logger = logging.getLogger(__name__) class Meta: abstract = True @@ -116,7 +117,9 @@ class SearchMixin(models.Model): if len(fields) == 1: try: search += str(getattr(self, str_field)) + ' ' - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) pass else: _self = self @@ -379,6 +382,7 @@ class CrudBaseMixin(CrispyLayoutFormMixin): class CrudListView(PermissionRequiredContainerCrudMixin, ListView): permission_required = (RP_LIST, ) + logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): @@ -552,7 +556,9 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): fm = None try: fm = model._meta.get_field(fo) - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) pass if fm and hasattr(fm, 'related_model')\ @@ -597,6 +603,7 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): class CrudCreateView(PermissionRequiredContainerCrudMixin, FormMessagesMixin, CreateView): permission_required = (RP_ADD, ) + logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): @@ -621,7 +628,9 @@ class CrudCreateView(PermissionRequiredContainerCrudMixin, try: self.object.owner = self.request.user self.object.modifier = self.request.user - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) pass if self.container_field: @@ -668,6 +677,7 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, permission_required = (RP_DETAIL, ) no_entries_msg = _('Nenhum registro Associado.') paginate_by = 10 + logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): @@ -690,7 +700,9 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, self.object, obj.model_set).model._meta.get_field( fieldname).related_model._meta.verbose_name_plural) for fieldname in self.list_field_names_set] - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) obj = self.crud if hasattr(self, 'crud') else self return [getattr( self.object, @@ -717,7 +729,9 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, self.resolve_model_set_url(ACTION_DETAIL, args=(obj.id,)) if i == 0 else None) for i, name in enumerate(self.list_field_names_set)] - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) return [( getattr(obj, name), self.resolve_model_set_url(ACTION_DETAIL, args=(obj.id,)) @@ -732,7 +746,9 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, def get(self, request, *args, **kwargs): try: self.object = self.model.objects.get(pk=kwargs.get('pk')) - except: + except Exception as e: + username = request.user.username + self.logger.error("user=" + username + ". " + str(e)) raise Http404 obj = self.crud if hasattr(self, 'crud') else self if hasattr(obj, 'model_set') and obj.model_set: @@ -805,12 +821,16 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, class CrudUpdateView(PermissionRequiredContainerCrudMixin, FormMessagesMixin, UpdateView): permission_required = (RP_CHANGE, ) + logger = logging.getLogger(__name__) def form_valid(self, form): + self.object = form.instance try: self.object.modifier = self.request.user - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) pass return super().form_valid(form) @@ -832,6 +852,7 @@ class CrudUpdateView(PermissionRequiredContainerCrudMixin, class CrudDeleteView(PermissionRequiredContainerCrudMixin, FormMessagesMixin, DeleteView): permission_required = (RP_DELETE, ) + logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): @@ -853,12 +874,20 @@ class CrudDeleteView(PermissionRequiredContainerCrudMixin, error_msg = 'Registro não pode ser removido, pois\ é referenciado por outros registros:
\ ' - + + username = request.user.username + self.logger.error("user=" + username + ". Registro não pode ser removido, pois " + "é referenciado por outros registros: " + error_msg2) messages.add_message(request, messages.ERROR, error_msg) @@ -1062,12 +1091,14 @@ class MasterDetailCrud(Crud): class ListView(Crud.ListView): permission_required = RP_LIST, + logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): return r'^(?P\d+)/%s$' % cls.model._meta.model_name def get_context_data(self, **kwargs): + obj = self.crud if hasattr(self, 'crud') else self context = CrudListView.get_context_data(self, **kwargs) @@ -1098,7 +1129,9 @@ class MasterDetailCrud(Crud): try: parent_object = parent_model.objects.get(**params) - except: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) raise Http404() context[ @@ -1119,6 +1152,7 @@ class MasterDetailCrud(Crud): class CreateView(Crud.CreateView): permission_required = RP_ADD, + logger = logging.getLogger(__name__) def dispatch(self, request, *args, **kwargs): return PermissionRequiredMixin.dispatch( @@ -1144,6 +1178,7 @@ class MasterDetailCrud(Crud): return form def get_context_data(self, **kwargs): + obj = self.crud if hasattr(self, 'crud') else self context = Crud.CreateView.get_context_data( self, **kwargs) @@ -1161,7 +1196,9 @@ class MasterDetailCrud(Crud): try: parent_object = parent_model.objects.get(**params) - except Exception: + except Exception as e: + username = self.request.user.username + self.logger.error("user=" + username + ". " + str(e)) raise Http404() else: parent_model = self.model diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 80ceff110..ca428b277 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1,6 +1,6 @@ import os - +import logging import django_filters from crispy_forms.bootstrap import Alert, FormActions, InlineRadios from crispy_forms.helper import FormHelper @@ -119,6 +119,8 @@ class ReceberProposicaoForm(Form): class MateriaSimplificadaForm(ModelForm): + logger = logging.getLogger(__name__) + class Meta: model = MateriaLegislativa fields = ['tipo', 'numero', 'ano', 'data_apresentacao', @@ -156,6 +158,8 @@ class MateriaSimplificadaForm(ModelForm): ano = cleaned_data['ano'] if data_apresentacao.year != ano: + self.logger.error("O ano da matéria ({}) é diferente" + " do ano na data de apresentação ({}).".format(ano, data_apresentacao.year)) raise ValidationError("O ano da matéria não pode ser " "diferente do ano na data de apresentação") @@ -164,6 +168,8 @@ class MateriaSimplificadaForm(ModelForm): class MateriaLegislativaForm(ModelForm): + logger = logging.getLogger(__name__) + tipo_autor = ModelChoiceField(label=_('Tipo Autor'), required=False, queryset=TipoAutor.objects.all(), @@ -204,6 +210,8 @@ class MateriaLegislativaForm(ModelForm): if protocolo: if not Protocolo.objects.filter(numero=protocolo,ano=ano).exists(): + self.logger.error("Protocolo %s/%s não" + " existe" % (protocolo, ano)) raise ValidationError(_('Protocolo %s/%s não' ' existe' % (protocolo, ano))) @@ -217,15 +225,23 @@ class MateriaLegislativaForm(ModelForm): ano=ano).exists() if exist_materia or exist_doc: + self.logger.error("Protocolo %s/%s ja possui" + " documento vinculado" + % (protocolo, ano)) raise ValidationError(_('Protocolo %s/%s ja possui' ' documento vinculado' % (protocolo, ano))) p = Protocolo.objects.get(numero=protocolo,ano=ano) if p.tipo_materia != cleaned_data['tipo']: + self.logger.error("Tipo do Protocolo ({}) deve ser o mesmo do Tipo Matéria ({})." + .format(cleaned_data['tipo'], p.tipo_materia)) raise ValidationError(_('Tipo do Protocolo deve ser o mesmo do Tipo Matéria')) if data_apresentacao.year != ano: + self.logger.error("O ano da matéria ({}) é diferente " + "do ano na data de apresentação ({})." + .format(ano, data_apresentacao.year)) raise ValidationError(_("O ano da matéria não pode ser " "diferente do ano na data de apresentação")) @@ -234,6 +250,9 @@ class MateriaLegislativaForm(ModelForm): if ano_origem_externa and data_origem_externa and \ ano_origem_externa != data_origem_externa.year: + self.logger.error("O ano de origem externa da matéria ({}) é " + " diferente do ano na data de origem externa ({})." + .format(ano_origem_externa, data_origem_externa)) raise ValidationError(_("O ano de origem externa da matéria não " "pode ser diferente do ano na data de " "origem externa")) @@ -260,6 +279,8 @@ class MateriaLegislativaForm(ModelForm): class UnidadeTramitacaoForm(ModelForm): + logger = logging.getLogger(__name__) + class Meta: model = UnidadeTramitacao fields = ['comissao', 'orgao', 'parlamentar'] @@ -278,6 +299,7 @@ class UnidadeTramitacaoForm(ModelForm): if len(cleaned_data) != 1: msg = _('Somente um campo deve ser preenchido!') + self.logger.error("Somente um campo deve ser preenchido!") raise ValidationError(msg) return cleaned_data @@ -329,6 +351,8 @@ class DocumentoAcessorioForm(ModelForm): class RelatoriaForm(ModelForm): + logger = logging.getLogger(__name__) + class Meta: model = Relatoria fields = ['data_designacao_relator', 'comissao', 'parlamentar', @@ -348,8 +372,12 @@ class RelatoriaForm(ModelForm): cleaned_data = self.cleaned_data try: + self.logger.debug("Tentando obter objeto Comissao.") comissao = Comissao.objects.get(id=self.initial['comissao']) - except ObjectDoesNotExist: + except ObjectDoesNotExist as e: + self.logger.error("Objeto Comissao não encontrado com id={} " + ".A localização atual deve ser uma comissão. " + .format(self.initial['comissao']) + str(e)) msg = _('A localização atual deve ser uma comissão.') raise ValidationError(msg) else: @@ -365,6 +393,8 @@ class TramitacaoForm(ModelForm): initial=False, label=_("Urgente?")) + logger = logging.getLogger(__name__) + class Meta: model = Tramitacao fields = ['data_tramitacao', @@ -407,11 +437,16 @@ class TramitacaoForm(ModelForm): if ultima_tramitacao: destino = ultima_tramitacao.unidade_tramitacao_destino if (destino != self.cleaned_data['unidade_tramitacao_local']): + self.logger.error("A origem da nova tramitação ({}) não é igual ao " + "destino da última adicionada ({})!" + .format(self.cleaned_data['unidade_tramitacao_local'], destino)) msg = _('A origem da nova tramitação deve ser igual ao ' 'destino da última adicionada!') raise ValidationError(msg) if cleaned_data['data_tramitacao'] > timezone.now().date(): + self.logger.error('A data de tramitação informada ({}) não é ' + + 'menor ou igual a data de hoje!'.format(cleaned_data['data_tramitacao'])) msg = _( 'A data de tramitação deve ser ' + 'menor ou igual a data de hoje!') @@ -421,18 +456,27 @@ class TramitacaoForm(ModelForm): data_tram_form < ultima_tramitacao.data_tramitacao): msg = _('A data da nova tramitação deve ser ' + 'maior que a data da última tramitação!') + self.logger.error("A data da nova tramitação ({}) deve ser " + "maior que a data da última tramitação ({})!" + .format(data_tram_form, ultima_tramitacao.data_tramitacao)) raise ValidationError(msg) if data_enc_form: if data_enc_form < data_tram_form: msg = _('A data de encaminhamento deve ser ' + 'maior que a data de tramitação!') + self.logger.error("A data de encaminhamento ({}) deve ser " + "maior que a data de tramitação! ({})" + .format(data_enc_form, data_tram_form)) raise ValidationError(msg) if data_prazo_form: if data_prazo_form < data_tram_form: msg = _('A data fim de prazo deve ser ' + 'maior que a data de tramitação!') + self.logger.error("A data fim de prazo ({}) deve ser " + + "maior que a data de tramitação ({})!" + .format(data_prazo_form, data_tram_form)) raise ValidationError(msg) return cleaned_data @@ -445,6 +489,8 @@ class TramitacaoUpdateForm(TramitacaoForm): data_tramitacao = forms.DateField(widget=forms.HiddenInput()) + logger = logging.getLogger(__name__) + class Meta: model = Tramitacao fields = ['data_tramitacao', @@ -479,6 +525,11 @@ class TramitacaoUpdateForm(TramitacaoForm): if ultima_tramitacao != self.instance: if self.cleaned_data['unidade_tramitacao_destino'] != \ self.instance.unidade_tramitacao_destino: + self.logger.error("Você não pode mudar a Unidade de Destino desta " + "tramitação para {}, pois irá conflitar com a Unidade " + "Local da tramitação seguinte ({})." + .format(self.cleaned_data['unidade_tramitacao_destino'], + self.instance.unidade_tramitacao_destino)) raise ValidationError( 'Você não pode mudar a Unidade de Destino desta ' 'tramitação, pois irá conflitar com a Unidade ' @@ -505,6 +556,8 @@ class LegislacaoCitadaForm(ModelForm): ano = forms.CharField(label='Ano', required=True) + logger = logging.getLogger(__name__) + class Meta: model = LegislacaoCitada fields = ['tipo', @@ -532,11 +585,16 @@ class LegislacaoCitadaForm(ModelForm): cleaned_data = self.cleaned_data try: + self.logger.debug("Tentando obter objeto NormalJuridica (numero={}, ano={}, tipo={})." + .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) norma = NormaJuridica.objects.get( numero=cleaned_data['numero'], ano=cleaned_data['ano'], tipo=cleaned_data['tipo']) except ObjectDoesNotExist: + self.logger.error("A norma a ser inclusa (numero={}, ano={}, tipo={}) " + "não existe no cadastro de Normas." + .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) msg = _('A norma a ser inclusa não existe no cadastro' ' de Normas.') raise ValidationError(msg) @@ -562,10 +620,12 @@ class LegislacaoCitadaForm(ModelForm): if not self.instance.id: if filtro_base.exists(): msg = _('Essa Legislação já foi cadastrada.') + self.logger.error("Essa Legislação já foi cadastrada.") raise ValidationError(msg) else: if filtro_base.exclude(id=self.instance.id).exists(): msg = _('Essa Legislação já foi cadastrada.') + self.logger.error("Essa Legislação já foi cadastrada.") raise ValidationError(msg) return cleaned_data @@ -579,6 +639,7 @@ class LegislacaoCitadaForm(ModelForm): class NumeracaoForm(ModelForm): + logger = logging.getLogger(__name__) class Meta: model = Numeracao fields = ['tipo_materia', @@ -593,6 +654,9 @@ class NumeracaoForm(ModelForm): return self.cleaned_data try: + self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}. tipo={})." + .format(self.cleaned_data['numero_materia'], + self.cleaned_data['ano_materia'], self.cleaned_data['tipo_materia'])) MateriaLegislativa.objects.get( numero=self.cleaned_data['numero_materia'], ano=self.cleaned_data['ano_materia'], @@ -600,6 +664,9 @@ class NumeracaoForm(ModelForm): except ObjectDoesNotExist: msg = _('A matéria a ser inclusa não existe no cadastro' ' de matérias legislativas.') + self.logger.error("A MateriaLegislativa a ser inclusa (numero={}, ano={}. tipo={}) não existe no cadastro de matérias legislativas." + .format(self.cleaned_data['numero_materia'], + self.cleaned_data['ano_materia'], self.cleaned_data['tipo_materia'])) raise ValidationError(msg) if Numeracao.objects.filter( @@ -609,6 +676,9 @@ class NumeracaoForm(ModelForm): numero_materia=self.cleaned_data['numero_materia'] ).exists(): msg = _('Essa numeração já foi cadastrada.') + self.logger.error("Essa numeração (materia={}, tipo_materia={}, ano_materia={}, numero_materia={}) " + "já foi cadastrada.".format(self.instance.materia, self.cleaned_data['tipo_materia'], + self.cleaned_data['ano_materia'], self.cleaned_data['numero_materia'])) raise ValidationError(msg) return self.cleaned_data @@ -616,6 +686,8 @@ class NumeracaoForm(ModelForm): class AnexadaForm(ModelForm): + logger = logging.getLogger(__name__) + tipo = forms.ModelChoiceField( label='Tipo', required=True, @@ -640,24 +712,30 @@ class AnexadaForm(ModelForm): cleaned_data = self.cleaned_data try: + self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})." + .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) materia_anexada = MateriaLegislativa.objects.get( numero=cleaned_data['numero'], ano=cleaned_data['ano'], tipo=cleaned_data['tipo']) except ObjectDoesNotExist: - msg = _('A matéria a ser anexada não existe no cadastro' - ' de matérias legislativas.') + msg = _('A MateriaLegislativa a ser anexada (numero={}, ano={}, tipo={}) não existe no cadastro' + ' de matérias legislativas.'.format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) + self.logger.error("A matéria a ser anexada não existe no cadastro" + " de matérias legislativas.") raise ValidationError(msg) materia_principal = self.instance.materia_principal if materia_principal == materia_anexada: + self.logger.error("Matéria não pode ser anexada a si mesma.") raise ValidationError(_('Matéria não pode ser anexada a si mesma')) is_anexada = Anexada.objects.filter(materia_principal=materia_principal, materia_anexada=materia_anexada ).exists() if is_anexada: - raise ValidationError(_('Materia já se encontra anexada')) + self.logger.error("Matéria já se encontra anexada.") + raise ValidationError(_('Matéria já se encontra anexada')) cleaned_data['materia_anexada'] = materia_anexada @@ -679,7 +757,7 @@ class MateriaLegislativaFilterSet(django_filters.FilterSet): filter_overrides = {models.DateField: { 'filter_class': django_filters.DateFromToRangeFilter, 'extra': lambda f: { - 'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')), + 'label': '%s (%s)' % (f.verbose_name, _('Inicial Final')), 'widget': RangeWidgetOverride} }} @@ -858,6 +936,8 @@ class AutoriaForm(ModelForm): data_relativa = forms.DateField( widget=forms.HiddenInput(), required=False) + logger = logging.getLogger(__name__) + def __init__(self, *args, **kwargs): super(AutoriaForm, self).__init__(*args, **kwargs) @@ -889,6 +969,7 @@ class AutoriaForm(ModelForm): if ((not pk and autorias.exists()) or (pk and autorias.exclude(pk=pk).exists())): + self.logger.error("Esse Autor (pk={}) já foi cadastrado.".format(pk)) raise ValidationError(_('Esse Autor já foi cadastrado.')) return cd @@ -896,6 +977,8 @@ class AutoriaForm(ModelForm): class AutoriaMultiCreateForm(Form): + logger = logging.getLogger(__name__) + tipo_autor = ModelChoiceField(label=_('Tipo Autor'), required=False, queryset=TipoAutor.objects.all(), @@ -937,6 +1020,7 @@ class AutoriaMultiCreateForm(Form): del self.errors['autores'] if 'autor' not in cd or not cd['autor'].exists(): + self.logger.error("Ao menos um autor deve ser selecionado para inclusão") raise ValidationError( _('Ao menos um autor deve ser selecionado para inclusão')) @@ -1049,6 +1133,8 @@ class TramitacaoEmLoteFilterSet(django_filters.FilterSet): class TipoProposicaoForm(ModelForm): + logger = logging.getLogger(__name__) + content_type = forms.ModelChoiceField( queryset=ContentType.objects.all(), label=TipoProposicao._meta.get_field('content_type').verbose_name, @@ -1112,11 +1198,14 @@ class TipoProposicaoForm(ModelForm): if 'tipo_conteudo_related' not in cd or not cd[ 'tipo_conteudo_related']: + self.logger.error("Seleção de Tipo não definida.") raise ValidationError( - _('Seleção de Tipo não definida')) + _('Seleção de Tipo não definida.')) if not content_type.model_class().objects.filter( pk=cd['tipo_conteudo_related']).exists(): + self.logger.error("O Registro definido (%s) não está na base de %s." + % (cd['tipo_conteudo_related'], content_type)) raise ValidationError( _('O Registro definido (%s) não está na base de %s.' ) % (cd['tipo_conteudo_related'], content_type)) @@ -1200,6 +1289,8 @@ class TipoProposicaoSelect(Select): class ProposicaoForm(forms.ModelForm): + logger = logging.getLogger(__name__) + TIPO_TEXTO_CHOICE = [ ('D', _('Arquivo Digital')), ('T', _('Texto Articulado')) @@ -1318,6 +1409,7 @@ class ProposicaoForm(forms.ModelForm): texto_original = self.cleaned_data.get('texto_original', False) if texto_original and texto_original.size > MAX_DOC_UPLOAD_SIZE: max_size = str(MAX_DOC_UPLOAD_SIZE / (1024 * 1024)) + self.logger.error("- Arquivo muito grande. ( > {0}MB )".format(max_size)) raise ValidationError( "Arquivo muito grande. ( > {0}MB )".format(max_size)) return texto_original @@ -1350,14 +1442,20 @@ class ProposicaoForm(forms.ModelForm): if tm and am and nm: try: + self.logger.debug("Tentando obter objeto MateriaLegislativa (tipo_id={}, ano={}, numero={})." + .format(tm, am, nm)) materia_de_vinculo = MateriaLegislativa.objects.get( tipo_id=tm, ano=am, numero=nm ) except ObjectDoesNotExist: + self.logger.error("Objeto MateriaLegislativa vinculada (tipo_id={}, ano={}, numero={}) não existe!" + .format(tm, am, nm)) raise ValidationError(_('Matéria Vinculada não existe!')) else: + self.logger.info("MateriaLegislativa vinculada (tipo_id={}, ano={}, numero={}) com sucesso." + .format(tm, am, nm)) cd['materia_de_vinculo'] = materia_de_vinculo return cd @@ -1404,6 +1502,8 @@ class DevolverProposicaoForm(forms.ModelForm): justificativa_devolucao = forms.CharField( required=False, widget=widgets.Textarea(attrs={'rows': 5})) + logger = logging.getLogger(__name__) + class Meta: model = Proposicao fields = [ @@ -1442,6 +1542,7 @@ class DevolverProposicaoForm(forms.ModelForm): if 'justificativa_devolucao' not in cd or\ not cd['justificativa_devolucao']: # TODO Implementar notificação ao autor por email + self.logger.error("Adicione uma Justificativa para devolução.") raise ValidationError( _('Adicione uma Justificativa para devolução.')) return cd @@ -1533,6 +1634,7 @@ class ConfirmarProposicaoForm(ProposicaoForm): self.instance = kwargs.get('instance', None) if not self.instance: + self.logger.error("Erro na Busca por proposição a incorporar") raise ValueError(_('Erro na Busca por proposição a incorporar')) if self.instance.tipo.content_type.model_class() == TipoDocumento: @@ -1625,6 +1727,9 @@ class ConfirmarProposicaoForm(ProposicaoForm): numeracao = sapl.base.models.AppConfig.attr('sequencia_numeracao') if not numeracao: + self.logger.error("A sequência de numeração (por ano ou geral)" + " não foi configurada para a aplicação em " + "tabelas auxiliares") raise ValidationError("A sequência de numeração (por ano ou geral)" " não foi configurada para a aplicação em " "tabelas auxiliares") @@ -1635,12 +1740,14 @@ class ConfirmarProposicaoForm(ProposicaoForm): TipoMateriaLegislativa: if 'regime_tramitacao' not in cd or\ not cd['regime_tramitacao']: + self.logger.error("Regime de Tramitação deve ser informado.") raise ValidationError( _('Regime de Tramitação deve ser informado.')) elif self.instance.tipo.content_type.model_class( ) == TipoDocumento and not cd['materia_de_vinculo']: - + self.logger.error("Documentos não podem ser incorporados sem definir " + "para qual Matéria Legislativa ele se destina.") raise ValidationError( _('Documentos não podem ser incorporados sem definir ' 'para qual Matéria Legislativa ele se destina.')) @@ -1692,9 +1799,11 @@ class ConfirmarProposicaoForm(ProposicaoForm): numeracao = None try: + self.logger.debug("Tentando obter modelo de sequência de numeração.") numeracao = sapl.base.models.AppConfig.objects.last( ).sequencia_numeracao - except AttributeError: + except AttributeError as e: + self.logger.error("Erro ao obter modelo. " + str(e)) pass tipo = self.instance.tipo.tipo_conteudo_related @@ -1905,6 +2014,9 @@ class MateriaAssuntoForm(ModelForm): class EtiquetaPesquisaForm(forms.Form): + + logger = logging.getLogger(__name__) + tipo_materia = forms.ModelChoiceField( label=TipoMateriaLegislativa._meta.verbose_name, queryset=TipoMateriaLegislativa.objects.all(), @@ -1966,12 +2078,16 @@ class EtiquetaPesquisaForm(forms.Form): # preencheu o Final, ou vice-versa if (not cleaned_data['data_inicial'] or not cleaned_data['data_final']): + self.logger.error("Caso pesquise por data, os campos de Data Incial e " + "Data Final devem ser preenchidos obrigatoriamente") raise ValidationError(_( 'Caso pesquise por data, os campos de Data Incial e ' + 'Data Final devem ser preenchidos obrigatoriamente')) # Caso tenha preenchido, verifica se a data final é maior que # a inicial elif cleaned_data['data_final'] < cleaned_data['data_inicial']: + self.logger.error("A Data Final ({}) não pode ser menor que a Data Inicial({})." + .format(cleaned_data['data_final'], cleaned_data['data_inicial'])) raise ValidationError(_( 'A Data Final não pode ser menor que a Data Inicial')) @@ -1980,12 +2096,17 @@ class EtiquetaPesquisaForm(forms.Form): cleaned_data['processo_final']): if (not cleaned_data['processo_inicial'] or not cleaned_data['processo_final']): + self.logger.error("Caso pesquise por número de processo, os campos de " + "Processo Inicial e Processo Final " + "devem ser preenchidos obrigatoriamente") raise ValidationError(_( 'Caso pesquise por número de processo, os campos de ' + 'Processo Inicial e Processo Final ' + 'devem ser preenchidos obrigatoriamente')) elif (cleaned_data['processo_final'] < cleaned_data['processo_inicial']): + self.logger.error("O processo final ({}) não pode ser menor que o inicial ({})." + .format(cleaned_data['processo_final'], cleaned_data['processo_inicial'])) raise ValidationError(_( 'O processo final não pode ser menor que o inicial')) @@ -1993,6 +2114,9 @@ class EtiquetaPesquisaForm(forms.Form): class FichaPesquisaForm(forms.Form): + + logger = logging.getLogger(__name__) + tipo_materia = forms.ModelChoiceField( label=TipoMateriaLegislativa._meta.verbose_name, queryset=TipoMateriaLegislativa.objects.all(), @@ -2037,6 +2161,8 @@ class FichaPesquisaForm(forms.Form): return cleaned_data if cleaned_data['data_final'] < cleaned_data['data_inicial']: + self.logger.error("A Data Final ({}) não pode ser menor que a Data Inicial ({})." + .format(cleaned_data['data_final'], cleaned_data['data_inicial'])) raise ValidationError(_( 'A Data Final não pode ser menor que a Data Inicial')) @@ -2067,6 +2193,8 @@ class FichaSelecionaForm(forms.Form): class ExcluirTramitacaoEmLote(forms.Form): + logger = logging.getLogger(__name__) + data_tramitacao = forms.DateField(required=True, label=_('Data da Tramitação')) @@ -2103,6 +2231,11 @@ class ExcluirTramitacaoEmLote(forms.Form): unidade_tramitacao_destino=unidade_tramitacao_destino, status=status) if not tramitacao_set.exists(): + self.logger.error("Não existem tramitações com os dados informados " + " (data_tramitacao={}, unidade_tramitacao_local={})." + "unidade_tramitacao_destino={}, status={})." + .format(data_tramitacao, unidade_tramitacao_local, + unidade_tramitacao_destino, status)) raise forms.ValidationError( _("Não existem tramitações com os dados informados.")) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index e3d62c2bf..c923ccb0f 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -7,7 +7,7 @@ from crispy_forms.layout import HTML from django.contrib import messages from django.contrib.auth.decorators import permission_required from django.contrib.auth.mixins import PermissionRequiredMixin -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.core.urlresolvers import reverse from django.db.models import Max from django.http import HttpResponse, JsonResponse @@ -21,6 +21,7 @@ from django.views.generic.base import RedirectView from django.views.generic.edit import FormView from django_filters.views import FilterView import weasyprint +import logging import sapl from sapl.base.models import Autor, CasaLegislativa @@ -92,11 +93,16 @@ def autores_ja_adicionados(materia_pk): def proposicao_texto(request, pk): + logger = logging.getLogger(__name__) + username = request.user.username.replace("'","") + logger.debug('user=' + username + '. Tentando obter objeto Proposicao com pk = {}.'.format(pk)) proposicao = Proposicao.objects.get(pk=pk) if proposicao.texto_original: if (not proposicao.data_recebimento and proposicao.autor.user_id != request.user.id): + logger.error("user=" + username + ". Usuário ({}) não tem permissão para acessar o texto original." + .format(request.user.id)) messages.error(request, _( 'Você não tem permissão para acessar o texto original.')) return redirect(reverse('sapl.materia:proposicao_detail', @@ -113,6 +119,7 @@ def proposicao_texto(request, pk): response['Content-Disposition'] = ( 'inline; filename="%s"' % arquivo.name.split('/')[-1]) return response + logger.error('user=' + username + '. Objeto Proposicao com pk={} não encontrado.'.format(pk)) raise Http404 @@ -165,6 +172,7 @@ class CriarProtocoloMateriaView(CreateView): template_name = "crud/form.html" form_class = MateriaSimplificadaForm form_valid_message = _('Matéria cadastrada com sucesso!') + logger = logging.getLogger(__name__) def get_success_url(self, materia): return reverse('sapl.materia:materialegislativa_detail', kwargs={ @@ -173,19 +181,25 @@ class CriarProtocoloMateriaView(CreateView): def get_context_data(self, **kwargs): context = super( CriarProtocoloMateriaView, self).get_context_data(**kwargs) + username = self.request.user.username.replace("'","") try: + self.logger.debug("user=" + username + ". Tentando obter objeto Protocolo.") protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) - except ObjectDoesNotExist: + except ObjectDoesNotExist as e: + self.logger.error("user=" + username + ". Objeto Protocolo com pk={} não encontrado. ".format(self.kwargs['pk']) + str(e)) raise Http404() numero = 1 try: + self.logger.debug("user=" + username + ". Tentando obter materias do último ano.") materias_ano = MateriaLegislativa.objects.filter( ano=protocolo.ano, tipo=protocolo.tipo_materia).latest('numero') numero = materias_ano.numero + 1 except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Não foram encontradas matérias no último ano ({}). " + "Definido 1 como padrão.".format(protocolo.ano)) pass # numero ficou com o valor padrão 1 acima context['form'].fields['tipo'].initial = protocolo.tipo_materia @@ -199,10 +213,13 @@ class CriarProtocoloMateriaView(CreateView): def form_valid(self, form): materia = form.save() + username = self.request.user.username.replace("'","") try: + self.logger.info("user=" + username + ". Tentando obter objeto Procolo com pk={}.".format(self.kwargs['pk'])) protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto Protocolo com pk={} não encontrado.'.format(self.kwargs['pk'])) raise Http404() if protocolo.autor: @@ -286,14 +303,18 @@ class ProposicaoTaView(IntegracaoTaView): @permission_required('materia.detail_materialegislativa') def recuperar_materia(request): + logger = logging.getLogger(__name__) + username = request.user.username.replace("'","") tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo']) ano = request.GET.get('ano', '') numeracao = None try: + logger.debug("user=" + username + ". Tentando obter numeração da matéria.") numeracao = sapl.base.models.AppConfig.objects.last( ).sequencia_numeracao - except AttributeError: + except AttributeError as e: + logger.error("user=" + username + ". " + str(e) + " Numeracao da matéria definida como None.") pass if tipo.sequencia_numeracao: @@ -526,20 +547,24 @@ class RetornarProposicao(UpdateView): model = Proposicao fields = ['data_envio', 'descricao' ] permission_required = ('materia.detail_proposicao_enviada', ) + logger = logging.getLogger(__name__) def dispatch(self, request, *args, **kwargs): - + username = request.user.username.replace("'","") try: + self.logger.info("user=" + username + ". Tentando obter objeto Proposicao com id={}.".format(kwargs['pk'])) p = Proposicao.objects.get(id=kwargs['pk']) except: + self.logger.error("user=" + username + ". Objeto Proposicao com id={} não encontrado.".format(kwargs['pk'])) raise Http404() if p.autor.user != request.user: - messages.error( + self.logger.error("user=" + username + ". Usuário ({}) sem acesso a esta opção.".format(request.user)) + messages.error( request, 'Usuário sem acesso a esta opção.' % request.user) - return redirect('/') + return redirect('/') return super(RetornarProposicao, self).dispatch( request, *args, **kwargs) @@ -550,6 +575,7 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): template_name = "materia/confirmar_proposicao.html" model = Proposicao form_class = ConfirmarProposicaoForm, DevolverProposicaoForm + logger = logging.getLogger(__name__) def get_success_url(self): msgs = self.object.results['messages'] @@ -561,12 +587,15 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): return self.object.results['url'] def get_object(self, queryset=None): + username = self.request.user.username.replace("'","") + try: """ Não deve haver acesso na rotina de confirmação a proposições: já recebidas -> data_recebimento != None não enviadas -> data_envio == None """ + self.logger.debug("user=" + username + ". Tentando obter objeto Proposicao.") proposicao = Proposicao.objects.get(pk=self.kwargs['pk'], data_envio__isnull=False, data_recebimento__isnull=True) @@ -582,10 +611,13 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): if hasher == 'P%s/%s' % (self.kwargs['hash'], proposicao.pk): self.object = proposicao - except: + except Exception as e: + self.logger.error("user=" + username + ". Objeto Proposicao com atributos (pk={}, data_envio=Not Null, " + "data_recebimento=Null) não encontrado. ".format(self.kwargs['pk']) + str(e)) raise Http404() if not self.object: + self.logger.error("user=" + username + ". Objeto vazio.") raise Http404() return self.object @@ -701,6 +733,7 @@ class ProposicaoCrud(Crud): 'materia.detail_proposicao_devolvida', 'materia.detail_proposicao_incorporada') + logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['subnav_template_name'] = '' @@ -711,7 +744,9 @@ class ProposicaoCrud(Crud): return context def get(self, request, *args, **kwargs): + action = request.GET.get('action', '') + username = request.user.username.replace("'","") if not action: return Crud.DetailView.get(self, request, *args, **kwargs) @@ -743,23 +778,32 @@ class ProposicaoCrud(Crud): messages.success(request, _( 'Proposição enviada com sucesso.')) try: + self.logger.debug("user=" + username + ". Tentando obter número do objeto MateriaLegislativa com " + "atributos tipo={} e ano={}." + .format(p.tipo.tipo_conteudo_related, p.ano)) numero = MateriaLegislativa.objects.filter(tipo=p.tipo.tipo_conteudo_related, ano=p.ano).last().numero + 1 messages.success(request, _( '%s : nº %s de %s
Atenção! Este número é apenas um provável ' 'número que pode não corresponder com a realidade' % (p.tipo, numero, p.ano))) - except ValueError: + except ValueError as e: + self.logger.error("user=" + username + "." + str(e)) pass - except AttributeError: + except AttributeError as e: + self.logger.error("user=" + username + "." + str(e)) pass - except TypeError: + except TypeError as e: + self.logger.error("user=" + username + "." + str(e)) pass elif action == 'return': if not p.data_envio: + self.logger.error("user=" + username + ". Proposição (numero={}) ainda não foi enviada.".format(p.numero_proposicao)) msg_error = _('Proposição ainda não foi enviada.') elif p.data_recebimento: + self.logger.error("user=" + username + ". Proposição (numero={}) já foi recebida, não é " + "possível retorná-la.".format(p.numero_proposicao)) msg_error = _('Proposição já foi recebida, não é ' 'possível retorná-la.') else: @@ -770,6 +814,7 @@ class ProposicaoCrud(Crud): ta.privacidade = STATUS_TA_PRIVATE ta.editing_locked = False ta.save() + self.logger.info("user=" + username + ". Proposição (numero={}) Retornada com sucesso.".format(p.numero_proposicao)) messages.success(request, _( 'Proposição Retornada com sucesso.')) @@ -781,10 +826,12 @@ class ProposicaoCrud(Crud): kwargs={'pk': kwargs['pk']})) def dispatch(self, request, *args, **kwargs): - + username = request.user.username.replace("'","") try: + self.logger.debug("user=" + username + ". Tentando obter objeto Proposicao com pk={}".format(kwargs['pk'])) p = Proposicao.objects.get(id=kwargs['pk']) - except: + except Exception as e: + self.logger.error("user=" + username + ". Erro ao obter proposicao com pk={}. Retornando 404. ".format(kwargs['pk']) + str(e)) raise Http404() if not self.has_permission(): @@ -813,16 +860,25 @@ class ProposicaoCrud(Crud): class DeleteView(BaseLocalMixin, Crud.DeleteView): + logger = logging.getLogger(__name__) + def _action_is_valid(self, request, *args, **kwargs): proposicao = Proposicao.objects.filter( id=kwargs['pk']).values_list( 'data_envio', 'data_recebimento') + username = request.user.username.replace("'","") + if proposicao: if proposicao[0][0] and proposicao[0][1]: + self.logger.error("user=" + username + ". Proposição (id={}) já foi enviada e recebida." + "Não pode mais ser excluida.".format(kwargs['pk'])) msg = _('Proposição já foi enviada e recebida.' 'Não pode mais ser excluida.') elif proposicao[0][0] and not proposicao[0][1]: + self.logger.error("user=" + username + ". Proposição (id={}) já foi enviada mas ainda não recebida " + "pelo protocolo. Use a opção Recuperar Proposição " + "para depois excluí-la.".format(kwargs['pk'])) msg = _('Proposição já foi enviada mas ainda não recebida ' 'pelo protocolo. Use a opção Recuperar Proposição ' 'para depois excluí-la.') @@ -834,17 +890,26 @@ class ProposicaoCrud(Crud): class UpdateView(BaseLocalMixin, Crud.UpdateView): + logger = logging.getLogger(__name__) + def _action_is_valid(self, request, *args, **kwargs): proposicao = Proposicao.objects.filter( id=kwargs['pk']).values_list( 'data_envio', 'data_recebimento') + + username = request.user.username.replace("'","") if proposicao: if proposicao[0][0] and proposicao[0][1]: + self.logger.error('user=' + username + '. Proposição (id={}) já foi enviada e recebida.' + 'Não pode mais ser editada'.format(kwargs['pk'])) msg = _('Proposição já foi enviada e recebida.' 'Não pode mais ser editada') elif proposicao[0][0] and not proposicao[0][1]: + self.logger.error('user=' + username + '. Proposição (id={}) já foi enviada mas ainda não recebida ' + 'pelo protocolo. Use a opção Recuperar Proposição ' + 'para voltar para edição.'.format(kwargs['pk'])) msg = _('Proposição já foi enviada mas ainda não recebida ' 'pelo protocolo. Use a opção Recuperar Proposição ' 'para voltar para edição.') @@ -857,6 +922,7 @@ class ProposicaoCrud(Crud): def get_success_url(self): tipo_texto = self.request.POST.get('tipo_texto', '') + username = self.request.user.username.replace("'","") if tipo_texto == 'T': messages.info(self.request, @@ -864,12 +930,17 @@ class ProposicaoCrud(Crud): 'alterada e a opção "Texto Articulado " for ' 'marcada, você será redirecionado para a ' 'edição do Texto Eletrônico.')) + self.logger.debug('user=' + username + '. Sempre que uma Proposição é inclusa ou ' + 'alterada e a opção "Texto Articulado " for ' + 'marcada, você será redirecionado para a ' + 'edição do Texto Eletrônico.') return reverse('sapl.materia:proposicao_ta', kwargs={'pk': self.object.pk}) else: return Crud.UpdateView.get_success_url(self) class CreateView(Crud.CreateView): + logger = logging.getLogger(__name__) form_class = ProposicaoForm layout_key = None @@ -881,6 +952,7 @@ class ProposicaoCrud(Crud): def get_success_url(self): tipo_texto = self.request.POST.get('tipo_texto', '') + username = self.request.user.username.replace("'","") if tipo_texto == 'T': messages.info(self.request, @@ -889,6 +961,11 @@ class ProposicaoCrud(Crud): 'marcada, você será redirecionado para o ' 'Texto Eletrônico. Use a opção "Editar Texto" ' 'para construir seu texto.')) + self.logger.debug('user=' + username + '. Sempre que uma Proposição é inclusa ou ' + 'alterada e a opção "Texto Articulado " for ' + 'marcada, você será redirecionado para o ' + 'Texto Eletrônico. Use a opção "Editar Texto" ' + 'para construir seu texto.') return reverse('sapl.materia:proposicao_ta', kwargs={'pk': self.object.pk}) else: @@ -920,6 +997,7 @@ class ProposicaoCrud(Crud): class ReciboProposicaoView(TemplateView): + logger = logging.getLogger(__name__) template_name = "materia/recibo_proposicao.html" permission_required = ('materia.detail_proposicao', ) @@ -957,14 +1035,18 @@ class ReciboProposicaoView(TemplateView): def get(self, request, *args, **kwargs): proposicao = Proposicao.objects.get(pk=self.kwargs['pk']) + username = request.user.username.replace("'","") if proposicao.data_envio: return TemplateView.get(self, request, *args, **kwargs) if not proposicao.data_envio and not proposicao.data_devolucao: + self.logger.error('user=' + username + '. Não é possível gerar recibo para uma ' + 'Proposição (pk={}) ainda não enviada.'.format(self.kwargs['pk'])) messages.error(request, _('Não é possível gerar recibo para uma ' 'Proposição ainda não enviada.')) elif proposicao.data_devolucao: + self.logger.error("user=" + username + ". Não é possível gerar recibo para proposicao de pk={}.".format(self.kwargs['pk'])) messages.error(request, _('Não é possível gerar recibo.')) return redirect(reverse('sapl.materia:proposicao_detail', @@ -979,17 +1061,22 @@ class RelatoriaCrud(MasterDetailCrud): class CreateView(MasterDetailCrud.CreateView): form_class = RelatoriaForm + logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) + username = self.request.user.username.replace("'","") try: + self.logger.debug("user=" + username + ". Tentando obter objeto Comissao de pk={}.".format(context['form'].initial['comissao'])) comissao = Comissao.objects.get( pk=context['form'].initial['comissao']) except: + self.logger.error("user=" + username + ". Objeto Comissão de pk={} não encontrado.".format(context['form'].initial['comissao'])) pass else: + self.logger.info("user=" + username + ". Objeto Comissao de pk={} obtido com sucesso.".format(context['form'].initial['comissao'])) composicao = comissao.composicao_set.order_by( '-periodo__data_inicio').first() participacao = Participacao.objects.filter( @@ -1025,15 +1112,22 @@ class RelatoriaCrud(MasterDetailCrud): class UpdateView(MasterDetailCrud.UpdateView): form_class = RelatoriaForm + logger = logging.getLogger(__name__) + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + username = self.request.user.username.replace("'","") try: + self.logger.debug("user=" + username + ". Tentando obter objeto Comissao de pk={}.".format(context['form'].initial['comissao'])) comissao = Comissao.objects.get( pk=context['form'].initial['comissao']) - except ObjectDoesNotExist: + except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Objeto Comissão de pk={} não encontrado.".format(context['form'].initial['comissao'])) pass - else: + else: + self.logger.info("user=" + username + ". Objeto Comissao de pk={} obtido com sucesso.".format(context['form'].initial['comissao'])) composicao = comissao.composicao_set.order_by( '-periodo__data_inicio').first() participacao = Participacao.objects.filter( @@ -1061,6 +1155,7 @@ class TramitacaoCrud(MasterDetailCrud): class CreateView(MasterDetailCrud.CreateView): form_class = TramitacaoForm + logger = logging.getLogger(__name__) def get_success_url(self): return reverse('sapl.materia:tramitacao_list', kwargs={ @@ -1083,6 +1178,7 @@ class TramitacaoCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) + username = self.request.user.username.replace("'","") ultima_tramitacao = Tramitacao.objects.filter( materia_id=self.kwargs['pk']).order_by( @@ -1097,6 +1193,8 @@ class TramitacaoCrud(MasterDetailCrud): (ultima_tramitacao.unidade_tramitacao_destino.pk, ultima_tramitacao.unidade_tramitacao_destino)] else: + self.logger.error('user=' + username + '. Unidade de tramitação destino ' + 'da última tramitação não pode ser vazia!') msg = _('Unidade de tramitação destino ' ' da última tramitação não pode ser vazia!') messages.add_message(self.request, messages.ERROR, msg) @@ -1104,7 +1202,9 @@ class TramitacaoCrud(MasterDetailCrud): return context def form_valid(self, form): + self.object = form.save() + username = self.request.user.username.replace("'","") if form.instance.status.indicador == 'F': form.instance.materia.em_tramitacao = False @@ -1113,25 +1213,32 @@ class TramitacaoCrud(MasterDetailCrud): form.instance.materia.save() try: + self.logger.debug("user=" + username + ". Tentando enviar Tramitacao (sender={}, post={}, request={})." + .format(Tramitacao, self.object, self.request)) tramitacao_signal.send(sender=Tramitacao, post=self.object, request=self.request) - except Exception: + except Exception as e: # TODO log error msg = _('Tramitação criada, mas e-mail de acompanhamento ' 'de matéria não enviado. Há problemas na configuração ' 'do e-mail.') + self.logger.warning('user=' + username + '. Tramitação criada, mas e-mail de acompanhamento ' + 'de matéria não enviado. Há problemas na configuração ' + 'do e-mail. ' + str(e)) messages.add_message(self.request, messages.WARNING, msg) return HttpResponseRedirect(self.get_success_url()) return super().form_valid(form) class UpdateView(MasterDetailCrud.UpdateView): form_class = TramitacaoUpdateForm + logger = logging.getLogger(__name__) layout_key = 'TramitacaoUpdate' def form_valid(self, form): self.object = form.save() + username = self.request.user.username.replace("'","") if form.instance.status.indicador == 'F': form.instance.materia.em_tramitacao = False @@ -1140,6 +1247,8 @@ class TramitacaoCrud(MasterDetailCrud): form.instance.materia.save() try: + self.logger.debug("user=" + username + ". Tentando enviar Tramitacao (sender={}, post={}, request={}" + .format(Tramitacao, self.object, self.request)) tramitacao_signal.send(sender=Tramitacao, post=self.object, request=self.request) @@ -1148,6 +1257,9 @@ class TramitacaoCrud(MasterDetailCrud): msg = _('Tramitação atualizada, mas e-mail de acompanhamento ' 'de matéria não enviado. Há problemas na configuração ' 'do e-mail.') + self.logger.warning('user=' + username + '. Tramitação atualizada, mas e-mail de acompanhamento ' + 'de matéria não enviado. Há problemas na configuração ' + 'do e-mail.') messages.add_message(self.request, messages.WARNING, msg) return HttpResponseRedirect(self.get_success_url()) return super().form_valid(form) @@ -1163,6 +1275,8 @@ class TramitacaoCrud(MasterDetailCrud): class DeleteView(MasterDetailCrud.DeleteView): + logger = logging.getLogger(__name__) + def delete(self, request, *args, **kwargs): tramitacao = Tramitacao.objects.get(id=self.kwargs['pk']) materia = MateriaLegislativa.objects.get(id=tramitacao.materia.id) @@ -1173,8 +1287,13 @@ class TramitacaoCrud(MasterDetailCrud): '-data_tramitacao', '-timestamp', '-id').first() + + username = request.user.username.replace("'","") if tramitacao.pk != ultima_tramitacao.pk: + self.logger.error("user=" + username + ". Não é possível deletar a tramitação de pk={}. " + "Somente a última tramitação (pk={}) pode ser deletada!." + .format(tramitacao.pk, ultima_tramitacao.pk)) msg = _('Somente a última tramitação pode ser deletada!') messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(url) @@ -1515,7 +1634,11 @@ class DocumentoAcessorioView(PermissionRequiredMixin, CreateView): class AcompanhamentoConfirmarView(TemplateView): + logger = logging.getLogger(__name__) + def get_redirect_url(self, email): + username = self.request.user.username.replace("'","") + self.logger.debug('user=' + username + '. Esta matéria está sendo acompanhada pelo e-mail: %s' % (email)) msg = _('Esta matéria está sendo acompanhada pelo e-mail: %s') % ( email) messages.add_message(self.request, messages.SUCCESS, msg) @@ -1525,18 +1648,24 @@ class AcompanhamentoConfirmarView(TemplateView): def get(self, request, *args, **kwargs): materia_id = kwargs['pk'] hash_txt = request.GET.get('hash_txt', '') + username = self.request.user.username.replace("'","") try: + self.logger.info("user=" + username + ". Tentando obter objeto AcompanhamentoMateria (materia_id={}, hash={})." + .format(materia_id, hash_txt)) acompanhar = AcompanhamentoMateria.objects.get( materia_id=materia_id, hash=hash_txt) except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Objeto AcompanhamentoMateria(materia_id={}, hash={}) não encontrado." + .format(materia_id, hash_txt)) raise Http404() - # except MultipleObjectsReturned: + except MultipleObjectsReturned as e: # A melhor solução deve ser permitir que a exceção # (MultipleObjectsReturned) seja lançada e vá para o log, # pois só poderá ser causada por um erro de desenvolvimente - + self.logger.error('user=' + username + '.' + str(e)) + pass acompanhar.confirmado = True acompanhar.save() @@ -1545,7 +1674,11 @@ class AcompanhamentoConfirmarView(TemplateView): class AcompanhamentoExcluirView(TemplateView): + logger = logging.getLogger(__name__) + def get_success_url(self): + username = self.request.user.username.replace("'","") + self.logger.debug("user=" + username + ". Você parou de acompanhar esta matéria.") msg = _('Você parou de acompanhar esta matéria.') messages.add_message(self.request, messages.INFO, msg) return reverse('sapl.materia:materialegislativa_detail', @@ -1554,11 +1687,16 @@ class AcompanhamentoExcluirView(TemplateView): def get(self, request, *args, **kwargs): materia_id = kwargs['pk'] hash_txt = request.GET.get('hash_txt', '') + username = self.request.user.username.replace("'","") try: + self.logger.info("user=" + username + ". Tentando deletar objeto AcompanhamentoMateria (materia_id={}, hash={})." + .format(materia_id, hash_txt)) AcompanhamentoMateria.objects.get(materia_id=materia_id, hash=hash_txt).delete() except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Objeto AcompanhamentoMateria (materia_id={}, hash={}) não encontrado." + .format(materia_id, hash_txt)) pass return HttpResponseRedirect(self.get_success_url()) @@ -1642,6 +1780,7 @@ class MateriaLegislativaPesquisaView(FilterView): class AcompanhamentoMateriaView(CreateView): + logger = logging.getLogger(__name__) template_name = "materia/acompanhamento_materia.html" def get_random_chars(self): @@ -1693,7 +1832,9 @@ class AcompanhamentoMateriaView(CreateView): "materia", materia, destinatario) - + self.logger.debug('user=' + usuario.username + '. Foi enviado um e-mail de confirmação. Confira sua caixa \ + de mensagens e clique no link que nós enviamos para \ + confirmar o acompanhamento desta matéria.') msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ confirmar o acompanhamento desta matéria.') @@ -1702,6 +1843,7 @@ class AcompanhamentoMateriaView(CreateView): # Caso esse Acompanhamento já exista # avisa ao usuário que essa matéria já está sendo acompanhada else: + self.logger.debug("user=" + usuario.username + ". Este e-mail já está acompanhando essa matéria.") msg = _('Este e-mail já está acompanhando essa matéria.') messages.add_message(request, messages.INFO, msg) @@ -1780,6 +1922,8 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): primeira_tramitacao = True + logger = logging.getLogger(__name__) + def get_context_data(self, **kwargs): context = super(PrimeiraTramitacaoEmLoteView, self).get_context_data(**kwargs) @@ -1822,10 +1966,13 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): def post(self, request, *args, **kwargs): + marcadas = request.POST.getlist('materia_id') tz = timezone.get_current_timezone() + username = request.user.username.replace("'","") + if len(marcadas) == 0: msg = _('Nenhuma máteria foi selecionada.') messages.add_message(request, messages.ERROR, msg) @@ -1877,10 +2024,15 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): ) t.save() try: + self.logger.debug("user=" + username + ". Tentando enviar tramitação.") tramitacao_signal.send(sender=Tramitacao, post=t, request=self.request) - except Exception: + + except Exception as e: + self.logger.error('user=' + username + '. Tramitação criada , mas e-mail de acompanhamento ' + 'de matéria não enviado. Há problemas na configuração ' + 'do e-mail. ' + str(e)) flag_error = True if flag_error: msg = _('Tramitação criada, mas e-mail de acompanhamento ' @@ -1898,6 +2050,7 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): materia.save() msg = _('Tramitação completa.') + self.logger.info('user=' + username + '. Tramitação completa.') messages.add_message(request, messages.SUCCESS, msg) return self.get(request, self.kwargs) @@ -2003,6 +2156,7 @@ class FichaPesquisaView(PermissionRequiredMixin, FormView): class FichaSelecionaView(PermissionRequiredMixin, FormView): + logger = logging.getLogger(__name__) form_class = FichaSelecionaForm template_name = 'materia/impressos/ficha_seleciona.html' permission_required = ('materia.can_access_impressos', ) @@ -2031,8 +2185,16 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView): context['form'].fields['materia'].choices = [ (m.id, str(m)) for m in materia_list] + + username = self.request.user.username.replace("'","") if context['quantidade'] > 100: + self.logger.info('user=' + username + '. Sua pesquisa (tipo={}, data_inicial={}, data_final={}) retornou mais do que ' + '100 impressos. Por questões de ' + 'performance, foram retornados ' + 'apenas os 100 primeiros. Caso ' + 'queira outros, tente fazer uma ' + 'pesquisa mais específica'.format(tipo, data_inicial, data_final)) messages.info(self.request, _('Sua pesquisa retornou mais do que ' '100 impressos. Por questões de ' 'performance, foram retornados ' @@ -2044,11 +2206,14 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView): def form_valid(self, form): context = {} + username = self.request.user.username.replace("'","") try: + self.logger.debug("user=" + username + ". Tentando obter objeto MateriaLegislativa com id={}".format(form.data['materia'])) materia = MateriaLegislativa.objects.get( id=form.data['materia']) except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Esta MáteriaLegislativa não existe (id={}).".format(form.data['materia'])) mensagem = _('Esta Máteria não existe!') self.messages.add_message(self.request, messages.INFO, mensagem) diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index 818d6ba38..d4f0046a6 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -1,5 +1,6 @@ import django_filters +import logging from crispy_forms.helper import FormHelper from crispy_forms.layout import Fieldset, Layout from django import forms @@ -105,6 +106,8 @@ class NormaJuridicaForm(ModelForm): widget=forms.Select(attrs={'autocomplete': 'off'}) ) + logger = logging.getLogger(__name__) + class Meta: model = NormaJuridica fields = ['tipo', @@ -129,6 +132,7 @@ class NormaJuridicaForm(ModelForm): def clean(self): + cleaned_data = super(NormaJuridicaForm, self).clean() if not self.is_valid(): @@ -137,6 +141,7 @@ class NormaJuridicaForm(ModelForm): import re has_digits = re.sub('[^0-9]', '', cleaned_data['numero']) if not has_digits: + self.logger.error("Número de norma ({}) não pode conter somente letras.".format(cleaned_data['numero'])) raise ValidationError('Número de norma não pode conter somente letras') if self.instance.numero != cleaned_data['numero']: @@ -144,24 +149,35 @@ class NormaJuridicaForm(ModelForm): numero=cleaned_data['numero'], tipo=cleaned_data['tipo']).exists() if norma: + self.logger.error("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 " "e Número no sistema") if (cleaned_data['tipo_materia'] and - cleaned_data['numero_materia'] and - cleaned_data['ano_materia']): + cleaned_data['numero_materia'] and + cleaned_data['ano_materia']): try: + self.logger.debug("Tentando obter objeto MateriaLegislativa com tipo={}, numero={}, ano={}." + .format(cleaned_data['tipo_materia'], cleaned_data['numero_materia'], cleaned_data['ano_materia'])) materia = MateriaLegislativa.objects.get( tipo_id=cleaned_data['tipo_materia'], numero=cleaned_data['numero_materia'], ano=cleaned_data['ano_materia']) except ObjectDoesNotExist: + self.logger.error("Matéria Legislativa %s/%s (%s) é inexistente." % ( + self.cleaned_data['numero_materia'], + self.cleaned_data['ano_materia'], + cleaned_data['tipo_materia'].descricao)) raise forms.ValidationError( _("Matéria Legislativa %s/%s (%s) é inexistente." % ( self.cleaned_data['numero_materia'], self.cleaned_data['ano_materia'], cleaned_data['tipo_materia'].descricao))) else: + self.logger.info("MateriaLegislativa com tipo={}, numero={}, ano={} obtida com sucesso." + .format(cleaned_data['tipo_materia'], cleaned_data['numero_materia'], cleaned_data['ano_materia'])) cleaned_data['materia'] = materia else: @@ -171,6 +187,8 @@ class NormaJuridicaForm(ModelForm): data = cleaned_data['data'] if data.year != ano: + self.logger.error("O ano da norma ({}) é diferente " + "do ano no campo data ({}).".format(ano, data.year)) raise ValidationError("O ano da norma não pode ser " "diferente do ano no campo data") return cleaned_data @@ -179,6 +197,8 @@ class NormaJuridicaForm(ModelForm): texto_integral = self.cleaned_data.get('texto_integral', False) if texto_integral and texto_integral.size > MAX_DOC_UPLOAD_SIZE: max_size = str(MAX_DOC_UPLOAD_SIZE / (1024 * 1024)) + tam_fornecido = str( texto_integral.size / (1024*1024) ) + self.logger.error("Arquivo muito grande ({}MB). ( Tamanho máximo permitido: {}MB )".format(tam_fornecido, max_size)) raise ValidationError( "Arquivo muito grande. ( > {0}MB )".format(max_size)) return texto_integral @@ -202,6 +222,8 @@ class AutoriaNormaForm(ModelForm): data_relativa = forms.DateField( widget=forms.HiddenInput(), required=False) + logger = logging.getLogger(__name__) + def __init__(self, *args, **kwargs): super(AutoriaNormaForm, self).__init__(*args, **kwargs) @@ -233,6 +255,7 @@ class AutoriaNormaForm(ModelForm): if ((not pk and autorias.exists()) or (pk and autorias.exclude(pk=pk).exists())): + self.logger.error("Autor ({}) já foi cadastrado.".format(cd['autor'])) raise ValidationError(_('Esse Autor já foi cadastrado.')) return cd @@ -245,6 +268,7 @@ class AnexoNormaJuridicaForm(ModelForm): 'norma': forms.HiddenInput(), } + logger = logging.getLogger(__name__) def clean(self): cleaned_data = super(AnexoNormaJuridicaForm, self).clean() if not self.is_valid(): @@ -252,6 +276,8 @@ class AnexoNormaJuridicaForm(ModelForm): anexo_arquivo = self.cleaned_data.get('anexo_arquivo', False) if anexo_arquivo and anexo_arquivo.size > MAX_DOC_UPLOAD_SIZE: max_size = str(MAX_DOC_UPLOAD_SIZE / (1024 * 1024)) + tam_fornecido = str( anexo_arquivo.size / (1024*1024) ) + self.logger.error("Arquivo muito grande ({}MB). ( Tamanho máximo permitido: {}MB )".format(tam_fornecido, max_size)) raise ValidationError( "Arquivo muito grande. ( > {0}MB )".format(max_size)) return cleaned_data @@ -282,6 +308,7 @@ class NormaRelacionadaForm(ModelForm): required=False, widget=forms.Textarea(attrs={'disabled': 'disabled'})) + logger = logging.getLogger(__name__) class Meta: model = NormaRelacionada fields = ['tipo', 'numero', 'ano', 'ementa', 'tipo_vinculo'] @@ -297,14 +324,17 @@ class NormaRelacionadaForm(ModelForm): cleaned_data = self.cleaned_data try: + self.logger.debug("Tentando obter objeto NormaJuridica com numero={}, ano={}, tipo={}.".format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) norma_relacionada = NormaJuridica.objects.get( numero=cleaned_data['numero'], ano=cleaned_data['ano'], tipo=cleaned_data['tipo']) except ObjectDoesNotExist: + self.logger.info("NormaJuridica com numero={}, ano={}, tipo={} não existe.".format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) msg = _('A norma a ser relacionada não existe.') raise ValidationError(msg) else: + self.logger.info("NormaJuridica com numero={}, ano={}, tipo={} obtida com sucesso.".format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) cleaned_data['norma_relacionada'] = norma_relacionada return cleaned_data @@ -340,6 +370,8 @@ class NormaPesquisaSimplesForm(forms.Form): required=False, max_length=150) + logger = logging.getLogger(__name__) + def __init__(self, *args, **kwargs): super(NormaPesquisaSimplesForm, self).__init__(*args, **kwargs) @@ -373,12 +405,15 @@ class NormaPesquisaSimplesForm(forms.Form): if (data_inicial and data_final and 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')) else: condicao1 = data_inicial and not data_final condicao2 = not data_inicial and data_final if condicao1 or condicao2: + self.logger.error("Caso pesquise por data, os campos de Data Inicial e " + "Data Final devem ser preenchidos obrigatoriamente") raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e ' + 'Data Final devem ser preenchidos obrigatoriamente')) diff --git a/sapl/norma/views.py b/sapl/norma/views.py index b91aec2a5..faca58d32 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -1,5 +1,6 @@ import re +import logging from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.exceptions import ObjectDoesNotExist @@ -199,16 +200,22 @@ class NormaCrud(Crud): class CreateView(Crud.CreateView): form_class = NormaJuridicaForm + logger = logging.getLogger(__name__) + @property def cancel_url(self): return self.search_url def get_initial(self): + username = self.request.user.username + try: + self.logger.debug('user=' + username + '. Tentando obter objeto de modelo da esfera da federação.') esfera = sapl.base.models.AppConfig.objects.last( ).esfera_federacao self.initial['esfera_federacao'] = esfera except: + self.logger.error('user=' + username + '. Erro ao obter objeto de modelo da esfera da federação.') pass self.initial['complemento'] = False return self.initial @@ -241,17 +248,24 @@ class NormaCrud(Crud): def recuperar_norma(request): + logger = logging.getLogger(__name__) + username = request.user.username + tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo']) numero = request.GET['numero'] ano = request.GET['ano'] try: + logger.info('user=' + username + '. Tentando obter NormaJuridica (tipo={}, ano={}, numero={}).' + .format(tipo, ano, numero)) norma = NormaJuridica.objects.get(tipo=tipo, ano=ano, numero=numero) response = JsonResponse({'ementa': norma.ementa, 'id': norma.id}) except ObjectDoesNotExist: + logger.error('user=' + username + '. NormaJuridica buscada (tipo={}, ano={}, numero={}) não existe. ' + 'Definida com ementa vazia e id 0.'.format(tipo, ano, numero)) response = JsonResponse({'ementa': '', 'id': 0}) return response diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 88d0aa785..963e53019 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -1,5 +1,6 @@ import html import json +import logging from django.contrib import messages from django.contrib.auth.decorators import user_passes_test @@ -42,6 +43,9 @@ def votacao_aberta(request): nenhuma. É utilizada como uma função auxiliar para a view votante_view. ''' + logger = logging.getLogger(__name__) + username = request.user.username + votacoes_abertas = SessaoPlenaria.objects.filter( Q(ordemdia__votacao_aberta=True) | Q(expedientemateria__votacao_aberta=True)).distinct() @@ -53,7 +57,9 @@ def votacao_aberta(request): reverse('sapl.sessao:sessaoplenaria_detail', kwargs={'pk': v.id}), v.__str__())) - + logger.info('user=' + username + '. Existe mais de uma votações aberta. Elas se encontram ' + 'nas seguintes Sessões: ' + ', '.join(msg_abertas) + '. ' + 'Para votar, peça para que o Operador feche-as.') msg = _('Existe mais de uma votações aberta. Elas se encontram ' 'nas seguintes Sessões: ' + ', '.join(msg_abertas) + '. ' 'Para votar, peça para que o Operador feche-as.') @@ -70,6 +76,11 @@ def votacao_aberta(request): numero_materias_abertas = len(ordens) + len(expedientes) if numero_materias_abertas > 1: + logger.info('user=' + username + '. Existe mais de uma votação aberta na Sessão: ' + + ('''
  • %s
  • ''' % ( + reverse('sapl.sessao:sessaoplenaria_detail', + kwargs={'pk': votacoes_abertas.first().id}), + votacoes_abertas.first().__str__()))) msg = _('Existe mais de uma votação aberta na Sessão: ' + ('''
  • %s
  • ''' % ( reverse('sapl.sessao:sessaoplenaria_detail', @@ -83,7 +94,7 @@ def votacao_aberta(request): def votacao(context,context_vars): - + logger = logging.getLogger(__name__) parlamentar = context_vars['votante'].parlamentar parlamentar_presente = False if parlamentar.id in context_vars['presentes']: @@ -105,13 +116,17 @@ def votacao(context,context_vars): if voto: try: + logger.debug("Tentando obter objeto VotoParlamentar com parlamentar={}.".format(context_vars['parlamentar'])) voto = voto.get(parlamentar=context_vars['parlamentar']) context.update({'voto_parlamentar': voto.voto}) except ObjectDoesNotExist: + logger.error("Voto do parlamentar {} não computado.".format(context_vars['parlamentar'])) context.update( {'voto_parlamentar': 'Voto não ' 'computado.'}) else: + logger.error("Parlamentar com id={} não está presente na " + "Ordem do Dia/Expediente em votação.".format(parlamentar.id)) context.update({'error_message': 'Você não está presente na ' 'Ordem do Dia/Expediente em votação.'}) @@ -185,14 +200,20 @@ def can_vote(context, context_vars, request): def votante_view(request): + logger = logging.getLogger(__name__) + username = request.user.username + # Pega o votante relacionado ao usuário template_name = 'painel/voto_nominal.html' context = {} context_vars = {} try: + logger.debug('user=' + username + '. Tentando obter objeto Votante com user={}.'.format(request.user)) votante = Votante.objects.get(user=request.user) except ObjectDoesNotExist: + logger.error("user=" + username + ". Usuário (user={}) não cadastrado como votante na tela de parlamentares. " + "Contate a administração de sua Casa Legislativa!".format(request.user)) msg = _("Usuário não cadastrado como votante na tela de parlamentares. Contate a administração de sua Casa Legislativa!") context.update({ 'error_message':msg @@ -205,8 +226,9 @@ def votante_view(request): # Verifica se usuário possui permissão para votar if 'parlamentares.can_vote' in request.user.get_all_permissions(): context, context_vars = can_vote(context, context_vars, request) - + logger.debug("user=" + username + ". Verificando se usuário {} possui permissão para votar.".format(request.user)) else: + logger.error("user=" + username + ". Usuário {} sem permissão para votar.".format(request.user)) context.update({'permissao': False, 'error_message': 'Usuário sem permissão para votar.'}) @@ -214,10 +236,14 @@ def votante_view(request): if request.method == 'POST': if context_vars['ordem_dia']: try: + logger.info("user=" + username + ". Tentando obter objeto VotoParlamentar para parlamentar={} e ordem={}." + .format(context_vars['parlamentar'], context_vars['ordem_dia'])) voto = VotoParlamentar.objects.get( parlamentar=context_vars['parlamentar'], ordem=context_vars['ordem_dia']) except ObjectDoesNotExist: + logger.error("user=" + username + ". Erro ao obter VotoParlamentar para parlamentar={} e ordem={}. Criando objeto." + .format(context_vars['parlamentar'], context_vars['ordem_dia'])) voto = VotoParlamentar.objects.create( parlamentar=context_vars['parlamentar'], voto=request.POST['voto'], @@ -225,6 +251,8 @@ def votante_view(request): ip=get_client_ip(request), ordem=context_vars['ordem_dia']) else: + logger.info("user=" + username + ". VotoParlamentar para parlamentar={} e ordem={} obtido com sucesso." + .format(context_vars['parlamentar'], context_vars['ordem_dia'])) voto.voto = request.POST['voto'] voto.ip = get_client_ip(request) voto.user = request.user @@ -232,10 +260,14 @@ def votante_view(request): elif context_vars['expediente']: try: + logger.info("user=" + username + ". Tentando obter objeto VotoParlamentar para parlamentar={} e expediente={}." + .format(context_vars['parlamentar'], context_vars['expediente'])) voto = VotoParlamentar.objects.get( parlamentar=context_vars['parlamentar'], expediente=context_vars['expediente']) except ObjectDoesNotExist: + logger.error("user=" + username + ". Erro ao obter VotoParlamentar para parlamentar={} e expediente={}. Criando objeto." + .format(context_vars['parlamentar'], context_vars['expediente'])) voto = VotoParlamentar.objects.create( parlamentar=context_vars['parlamentar'], voto=request.POST['voto'], @@ -243,6 +275,8 @@ def votante_view(request): ip=get_client_ip(request), expediente=context_vars['expediente']) else: + logger.info("user=" + username + ". VotoParlamentar para parlamentar={} e expediente={} obtido com sucesso." + .format(context_vars['parlamentar'], context_vars['expediente'])) voto.voto = request.POST['voto'] voto.ip = get_client_ip(request) voto.user = request.user @@ -304,9 +338,14 @@ def cronometro_painel(request): def get_cronometro_status(request, name): + logger = logging.getLogger(__name__) + username = request.user.username + try: + logger.debug("user=" + username + ". Tentando obter cronometro.") cronometro = request.session[name] - except KeyError: + except KeyError as e: + logger.error("user=" + username + ". Erro ao obter cronometro. Retornado como vazio. " + str(e)) cronometro = '' return cronometro @@ -402,6 +441,7 @@ def response_nenhuma_materia(response): def get_votos(response, materia): + logger = logging.getLogger(__name__) if type(materia) == OrdemDia: registro = RegistroVotacao.objects.filter( ordem=materia, materia=materia.materia).last() @@ -433,9 +473,12 @@ def get_votos(response, materia): for i, p in enumerate(response['presentes']): try: + logger.info("Tentando obter votos do parlamentar (id={}).".format(p['parlamentar_id'])) if votos_parlamentares.get(parlamentar_id=p['parlamentar_id']).voto: response['presentes'][i]['voto'] = 'Voto Informado' except ObjectDoesNotExist: + logger.error("Votos do parlamentar (id={}) não encontrados. Retornado vazio." + .format(p['parlamentar_id'])) response['presentes'][i]['voto'] = '' else: @@ -450,9 +493,11 @@ def get_votos(response, materia): for i, p in enumerate(response['presentes']): try: + logger.debug("Tentando obter votos do parlamentar (id={}).".format(p['parlamentar_id'])) response['presentes'][i]['voto'] = votos_parlamentares.get( parlamentar_id=p['parlamentar_id']).voto except ObjectDoesNotExist: + logger.error("Votos do parlamentar (id={}) não encontrados. Retornado None.".format(p['parlamentar_id'])) response['presentes'][i]['voto'] = None response.update({ diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py old mode 100644 new mode 100755 index 6ae314785..36237d448 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -1,3 +1,5 @@ +import logging + from datetime import timedelta from crispy_forms.helper import FormHelper @@ -40,9 +42,12 @@ class CustomImageCropWidget(ImageCropWidget): def validar_datas_legislatura(eleicao, inicio, fim, pk=None): - + logger = logging.getLogger(__name__) # Verifica se data de eleição < inicio < fim if inicio >= fim or eleicao >= inicio: + logger.error('A data início ({}) deve ser menor que a ' + + 'data fim ({}) e a data eleição ({}) deve ser ' + + 'menor que a data início ({})'.format(inicio, fim, eleicao, inicio)) msg_error = _('A data início deve ser menor que a ' + 'data fim e a data eleição deve ser ' + 'menor que a data início') @@ -53,12 +58,15 @@ def validar_datas_legislatura(eleicao, inicio, fim, pk=None): data_inicio__lte=fim, data_fim__gte=inicio ).exclude(pk=pk).exists() if intersecao_legislatura: + logger.error("Já existe uma legislatura neste intervalo de datas (data_inicio<={} e data_fim>={})." + .format(fim, inicio)) msg_error = _('Já existe uma legislatura neste intervalo de datas') return (False, msg_error) # Verifica se há alguma outra data de eleição cadastrada if Legislatura.objects.filter( data_eleicao=eleicao).exclude(pk=pk).exists(): + logger.error("Esta data de eleição ({}) já foi cadastrada.".format(eleicao)) msg_error = _('Esta data de eleição já foi cadastrada') return (False, msg_error) @@ -66,7 +74,7 @@ def validar_datas_legislatura(eleicao, inicio, fim, pk=None): class MandatoForm(ModelForm): - + logger = logging.getLogger(__name__) class Meta: model = Mandato fields = ['legislatura', 'coligacao', 'votos_recebidos', @@ -89,6 +97,9 @@ class MandatoForm(ModelForm): if data_inicio_mandato: if (data_inicio_mandato < legislatura.data_inicio or data_inicio_mandato > legislatura.data_fim): + self.logger.error("Data início mandato ({}) fora do intervalo" + " de legislatura informada ({} a {})." + .format(data_inicio_mandato, legislatura.data_inicio, legislatura.data_fim)) raise ValidationError(_("Data início mandato fora do intervalo" " de legislatura informada")) @@ -96,17 +107,27 @@ class MandatoForm(ModelForm): if data_fim_mandato: if (data_fim_mandato < legislatura.data_inicio or data_fim_mandato > legislatura.data_fim): + self.logger.error("Data fim mandato ({}) fora do intervalo" + " de legislatura informada ({} a {})." + .format(data_fim_mandato, legislatura.data_inicio, legislatura.data_fim)) raise ValidationError(_("Data fim mandato fora do intervalo de" " legislatura informada")) data_expedicao_diploma = data['data_expedicao_diploma'] if (data_expedicao_diploma and data_expedicao_diploma > data_inicio_mandato): + self.logger.error("A data da expedição do diploma ({}) deve ser anterior " + "a data de início do mandato ({}).".format(data_expedicao_diploma, data_inicio_mandato)) raise ValidationError(_("A data da expedição do diploma deve ser anterior " "a data de início do mandato")) coligacao = data['coligacao'] if coligacao and not coligacao.legislatura == legislatura: + self.logger.error("A coligação selecionada ({}) não está cadastrada " + "na mesma legislatura ({}) que o presente mandato ({}), " + "favor verificar a coligação ou fazer o cadastro " + "de uma nova coligação na legislatura correspondente" + .format(coligacao, coligacao.legislatura, legislatura)) raise ValidationError(_("A coligação selecionada não está cadastrada " "na mesma legislatura que o presente mandato, " "favor verificar a coligação ou fazer o cadastro " @@ -116,6 +137,8 @@ class MandatoForm(ModelForm): parlamentar=data['parlamentar'], legislatura=data['legislatura']).exists() if existe_mandato: + self.logger.error("Mandato nesta legislatura (parlamentar={}, legislatura={}) já existe." + .format(data['parlamentar'], data['legislatura'])) raise ValidationError(_('Mandato nesta legislatura já existe.')) return self.cleaned_data @@ -123,6 +146,8 @@ class MandatoForm(ModelForm): class LegislaturaForm(ModelForm): + logger = logging.getLogger(__name__) + class Meta: model = Legislatura exclude = [] @@ -148,8 +173,13 @@ class LegislaturaForm(ModelForm): ).order_by('data_fim').first() if ultima_legislatura and ultima_legislatura.numero >= numero: + self.logger.error("Número ({}) deve ser maior que o da legislatura anterior ({})." + .format(numero, ultima_legislatura.numero)) raise ValidationError(_("Número deve ser maior que o da legislatura anterior")) elif proxima_legislatura and proxima_legislatura.numero <= numero: + self.logger.error("O Número ({}) deve ser menor que {}, pois existe uma " + "legislatura afrente cronologicamente desta que está sendo criada!" + .format(numero, proxima_legislatura.numero)) msg_erro = "O Número deve ser menor que {}, pois existe uma " \ "legislatura afrente cronologicamente desta que está sendo criada!" msg_erro = msg_erro.format(proxima_legislatura.numero) @@ -222,8 +252,13 @@ class ParlamentarCreateForm(ParlamentarForm): def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): + + logger = logging.getLogger(__name__) + # Verifica se data de desfiliacao é anterior a data de filiacao if data_desfiliacao and data_desfiliacao < data_filiacao: + logger.error("A data de desfiliação ({}) é anterior à data de filiação ({})." + .format(data_desfiliacao, data_filiacao)) error_msg = _("A data de desfiliação não pode anterior \ à data de filiação") return [False, error_msg] @@ -249,6 +284,8 @@ def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): # filiação em edição não é a última e está sem data de desfiliação if not data_desfiliacao and filiacao_em_edicao_id and\ filiacao_em_edicao_id != filiacoes.last().pk: + logger.error("Data de desfiliação do parlamentar não pode ser " + "ausente, se existirem datas de filiação posteriores.") error_msg = _("Data de desfiliação do parlamentar não pode ser\ ausente, se existirem datas de filiação posteriores.") @@ -256,6 +293,8 @@ def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): # já existe outra sem data de desfiliação elif not data_desfiliacao and not filiacao_em_edicao_id and\ not filiacoes.last().data_desfiliacao: + logger.error("O parlamentar não pode se filiar a novo partido sem" + " antes se desfiliar do partido anterior.") error_msg = _("O parlamentar não pode se filiar a novo partido sem\ antes se desfiliar do partido anterior.") @@ -266,14 +305,20 @@ def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): # testa a intercessão de intervalo com outra filiação if filiacoes.filter(range_livre_exigido).exists(): - error_msg = _("A data de filiação e desfiliação não podem estar\ - no intervalo de outro período de filiação.") + logger.error("A data de filiação e desfiliação não podem estar" + " no intervalo de outro período de filiação.") + error_msg = _("A data de filiação e desfiliação (intervalo de {} a {}) " + "não podem estar no intervalo de outro período de filiação." + .format(data_filiacao, df_desfiliacao, )) if not error_msg: # passou pelo teste de intervalo mas a data de filiação é maior que # a ultima que está em aberto if filiacoes.filter(data_desfiliacao__isnull=True, data__lte=data_filiacao).exists(): + logger.error("Não pode haver um registro de filiação com data de " + "filiação igual ou superior a data de filiação em aberto ({})." + .format(data_filiacao)) error_msg = _("Não pode haver um registro de filiação com data de \ filiação igual ou superior a data de filiação em aberto.") @@ -313,6 +358,8 @@ class FiliacaoForm(ModelForm): class ComposicaoColigacaoForm(ModelForm): + logger = logging.getLogger(__name__) + class Meta: model = ComposicaoColigacao fields = ['partido'] @@ -328,6 +375,8 @@ class ComposicaoColigacaoForm(ModelForm): if (ComposicaoColigacao.objects.filter( coligacao_id=pk, partido=cleaned_data.get('partido')).exists()): + self.logger.error("Esse partido (coligacao_id={} e partido={}) já foi cadastrado " + "nesta coligação.".format(pk, cleaned_data.get('partido'))) msg = _('Esse partido já foi cadastrado nesta coligação.') raise ValidationError(msg) @@ -335,7 +384,7 @@ class ComposicaoColigacaoForm(ModelForm): class FrenteForm(ModelForm): - + logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): super(FrenteForm, self).__init__(*args, **kwargs) self.fields['parlamentares'].queryset = Parlamentar.objects.filter( @@ -354,6 +403,8 @@ class FrenteForm(ModelForm): return self.cleaned_data if cd['data_extincao'] and cd['data_criacao'] >= cd['data_extincao']: + self.logger.error("Data Dissolução ({}) não pode ser anterior a Data Criação ({})." + .format(cd['data_extincao'],cd['data_criacao'])) raise ValidationError(_("Data Dissolução não pode ser anterior a Data Criação")) return cd @@ -383,6 +434,8 @@ class VotanteForm(ModelForm): required=True, max_length=30) + logger = logging.getLogger(__name__) + class Meta: model = Votante fields = ['username'] @@ -413,12 +466,15 @@ class VotanteForm(ModelForm): username = cd['username'] user = get_user_model().objects.filter(username=username) if not user.exists(): + self.logger.error("Não foi possível vincular usuário. Usuário {} não existe.".format(username)) raise ValidationError(_( "{} [{}] {}".format( 'Não foi possível vincular usuário. Usuário', username, 'não existe'))) if Votante.objects.filter(user=user[0].pk).exists(): + self.logger.error("Não foi possível vincular usuário. Usuário {} já está " + "vinculado à outro parlamentar.".format(username)) raise ValidationError(_( "{} [{}] {}".format( 'Não foi possível vincular usuário. Usuário', diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index ad4a8f5e5..fb98cce73 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -1,4 +1,5 @@ import json +import logging from datetime import datetime from django.contrib import messages @@ -267,11 +268,16 @@ def parlamentares_frente_selected(request): """ :return: Lista com o id dos parlamentares em uma frente """ + logger = logging.getLogger(__name__) + username = request.user.username try: + logger.info("user=" + username + ". Tentando objet objeto Frente com id={}.".format(request.GET['frente_id'])) frente = Frente.objects.get(id=int(request.GET['frente_id'])) except ObjectDoesNotExist: + logger.error("user=" + username + ". Frente buscada (id={}) não existe. Retornada lista vazia.".format(request.GET['frente_id'])) lista_parlamentar_id = [] else: + logger.info("user=" + username + ". Frente (id={}) encontrada com sucesso.".format(request.GET['frente_id'])) lista_parlamentar_id = frente.parlamentares.all().values_list( 'id', flat=True) return JsonResponse({'id_list': list(lista_parlamentar_id)}) @@ -349,17 +355,22 @@ class ComposicaoColigacaoCrud(MasterDetailCrud): class LegislaturaCrud(CrudAux): + model = Legislatura help_topic = 'legislatura' class CreateView(CrudAux.CreateView): + logger = logging.getLogger(__name__) form_class = LegislaturaForm def get_initial(self): + username = self.request.user.username try: + self.logger.error("user=" + username + ". Tentando obter última Legislatura.") ultima_legislatura = Legislatura.objects.latest('numero') numero = ultima_legislatura.numero + 1 except Legislatura.DoesNotExist: + self.logger.error("user=" + username + ". Legislatura não encontrada. Número definido como 1.") numero = 1 return {'numero': numero} @@ -451,15 +462,19 @@ class ParlamentarCrud(Crud): class ListView(Crud.ListView): template_name = "parlamentares/parlamentares_list.html" paginate_by = None + logger = logging.getLogger(__name__) @xframe_options_exempt def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def take_legislatura_id(self): + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter id da legislatura.") return int(self.request.GET['pk']) except: + self.logger.error("user=" + username + ". Legislatura não possui ID. Buscando em todas as entradas.") legislaturas = Legislatura.objects.all() for l in legislaturas: if l.atual(): @@ -469,21 +484,26 @@ class ParlamentarCrud(Crud): return -1 def get_queryset(self): + self.logger = logging.getLogger(__name__) queryset = super().get_queryset() legislatura_id = self.take_legislatura_id() # Pelo menos uma casa legislativa criou uma # legislatura de numero zero, o que é um absurdo + username = self.request.user.username if legislatura_id >= 0: return queryset.filter( mandato__legislatura_id=legislatura_id).annotate( mandato_titular=F('mandato__titular')) else: try: + self.logger.debug("user=" + username + ". Tentando obter o mais recente registro do objeto Legislatura.") l = Legislatura.objects.all().order_by( '-data_inicio').first() except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Objeto não encontrado. Retornando todos os registros.") return Legislatura.objects.all() else: + self.logger.info("user=" + username + ". Objeto encontrado com sucesso.") if l is None: return Legislatura.objects.all() return queryset.filter(mandato__legislatura_id=l).annotate( @@ -495,6 +515,7 @@ class ParlamentarCrud(Crud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) + username = self.request.user.username # Adiciona legislatura para filtrar parlamentares legislaturas = Legislatura.objects.all().order_by('-numero') @@ -520,6 +541,9 @@ class ParlamentarCrud(Crud): # da legislatura e data de desfiliação deve nula, ou maior, # ou igual a data de fim da legislatura try: + self.logger.debug("user=" + username + ". Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null))." + .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim)) filiacao = parlamentar.filiacao_set.get(Q( data__lte=legislatura.data_fim, data_desfiliacao__gte=legislatura.data_fim) | Q( @@ -528,17 +552,24 @@ class ParlamentarCrud(Crud): # Caso não exista filiação com essas condições except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null)) não possui filiação." + .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim)) row[1] = ('Não possui filiação', None, None) # Caso exista mais de uma filiação nesse intervalo # Entretanto, NÃO DEVE OCORRER except MultipleObjectsReturned: + self.logger.error("user=" + username + ". O Parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null)) possui duas filiações conflitantes" + .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim)) row[1] = ( 'O Parlamentar possui duas filiações conflitantes', None) # Caso encontre UMA filiação nessas condições else: + self.logger.info("user=" + username + ". Filiação encontrada com sucesso.") row[1] = (filiacao.partido.sigla, None, None) return context @@ -547,6 +578,7 @@ class ParlamentarCrud(Crud): class ParlamentarMateriasView(FormView): template_name = "parlamentares/materias.html" success_url = reverse_lazy('sapl.parlamentares:parlamentar_materia') + logger = logging.getLogger(__name__) def get_autoria(self, resultset): autoria = {} @@ -567,13 +599,15 @@ class ParlamentarMateriasView(FormView): @xframe_options_exempt def get(self, request, *args, **kwargs): parlamentar_pk = kwargs['pk'] - + username = request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter Autor (object_id={}).".format(parlamentar_pk)) autor = Autor.objects.get( content_type=ContentType.objects.get_for_model(Parlamentar), object_id=parlamentar_pk) except ObjectDoesNotExist: - mensagem = _('Este Parlamentar não é autor de matéria.') + mensagem = _('Este Parlamentar (pk={}) não é Autor de matéria.'.format(parlamentar_pk)) + self.logger.error("user=" + username + ". Este Parlamentar (pk={}) não é Autor de matéria.".format(parlamentar_pk)) messages.add_message(request, messages.ERROR, mensagem) return HttpResponseRedirect( reverse( @@ -615,6 +649,7 @@ class ParlamentarMateriasView(FormView): class MesaDiretoraView(FormView): template_name = 'parlamentares/composicaomesa_form.html' success_url = reverse_lazy('sapl.parlamentares:mesa_diretora') + logger = logging.getLogger(__name__) def get_template_names(self): if self.request.user.has_perm('parlamentares.change_composicaomesa'): @@ -628,6 +663,10 @@ class MesaDiretoraView(FormView): # Essa função avisa quando se pode compor uma Mesa Legislativa def validation(self, request): + username = request.user.username + self.logger.info('user=' + username + '. Não há nenhuma Sessão Legislativa cadastrada. ' + + 'Só é possível compor uma Mesa Diretora quando ' + + 'há uma Sessão Legislativa cadastrada.') mensagem = _('Não há nenhuma Sessão Legislativa cadastrada. ' + 'Só é possível compor uma Mesa Diretora quando ' + 'há uma Sessão Legislativa cadastrada.') @@ -693,9 +732,11 @@ def altera_field_mesa(request): operação (Legislatura/Sessão/Inclusão/Remoção), atualizando os campos após cada alteração """ + logger = logging.getLogger(__name__) legislatura = request.GET['legislatura'] sessoes = SessaoLegislativa.objects.filter( legislatura=legislatura).order_by('-data_inicio') + username = request.user.username if not sessoes: return JsonResponse({'msg': ('Nenhuma sessão encontrada!', 0)}) @@ -710,8 +751,11 @@ def altera_field_mesa(request): else: year = timezone.now().year try: + logger.debug("user=" + username + ". Tentando obter id de sessoes com data_inicio.ano={}.".format(year)) sessao_selecionada = sessoes.get(data_inicio__year=year).id except ObjectDoesNotExist: + logger.error("user=" + username + ". Id de sessoes com data_inicio.ano={} não encontrado. " + "Selecionado o ID da primeira sessão.".format(year)) sessao_selecionada = sessoes.first().id # Atualiza os componentes da view após a mudança @@ -751,7 +795,8 @@ def insere_parlamentar_composicao(request): Essa função lida com qualquer operação de inserção na composição da Mesa Diretora """ - + logger = logging.getLogger(__name__) + username = request.user.username if request.user.has_perm( '%s.add_%s' % ( AppConfig.label, ComposicaoMesa._meta.model_name)): @@ -759,19 +804,24 @@ def insere_parlamentar_composicao(request): composicao = ComposicaoMesa() try: + logger.debug("user=" + username + ". Tentando obter SessaoLegislativa com id={}.".format(request.POST['sessao'])) composicao.sessao_legislativa = SessaoLegislativa.objects.get( id=int(request.POST['sessao'])) except MultiValueDictKeyError: + logger.error("user=" + username + ". 'MultiValueDictKeyError', nenhuma sessão foi inserida!") return JsonResponse({'msg': ('Nenhuma sessão foi inserida!', 0)}) try: + logger.debug("user=" + username + ". Tentando obter Parlamentar com id={}.".format(request.POST['parlamentar'])) composicao.parlamentar = Parlamentar.objects.get( id=int(request.POST['parlamentar'])) except MultiValueDictKeyError: + logger.error("user=" + username + ". 'MultiValueDictKeyError', nenhum parlamentar foi inserido!") return JsonResponse({ 'msg': ('Nenhum parlamentar foi inserido!', 0)}) try: + logger.info("user=" + username + ". Tentando obter CargoMesa com id={}.".format(request.POST['cargo'])) composicao.cargo = CargoMesa.objects.get( id=int(request.POST['cargo'])) parlamentar_ja_inserido = ComposicaoMesa.objects.filter( @@ -784,11 +834,14 @@ def insere_parlamentar_composicao(request): composicao.save() except MultiValueDictKeyError: + logger.error("user=" + username + ". 'MultiValueDictKeyError', nenhum cargo foi inserido!") return JsonResponse({'msg': ('Nenhum cargo foi inserido!', 0)}) + logger.info("user=" + username + ". Parlamentar inserido com sucesso!") return JsonResponse({'msg': ('Parlamentar inserido com sucesso!', 1)}) else: + logger.error("user=" + username + " não tem permissão para esta operação!") return JsonResponse( {'msg': ('Você não tem permissão para esta operação!', 0)}) @@ -798,26 +851,32 @@ def remove_parlamentar_composicao(request): Essa função lida com qualquer operação de remoção na composição da Mesa Diretora """ - + logger = logging.getLogger(__name__) + username = request.user.username if request.POST and request.user.has_perm( '%s.delete_%s' % ( AppConfig.label, ComposicaoMesa._meta.model_name)): if 'composicao_mesa' in request.POST: try: + logger.debug("user=" + username + ". Tentando obter ComposicaoMesa com id={}.".format(request.POST['composicao_mesa'])) composicao = ComposicaoMesa.objects.get( id=request.POST['composicao_mesa']) except ObjectDoesNotExist: + logger.error("user=" + username + ". ComposicaoMesa com id={} não encontrada, portanto não pode ser removida." + .format(request.POST['composicao_mesa'])) return JsonResponse( {'msg': ( 'Composição da Mesa não pôde ser removida!', 0)}) composicao.delete() + logger.info("user=" + username + ". ComposicaoMesa com id={} excluido com sucesso!".format(request.POST['composicao_mesa'])) return JsonResponse( {'msg': ( 'Parlamentar excluido com sucesso!', 1)}) else: + logger.info("user=" + username + ". Nenhum parlamentar escolhido para ser excluído.") return JsonResponse( {'msg': ( 'Selecione algum parlamentar para ser excluido!', 0)}) @@ -833,7 +892,13 @@ def partido_parlamentar_sessao_legislativa(sessao, parlamentar): # A data de filiacao deve ser menor que a data de fim # da sessao legislativa e data de desfiliação deve nula, ou maior, # ou igual a data de fim da sessao + logger = logging.getLogger(__name__) try: + logger.debug("Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null))." + .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) + + logger.info("Tentando obter filiação correspondente.") filiacao = parlamentar.filiacao_set.get(Q( data__lte=sessao.data_fim, data_desfiliacao__gte=sessao.data_fim) | Q( @@ -842,15 +907,24 @@ def partido_parlamentar_sessao_legislativa(sessao, parlamentar): # Caso não exista filiação com essas condições except ObjectDoesNotExist: + logger.error("Filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null não encontrada. Retornando vazio." + .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) return '' # Caso exista mais de uma filiação nesse intervalo # Entretanto, NÃO DEVE OCORRER except MultipleObjectsReturned: + logger.error("O Parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null possui duas filiações conflitantes." + .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) return 'O Parlamentar possui duas filiações conflitantes' # Caso encontre UMA filiação nessas condições else: + logger.info("Filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null encontrada com sucesso." + .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) return filiacao.partido.sigla @@ -860,7 +934,8 @@ def altera_field_mesa_public_view(request): da Mesa Diretora para usuários anônimos, atualizando os campos após cada alteração """ - + logger = logging.getLogger(__name__) + username = request.user.username legislatura = request.GET['legislatura'] sessoes = SessaoLegislativa.objects.filter( legislatura=legislatura).order_by('-data_inicio') @@ -877,8 +952,11 @@ def altera_field_mesa_public_view(request): else: try: year = timezone.now().year + logger.info("user=" + username + ". Tentando obter sessões com data_inicio.ano = {}.".format(year)) sessao_selecionada = sessoes.get(data_inicio__year=year).id - except ObjectDoesNotExist as e: + except ObjectDoesNotExist: + logger.error("user=" + username + ". Sessões não encontradas com com data_inicio.ano = {}. " + "Selecionado o id da primeira sessão.".format(year)) sessao_selecionada = sessoes.first().id # Atualiza os componentes da view após a mudança diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index 4df450c61..a621754b7 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -1,5 +1,6 @@ import django_filters +import logging from crispy_forms.bootstrap import InlineRadios from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout @@ -226,6 +227,8 @@ class DocumentoAdministrativoFilterSet(django_filters.FilterSet): class AnularProcoloAdmForm(ModelForm): + logger = logging.getLogger(__name__) + numero = forms.CharField(required=True, label=Protocolo._meta. get_field('numero').verbose_name @@ -252,12 +255,15 @@ class AnularProcoloAdmForm(ModelForm): ano = cleaned_data['ano'] try: + self.logger.debug("Tentando obter Protocolo com numero={} e ano={}.".format(numero, ano)) protocolo = Protocolo.objects.get(numero=numero, ano=ano) if protocolo.anulado: + self.logger.error("Protocolo %s/%s já encontra-se anulado" % (numero, ano)) raise forms.ValidationError( _("Protocolo %s/%s já encontra-se anulado") % (numero, ano)) except ObjectDoesNotExist: + self.logger.error("Protocolo %s/%s não existe" % (numero, ano)) raise forms.ValidationError( _("Protocolo %s/%s não existe" % (numero, ano))) @@ -270,6 +276,8 @@ class AnularProcoloAdmForm(ModelForm): ).order_by('-ano', '-numero').exists() if exists: + self.logger.error("Protocolo %s/%s não pode ser removido pois existem " + "documentos vinculados a ele." % (numero, ano)) raise forms.ValidationError( _("Protocolo %s/%s não pode ser removido pois existem " "documentos vinculados a ele." % (numero, ano))) @@ -386,6 +394,9 @@ class ProtocoloDocumentForm(ModelForm): class ProtocoloMateriaForm(ModelForm): + + logger = logging.getLogger(__name__) + autor = forms.ModelChoiceField(required=True, empty_label='------', queryset=Autor.objects.all() @@ -441,10 +452,13 @@ class ProtocoloMateriaForm(ModelForm): def clean_autor(self): autor_field = self.cleaned_data['autor'] try: + self.logger.debug("Tentando obter Autor com id={}.".format(autor_field.id)) autor = Autor.objects.get(id=autor_field.id) except ObjectDoesNotExist: + self.logger.error("Autor com id={} não encontrado. Definido como None.".format(autor_field.id)) autor_field = None else: + self.logger.info("Autor com id={} encontrado com sucesso.".format(autor_field.id)) autor_field = autor return autor_field @@ -459,15 +473,22 @@ class ProtocoloMateriaForm(ModelForm): if data['vincular_materia'] == 'True': try: if not data['ano_materia'] or not data['numero_materia']: + self.logger.error("Não foram informados o número ou ano da matéria a ser vinculada") raise ValidationError( 'Favor informar o número e ano da matéria a ser vinculada') + self.logger.debug("Tentando obter MateriaLegislativa com ano={}, numero={} e data={}." + .format(data['ano_materia'], data['numero_materia'], data['tipo_materia'])) self.materia = MateriaLegislativa.objects.get(ano=data['ano_materia'], numero=data['numero_materia'], tipo=data['tipo_materia']) if self.materia.numero_protocolo: + self.logger.error("MateriaLegislativa informada já possui o protocolo {}/{} vinculado." + .format(self.materia.numero_protocolo, self.materia.ano)) raise ValidationError(_('Matéria Legislativa informada já possui o protocolo {}/{} vinculado.' .format(self.materia.numero_protocolo, self.materia.ano))) except ObjectDoesNotExist: + self.logger.error("MateriaLegislativa informada (ano={}, numero={} e data={}) não existente." + .format(data['ano_materia'], data['numero_materia'], data['tipo_materia'])) raise ValidationError(_('Matéria Legislativa informada não existente.')) return data @@ -528,6 +549,8 @@ class DocumentoAcessorioAdministrativoForm(ModelForm): class TramitacaoAdmForm(ModelForm): + logger = logging.getLogger(__name__) + class Meta: model = TramitacaoAdministrativo fields = ['data_tramitacao', @@ -565,11 +588,17 @@ class TramitacaoAdmForm(ModelForm): if ultima_tramitacao: destino = ultima_tramitacao.unidade_tramitacao_destino if (destino != self.cleaned_data['unidade_tramitacao_local']): + self.logger.error('A origem da nova tramitação ({}) deve ser ' + 'igual ao destino ({}) da última adicionada!' + .format(self.cleaned_data['unidade_tramitacao_local'], destino)) msg = _('A origem da nova tramitação deve ser igual ao ' 'destino da última adicionada!') raise ValidationError(msg) if self.cleaned_data['data_tramitacao'] > timezone.now().date(): + self.logger.error('A data de tramitação ({}) deve ser ' + 'menor ou igual a data de hoje ({})!' + .format(self.cleaned_data['data_tramitacao'], timezone.now().date())) msg = _( 'A data de tramitação deve ser ' + 'menor ou igual a data de hoje!') @@ -577,18 +606,27 @@ class TramitacaoAdmForm(ModelForm): if (ultima_tramitacao and data_tram_form < ultima_tramitacao.data_tramitacao): + self.logger.error('A data da nova tramitação ({}) deve ser ' + 'maior que a data da última tramitação ({})!' + .format(data_tram_form, ultima_tramitacao.data_tramitacao)) msg = _('A data da nova tramitação deve ser ' + 'maior que a data da última tramitação!') raise ValidationError(msg) if data_enc_form: if data_enc_form < data_tram_form: + self.logger.error('A data de encaminhamento ({}) deve ser ' + 'maior que a data de tramitação ({})!' + .format(data_enc_form, data_tram_form)) msg = _('A data de encaminhamento deve ser ' + 'maior que a data de tramitação!') raise ValidationError(msg) if data_prazo_form: if data_prazo_form < data_tram_form: + self.logger.error('A data fim de prazo ({}) deve ser ' + 'maior que a data de tramitação ({})!' + .format(data_prazo_form, data_tram_form)) msg = _('A data fim de prazo deve ser ' + 'maior que a data de tramitação!') raise ValidationError(msg) @@ -604,6 +642,8 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): data_tramitacao = forms.DateField(widget=forms.HiddenInput()) + logger = logging.getLogger(__name__) + class Meta: model = TramitacaoAdministrativo fields = ['data_tramitacao', @@ -631,6 +671,9 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): if ultima_tramitacao != self.instance: if self.cleaned_data['unidade_tramitacao_destino'] != \ self.instance.unidade_tramitacao_destino: + self.logger.error('Você não pode mudar a Unidade de Destino desta ' + 'tramitação (id={}), pois irá conflitar com a Unidade ' + 'Local da tramitação seguinte'.format(self.instance.documento_id)) raise ValidationError( 'Você não pode mudar a Unidade de Destino desta ' 'tramitação, pois irá conflitar com a Unidade ' @@ -646,6 +689,8 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): class DocumentoAdministrativoForm(ModelForm): + logger = logging.getLogger(__name__) + data = forms.DateField(initial=timezone.now) ano_protocolo = forms.ChoiceField(required=False, @@ -711,19 +756,26 @@ class DocumentoAdministrativoForm(ModelForm): tipo=tipo_documento, ano=ano_protocolo).exists() if doc_exists: + self.logger.error("DocumentoAdministrativo (numero={}, tipo={} e ano={}) já existe." + .format(numero_documento, tipo_documento, ano_protocolo)) raise ValidationError(_('Documento já existente')) # campos opcionais, mas que se informados devem ser válidos if numero_protocolo and ano_protocolo: try: + self.logger.debug("Tentando obter Protocolo com numero={} e ano={}." + .format(numero_protocolo, ano_protocolo)) self.fields['protocolo'].initial = Protocolo.objects.get( numero=numero_protocolo, ano=ano_protocolo).pk except ObjectDoesNotExist: + self.logger.error("Protocolo %s/%s inexistente." % ( + numero_protocolo, ano_protocolo)) msg = _('Protocolo %s/%s inexistente.' % ( numero_protocolo, ano_protocolo)) raise ValidationError(msg) except MultipleObjectsReturned: + self.logger.error("Existe mais de um Protocolo com este ano ({}) e número ({}).".format(ano_protocolo,numero_protocolo)) msg = _( 'Existe mais de um Protocolo com este ano e número.' % ( numero_protocolo, ano_protocolo)) @@ -741,6 +793,8 @@ class DocumentoAdministrativoForm(ModelForm): protocolo__numero=numero_protocolo, protocolo__ano=ano_protocolo).exists() if exist_materia or exist_doc: + self.logger.error('Protocolo com numero=%s e ano=%s já possui' + ' documento vinculado' % (numero_protocolo, ano_protocolo)) raise ValidationError(_('Protocolo %s/%s já possui' ' documento vinculado' % (numero_protocolo, ano_protocolo))) @@ -792,6 +846,8 @@ class DocumentoAdministrativoForm(ModelForm): class DesvincularDocumentoForm(ModelForm): + logger = logging.getLogger(__name__) + numero = forms.CharField(required=True, label=DocumentoAdministrativo._meta. get_field('numero').verbose_name @@ -815,11 +871,15 @@ class DesvincularDocumentoForm(ModelForm): tipo = cleaned_data['tipo'] try: + self.logger.debug("Tentando obter DocumentoAdministrativo com numero={}, ano={} e tipo={}." + .format(numero, ano, tipo)) documento = DocumentoAdministrativo.objects.get(numero=numero, ano=ano, tipo=tipo) if not documento.protocolo: + self.logger.error("DocumentoAdministrativo %s %s/%s não se encontra vinculado a nenhum protocolo." % (tipo, numero, ano)) raise forms.ValidationError( _("%s %s/%s não se encontra vinculado a nenhum protocolo" % (tipo, numero, ano))) except ObjectDoesNotExist: + self.logger.error("DocumentoAdministrativo %s %s/%s não existe" % (tipo, numero, ano)) raise forms.ValidationError( _("%s %s/%s não existe" % (tipo, numero, ano))) @@ -853,6 +913,8 @@ class DesvincularDocumentoForm(ModelForm): class DesvincularMateriaForm(forms.Form): + logger = logging.getLogger(__name__) + numero = forms.CharField(required=True, label=_('Número da Matéria')) ano = forms.ChoiceField(required=True, @@ -877,11 +939,15 @@ class DesvincularMateriaForm(forms.Form): tipo = cleaned_data['tipo'] try: + self.logger.info("Tentando obter MateriaLegislativa com numero={}, ano={} e tipo={}." + .format(numero, ano, tipo)) materia = MateriaLegislativa.objects.get(numero=numero, ano=ano, tipo=tipo) if not materia.numero_protocolo: + self.logger.error("MateriaLegislativa %s %s/%s não se encontra vinculada a nenhum protocolo" % (tipo, numero, ano)) raise forms.ValidationError( _("%s %s/%s não se encontra vinculada a nenhum protocolo" % (tipo, numero, ano))) except ObjectDoesNotExist: + self.logger.error("MateriaLegislativa %s %s/%s não existe" % (tipo, numero, ano)) raise forms.ValidationError( _("%s %s/%s não existe" % (tipo, numero, ano))) diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py old mode 100644 new mode 100755 index 7ba286592..87e82cb7c --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -21,8 +21,9 @@ from django.views.generic.edit import FormView from django_filters.views import FilterView import sapl -from sapl.base.models import Autor, CasaLegislativa +import logging from sapl.comissoes.models import Comissao +from sapl.base.models import Autor, CasaLegislativa from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, make_pagination from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Legislatura, Parlamentar @@ -59,7 +60,10 @@ def recuperar_materia_protocolo(request): tipo = request.GET.get('tipo') ano = request.GET.get('ano') numero = request.GET.get('numero') + logger = logging.getLogger(__name__) + username = request.user.username try: + logger.debug("user=" + username + ". Tentando obter matéria com tipo={}, ano={} e numero={}.".format(tipo, ano, numero)) materia = MateriaLegislativa.objects.get( tipo=tipo, ano=ano,numero=numero) autoria = materia.autoria_set.first() @@ -70,6 +74,7 @@ def recuperar_materia_protocolo(request): 'tipo_autor':autoria.autor.tipo.pk}) response = JsonResponse(content) except Exception as e: + logger.error("user=" + username + ". " + str(e)) response = JsonResponse({'error':e}) return response @@ -99,7 +104,11 @@ def doc_texto_integral(request, pk): class AcompanhamentoConfirmarView(TemplateView): + logger = logging.getLogger(__name__) + def get_redirect_url(self, email): + username = self.request.user.username + self.logger.info('user=' + username + '. Este documento está sendo acompanhado pelo e-mail: {}'.format(email)) msg = _('Este documento está sendo acompanhado pelo e-mail: %s') % ( email) messages.add_message(self.request, messages.SUCCESS, msg) @@ -109,12 +118,16 @@ class AcompanhamentoConfirmarView(TemplateView): def get(self, request, *args, **kwargs): documento_id = kwargs['pk'] hash_txt = request.GET.get('hash_txt', '') + username = request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter objeto AcompanhamentoDocumento com documento_id={} e hash={}" + .format(documento_id, hash_txt)) acompanhar = AcompanhamentoDocumento.objects.get( documento_id=documento_id, hash=hash_txt) - except ObjectDoesNotExist: + except ObjectDoesNotExist as e: + self.logger.error("user=" + username + ". " + str(e)) raise Http404() # except MultipleObjectsReturned: # A melhor solução deve ser permitir que a exceção @@ -129,7 +142,11 @@ class AcompanhamentoConfirmarView(TemplateView): class AcompanhamentoExcluirView(TemplateView): + logger = logging.getLogger(__name__) + def get_success_url(self): + username = self.request.user.username + self.logger.info("user=" + username + ". Você parou de acompanhar este Documento (pk={}).".format(self.kwargs['pk'])) msg = _('Você parou de acompanhar este Documento.') messages.add_message(self.request, messages.INFO, msg) return reverse('sapl.protocoloadm:documentoadministrativo_detail', @@ -138,12 +155,15 @@ class AcompanhamentoExcluirView(TemplateView): def get(self, request, *args, **kwargs): documento_id = kwargs['pk'] hash_txt = request.GET.get('hash_txt', '') - + username = request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter AcompanhamentoDocumento com documento_id={} e hash={}." + .format(documento_id, hash_txt)) AcompanhamentoDocumento.objects.get(documento_id=documento_id, hash=hash_txt).delete() except ObjectDoesNotExist: - pass + self.logger.error("user=" + username + ". AcompanhamentoDocumento com documento_id={} e hash={} não encontrado." + .format(documento_id, hash_txt)) return HttpResponseRedirect(self.get_success_url()) @@ -151,6 +171,8 @@ class AcompanhamentoExcluirView(TemplateView): class AcompanhamentoDocumentoView(CreateView): template_name = "protocoloadm/acompanhamento_documento.html" + logger = logging.getLogger(__name__) + def get_random_chars(self): s = ascii_letters + digits return ''.join(choice(s) for i in range(choice([6, 7]))) @@ -200,7 +222,9 @@ class AcompanhamentoDocumentoView(CreateView): "documento", documento, destinatario) - + self.logger.info('user={} .Foi enviado um e-mail de confirmação. Confira sua caixa ' + 'de mensagens e clique no link que nós enviamos para ' + 'confirmar o acompanhamento deste documento.'.format(usuario.username)) msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ confirmar o acompanhamento deste documento.') @@ -209,6 +233,7 @@ class AcompanhamentoDocumentoView(CreateView): # Caso esse Acompanhamento já exista # avisa ao usuário que esse documento já está sendo acompanhado else: + self.logger.info('user=' + request.user.username + '. Este e-mail já está acompanhando esse documento (pk={}).'.format(pk)) msg = _('Este e-mail já está acompanhando esse documento.') messages.add_message(request, messages.INFO, msg) @@ -433,6 +458,9 @@ class AnularProtocoloAdmView(PermissionRequiredMixin, CreateView): class ProtocoloDocumentoView(PermissionRequiredMixin, FormValidMessageMixin, CreateView): + + logger = logging.getLogger(__name__) + template_name = "protocoloadm/protocolar_documento.html" form_class = ProtocoloDocumentForm form_valid_message = _('Protocolo cadastrado com sucesso!') @@ -444,10 +472,14 @@ class ProtocoloDocumentoView(PermissionRequiredMixin, def form_valid(self, form): protocolo = form.save(commit=False) + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter sequência de numeração.") numeracao = sapl.base.models.AppConfig.objects.last( ).sequencia_numeracao - except AttributeError: + except AttributeError as e: + self.logger.error("user=" + username + ". É preciso definir a sequencia de " + "numeração na tabelas auxiliares! " + str(e)) msg = _('É preciso definir a sequencia de ' + 'numeração na tabelas auxiliares!') messages.add_message(self.request, messages.ERROR, msg) @@ -474,7 +506,8 @@ class ProtocoloDocumentoView(PermissionRequiredMixin, if not protocolo.numero: protocolo.numero = (numero['numero__max'] + 1) if numero['numero__max'] else 1 elif protocolo.numero < (numero['numero__max'] + 1) if numero['numero__max'] else 0: - msg = _('Número de protocolo deve ser maior que {}').format(numero['numero__max']) + msg = _('Número de protocolo deve ser maior que {}'.format(numero['numero__max'])) + self.logger.error("user=" + username + ". Número de protocolo deve ser maior que {}.".format(numero['numero__max'])) messages.add_message(self.request, messages.ERROR, msg) return self.render_to_response(self.get_context_data()) protocolo.ano = timezone.now().year @@ -518,21 +551,30 @@ class CriarDocumentoProtocolo(PermissionRequiredMixin, CreateView): class ProtocoloMostrarView(PermissionRequiredMixin, TemplateView): + logger = logging.getLogger(__name__) template_name = "protocoloadm/protocolo_mostrar.html" permission_required = ('protocoloadm.detail_protocolo', ) def get_context_data(self, **kwargs): + context = super(ProtocoloMostrarView, self).get_context_data(**kwargs) protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) + username = self.request.user.username if protocolo.tipo_materia: try: + self.logger.debug("user=" + username + ". Tentando obter objeto MateriaLegislativa com numero_protocolo={} e ano={}." + .format(protocolo.numero, protocolo.ano)) materia = MateriaLegislativa.objects.get( numero_protocolo=protocolo.numero, ano=protocolo.ano) except ObjectDoesNotExist: + self.logger.error("user=" + username + ". Objeto MateriaLegislativa com numero_protocolo={} e ano={} não encontrado." + " Definido como None.".format(protocolo.numero, protocolo.ano)) context['materia'] = None else: + self.logger.info("user=" + username + ". Objeto MateriaLegislativa com numero_protocolo={} e ano={} encontrado" + "com sucesso.".format(protocolo.numero, protocolo.ano)) context['materia'] = materia if protocolo.tipo_documento: @@ -577,6 +619,8 @@ class ComprovanteProtocoloView(PermissionRequiredMixin, TemplateView): class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): + logger = logging.getLogger(__name__) + template_name = "protocoloadm/protocolar_materia.html" form_class = ProtocoloMateriaForm form_valid_message = _('Matéria cadastrada com sucesso!') @@ -588,10 +632,14 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): def form_valid(self, form): protocolo = form.save(commit=False) + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter sequência de numeração.") numeracao = sapl.base.models.AppConfig.objects.last( ).sequencia_numeracao except AttributeError: + self.logger.error("user=" + username + ". É preciso definir a sequencia de " + "numeração na tabelas auxiliares!") msg = _('É preciso definir a sequencia de ' + 'numeração na tabelas auxiliares!') messages.add_message(self.request, messages.ERROR, msg) @@ -620,6 +668,8 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): protocolo.numero = (numero['numero__max'] + 1) if numero['numero__max'] else 1 if numero['numero__max']: if protocolo.numero < (numero['numero__max'] + 1): + self.logger.error("user=" + username + ". Número de protocolo ({}) é menor que {}" + .format(protocolo.numero, numero['numero__max'])) msg = _('Número de protocolo deve ser maior que {}').format(numero['numero__max']) messages.add_message(self.request, messages.ERROR, msg) return self.render_to_response(self.get_context_data()) @@ -801,6 +851,7 @@ class TramitacaoAdmCrud(MasterDetailCrud): class CreateView(MasterDetailCrud.CreateView): form_class = TramitacaoAdmForm + logger = logging.getLogger(__name__) def get_initial(self): initial = super(CreateView, self).get_initial() @@ -832,30 +883,38 @@ class TramitacaoAdmCrud(MasterDetailCrud): def form_valid(self, form): self.object = form.save() - + username = self.request.user.username try: tramitacao_signal.send(sender=TramitacaoAdministrativo, post=self.object, request=self.request) except Exception as e: # TODO log error + self.logger.error('user=' + username + '. Tramitação criada, mas e-mail de acompanhamento de documento ' + 'não enviado. A não configuração do servidor de e-mail ' + 'impede o envio de aviso de tramitação. ' + str(e)) msg = _('Tramitação criada, mas e-mail de acompanhamento ' - 'de documento não enviado. A não configuração do' - ' servidor de e-mail impede o envio de aviso de tramitação') + 'de documento não enviado. A não configuração do' + ' servidor de e-mail impede o envio de aviso de tramitação') messages.add_message(self.request, messages.WARNING, msg) return HttpResponseRedirect(self.get_success_url()) return super().form_valid(form) class UpdateView(MasterDetailCrud.UpdateView): form_class = TramitacaoAdmEditForm + logger = logging.getLogger(__name__) def form_valid(self, form): self.object = form.save() + username = self.request.user.username try: tramitacao_signal.send(sender=TramitacaoAdministrativo, post=self.object, request=self.request) except Exception as e: # TODO log error + self.logger.error('user=' + username + '. Tramitação criada, mas e-mail de acompanhamento de documento ' + 'não enviado. A não configuração do servidor de e-mail ' + 'impede o envio de aviso de tramitação. ' + str(e)) msg = _('Tramitação criada, mas e-mail de acompanhamento ' 'de documento não enviado. A não configuração do' ' servidor de e-mail impede o envio de aviso de tramitação') diff --git a/sapl/redireciona_urls/views.py b/sapl/redireciona_urls/views.py index ade47c9de..ee0212661 100644 --- a/sapl/redireciona_urls/views.py +++ b/sapl/redireciona_urls/views.py @@ -1,3 +1,5 @@ +import logging + from django.core.urlresolvers import NoReverseMatch, reverse from django.views.generic import RedirectView @@ -71,12 +73,16 @@ def has_iframe(url, request): class RedirecionaSAPLIndex(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url_pattern = 'sapl_index' + username = self.request.user.username try: + self.logger.info("user=" + username + ". Tentando obter url.") url = reverse(url_pattern) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(url_pattern) url = has_iframe(url, self.request) @@ -86,23 +92,30 @@ class RedirecionaSAPLIndex(RedirectView): class RedirecionaParlamentar(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING pk_parlamentar = self.request.GET.get( 'cod_parlamentar', EMPTY_STRING) + username = self.request.user.username if pk_parlamentar: try: kwargs = {'pk': pk_parlamentar} + self.logger.debug("user=" + username + ". Tentando obter url correspondente.") url = reverse(parlamentar_detail, kwargs=kwargs) - except NoReverseMatch: + except NoReverseMatch as 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)) raise UnknownUrlNameError(parlamentar_list) numero_legislatura = self.request.GET.get( @@ -119,22 +132,28 @@ class RedirecionaParlamentar(RedirectView): class RedirecionaComissao(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url = EMPTY_STRING pk_comissao = self.request.GET.get('cod_comissao', EMPTY_STRING) + username = self.request.user.username if pk_comissao: kwargs = {'pk': pk_comissao} try: + self.logger.debug("user=" + username + ". Tentando obter url correspondente.") url = reverse(comissao_detail, kwargs=kwargs) - except NoReverseMatch: + except NoReverseMatch as 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: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(comissao_list) url = has_iframe(url, self.request) @@ -144,24 +163,30 @@ class RedirecionaComissao(RedirectView): class RedirecionaComposicaoComissao(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url = EMPTY_STRING pk_composicao = self.request.GET.get( 'cod_periodo_comp_sel', EMPTY_STRING) pk_comissao = self.request.GET.get('cod_comissao', EMPTY_STRING) + username = self.request.user.username if pk_comissao: kwargs = {'pk': pk_comissao} try: + self.logger.debug("user=" + username + ". Tentando obter url correspondente.") url = reverse(comissao_detail, kwargs=kwargs) - except NoReverseMatch: + except NoReverseMatch as 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: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(comissao_list) url = has_iframe(url, self.request) @@ -171,22 +196,29 @@ class RedirecionaComposicaoComissao(RedirectView): class RedirecionaPautaSessao(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + pk_sessao_plenaria = self.request.GET.get( 'cod_sessao_plen', EMPTY_STRING) + username = self.request.user.username if pk_sessao_plenaria: kwargs = {'pk': pk_sessao_plenaria} try: + self.logger.debug("user=" + username + ". Tentando obter url correspondente.") url = reverse(pauta_sessao_detail, kwargs=kwargs) - except NoReverseMatch: + except NoReverseMatch as 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: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(pauta_sessao_list) data_sessao_plenaria = self.request.GET.get( @@ -212,23 +244,29 @@ class RedirecionaPautaSessao(RedirectView): class RedirecionaSessaoPlenaria(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): pk_sessao_plenaria = self.request.GET.get( 'cod_sessao_plen', EMPTY_STRING) url = EMPTY_STRING + username = self.request.user.username if pk_sessao_plenaria: kwargs = {'pk': pk_sessao_plenaria} try: + self.logger.debug("user=" + username + ". Tentando obter url correspondente.") url = reverse(sessao_plenaria_detail, kwargs=kwargs) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(sessao_plenaria_detail) else: try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(sessao_plenaria_list) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(sessao_plenaria_list) year = self.request.GET.get( @@ -261,12 +299,17 @@ class RedirecionaSessaoPlenaria(RedirectView): class RedirecionaRelatoriosList(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorios_list) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorios_list) url = has_iframe(url, self.request) @@ -276,12 +319,16 @@ class RedirecionaRelatoriosList(RedirectView): class RedirecionaRelatoriosMateriasEmTramitacaoList(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorio_materia_por_tramitacao) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorio_materia_por_tramitacao) year = self.request.GET.get( @@ -339,13 +386,17 @@ class RedirecionaMateriaLegislativaDetail(RedirectView): class RedirecionaMateriaLegislativaList(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url = EMPTY_STRING args = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(materialegislativa_list) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(materialegislativa_list) tipo_materia = self.request.GET.get( @@ -414,12 +465,17 @@ class RedirecionaMateriaLegislativaList(RedirectView): class RedirecionaMesaDiretoraView(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(parlamentar_mesa_diretora) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(parlamentar_mesa_diretora) url = has_iframe(url, self.request) @@ -447,14 +503,18 @@ class RedirecionaNormasJuridicasDetail(RedirectView): class RedirecionaNormasJuridicasTextoIntegral(RedirectView): permanent = False + logger = logging.getLogger(__name__) def get_redirect_url(self, **kwargs): url = EMPTY_STRING + username = self.request.user.username try: + 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)) raise e url = has_iframe(url, self.request) @@ -465,13 +525,17 @@ class RedirecionaNormasJuridicasTextoIntegral(RedirectView): class RedirecionaNormasJuridicasList(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url = EMPTY_STRING args = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(norma_juridica_pesquisa) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(norma_juridica_pesquisa) tipo_norma = self.request.GET.get( @@ -523,13 +587,18 @@ class RedirecionaNormasJuridicasList(RedirectView): class RedirecionaHistoricoTramitacoesList(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING args = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(historico_tramitacoes) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(historico_tramitacoes) inicio_intervalo_data_tramitacao = self.request.GET.get( @@ -580,13 +649,18 @@ class RedirecionaHistoricoTramitacoesList(RedirectView): class RedirecionaAtasList(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING args = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(pesquisar_atas) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(pesquisar_atas) inicio_intervalo_data_ata = self.request.GET.get( @@ -614,13 +688,18 @@ class RedirecionaAtasList(RedirectView): class RedirecionaPresencaParlamentares(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING args = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(presenca_sessao) - except NoReverseMatch: + except NoReverseMatch as 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( @@ -648,12 +727,16 @@ class RedirecionaPresencaParlamentares(RedirectView): class RedirecionaMateriasPorAutor(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): url = EMPTY_STRING + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorio_materia_por_autor) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorio_materia_por_autor) url = has_iframe(url, self.request) @@ -664,14 +747,18 @@ class RedirecionaMateriasPorAutor(RedirectView): class RedirecionaMateriasPorAnoAutorTipo(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + url = EMPTY_STRING ano = self.request.GET.get('ano', '') - + username = self.request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorio_materia_por_ano_autor_tipo) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorio_materia_por_ano_autor_tipo) if ano: @@ -686,23 +773,30 @@ class RedirecionaMateriasPorAnoAutorTipo(RedirectView): class RedirecionaReuniao(RedirectView): permanent = True + logger = logging.getLogger(__name__) def get_redirect_url(self): + pk_reuniao = self.request.GET.get( 'cod_comissao', EMPTY_STRING) url = EMPTY_STRING + username = self.request.user.username if pk_reuniao: kwargs = {'pk': pk_reuniao} try: + self.logger.debug("user=" + username + ". Tentando obter url correspondente (pk={}).".format(kwargs['pk'])) url = reverse(reuniao_detail, kwargs=kwargs) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(reuniao_detail) else: try: + self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(reuniao_list) - except NoReverseMatch: + except NoReverseMatch as e: + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(reuniao_list) year = self.request.GET.get( diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py old mode 100644 new mode 100755 index cfbf784eb..5b04ea82b --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -1,5 +1,6 @@ import html import re +import logging from datetime import datetime as dt from django.core.exceptions import ObjectDoesNotExist @@ -782,7 +783,8 @@ def relatorio_sessao_plenaria(request, pk): ''' pdf_sessao_plenaria_gerar.py ''' - + logger = logging.getLogger(__name__) + username = request.user.username response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = ( 'inline; filename="relatorio_protocolo.pdf"') @@ -797,8 +799,10 @@ def relatorio_sessao_plenaria(request, pk): imagem = get_imagem(casa) try: + logger.debug("user=" + username + ". Tentando obter SessaoPlenaria com id={}.".format(pk)) sessao = SessaoPlenaria.objects.get(id=pk) - except ObjectDoesNotExist: + except ObjectDoesNotExist as e: + logger.error("user=" + username + ". Essa SessaoPlenaria não existe (pk={}). ".format(pk) + str(e)) raise Http404('Essa página não existe') (inf_basicas_dic, @@ -1125,7 +1129,7 @@ def get_pauta_sessao(sessao, casa): numeracao = Numeracao.objects.filter(materia=votacao.materia).first() if numeracao: - dic_votacao["des_numeracao"] = str( + dic_votacao["des_numeracao"] = str( numeracao.numero_materia) + '/' + str(numeracao.ano_materia) turno, tramitacao = get_turno(dic_votacao, materia, sessao.data_inicio) diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index dbdfce8ce..522cced6a 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -1,6 +1,8 @@ from builtins import LookupError import django +import logging + from django.apps import apps from django.contrib.auth import get_user_model from django.contrib.auth.management import _get_all_permissions @@ -28,12 +30,14 @@ def create_proxy_permissions( using=DEFAULT_DB_ALIAS, **kwargs): if not app_config.models_module: return - + logger = logging.getLogger(__name__) # print(app_config) try: + logger.info("Tentando obter modelo de permissão do app.") Permission = apps.get_model('auth', 'Permission') - except LookupError: + except LookupError as e: + logger.error(str(e)) return if not router.allow_migrate_model(using, Permission): @@ -69,9 +73,11 @@ def create_proxy_permissions( app_label, model = opts.app_label, opts.model_name try: + logger.info("Tentando obter db_manager.") ctype = ContentType.objects.db_manager( using).get_by_natural_key(app_label, model) - except: + except Exception as e: + logger.error(str(e)) ctype = ContentType.objects.db_manager( using).create(app_label=app_label, model=model) else: @@ -81,12 +87,14 @@ def create_proxy_permissions( # FIXME: Retirar try except quando sapl passar a usar django 1.11 try: + logger.info("_get_all_permissions") # Função não existe mais em Django 1.11 # como sapl ainda não foi para Django 1.11 # esta excessão foi adicionada para caso o # Sapl esteja rodando em um projeto 1.11 não ocorra erros _all_perms_of_klass = _get_all_permissions(klass._meta, ctype) - except: + except Exception as e: + logger.error(str(e)) # Nova função usada em projetos com Django 1.11 e o sapl é uma app _all_perms_of_klass = _get_all_permissions(klass._meta) @@ -111,6 +119,13 @@ def create_proxy_permissions( # error when the name is longer than 255 characters for perm in perms: if len(perm.name) > permission_name_max_length: + logger.error("The permission name %s of %s.%s " + "is longer than %s characters" % ( + perm.name, + perm.content_type.app_label, + perm.content_type.model, + permission_name_max_length, + )) raise exceptions.ValidationError( 'The permission name %s of %s.%s ' 'is longer than %s characters' % ( @@ -155,15 +170,17 @@ def get_rules(): def _config_group(self, group_name, rules_list): if not group_name: return - + logger = logging.getLogger(__name__) group, created = Group.objects.get_or_create(name=group_name) group.permissions.clear() try: + logger.info("Tentando associar grupos.") print(' ', group_name) for model, perms in rules_list: self.associar(group, model, perms) except Exception as e: + logger.error(str(e)) print(group_name, e) def groups_add_user(self, user, groups_name): diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py old mode 100644 new mode 100755 index 9f172d518..3c1da0380 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -1,4 +1,5 @@ from operator import itemgetter +import logging from re import sub from django.contrib import messages @@ -62,10 +63,10 @@ TipoResultadoVotacaoCrud = CrudAux.build( def reordernar_materias_expediente(request, pk): expedientes = ExpedienteMateria.objects.filter( sessao_plenaria_id=pk) + for exp_num, e in enumerate(expedientes, 1): e.numero_ordem = exp_num e.save() - return HttpResponseRedirect( reverse('sapl.sessao:expedientemateria_list', kwargs={'pk': pk})) @@ -82,7 +83,10 @@ def reordernar_materias_ordem(request, pk): def verifica_presenca(request, model, spk): + logger = logging.getLogger(__name__) if not model.objects.filter(sessao_plenaria_id=spk).exists(): + username = request.user.username + logger.error("user=" + username + ". Votação não pode ser aberta sem presenças (sessao_plenaria_id={}).".format(spk)) msg = _('Votação não pode ser aberta sem presenças') messages.add_message(request, messages.ERROR, msg) return False @@ -94,6 +98,8 @@ def verifica_votacoes_abertas(request): Q(ordemdia__votacao_aberta=True) | Q(expedientemateria__votacao_aberta=True)).distinct() + logger = logging.getLogger(__name__) + if votacoes_abertas: msg_abertas = [] for v in votacoes_abertas: @@ -101,7 +107,10 @@ def verifica_votacoes_abertas(request): reverse('sapl.sessao:sessaoplenaria_detail', kwargs={'pk': v.id}), v.__str__())) - + username = request.user.username + logger.info('user=' + username + '. Já existem votações abertas nas seguintes Sessões: ' + + ', '.join(msg_abertas) + '. Para abrir ' + 'outra, termine ou feche as votações abertas.') msg = _('Já existem votações abertas nas seguintes Sessões: ' + ', '.join(msg_abertas) + '. Para abrir ' 'outra, termine ou feche as votações abertas.') @@ -113,9 +122,13 @@ def verifica_votacoes_abertas(request): def verifica_sessao_iniciada(request, spk): + logger = logging.getLogger(__name__) sessao = SessaoPlenaria.objects.get(id=spk) if not sessao.iniciada or sessao.finalizada: + username = request.user.username + logger.info('user=' + username + '. Não é possível abrir matérias para votação. ' + 'Esta SessaoPlenaria (id={}) não foi iniciada ou está finalizada.'.format(spk)) msg = _('Não é possível abrir matérias para votação. ' 'Esta Sessão Plenária não foi iniciada ou está finalizada.' ' Vá em "Abertura"->"Dados Básicos" e altere os valores dos campos necessários.') @@ -672,6 +685,7 @@ class SessaoCrud(Crud): class CreateView(Crud.CreateView): form_class = SessaoPlenariaForm + logger = logging.getLogger(__name__) @property def cancel_url(self): @@ -691,6 +705,11 @@ class SessaoCrud(Crud): else: msg = _('Cadastre alguma legislatura antes de adicionar ' + 'uma sessão plenária!') + + username = self.request.user.username + self.logger.error('user=' + username + '. Cadastre alguma legislatura antes de adicionar ' + 'uma sessão plenária!') + messages.add_message(self.request, messages.ERROR, msg) return {} @@ -727,6 +746,7 @@ class PresencaView(FormMixin, PresencaMixin, DetailView): template_name = 'sessao/presenca.html' form_class = PresencaForm model = SessaoPlenaria + logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): context = FormMixin.get_context_data(self, **kwargs) @@ -761,7 +781,8 @@ class PresencaView(FormMixin, PresencaMixin, DetailView): sessao.sessao_plenaria = self.object sessao.parlamentar = Parlamentar.objects.get(id=p) sessao.save() - + username = request.user.username + self.logger.info("user=" + username + ". SessaoPlenariaPresenca salva com sucesso (parlamentar_id={})!".format(p)) msg = _('Presença em Sessão salva com sucesso!') messages.add_message(request, messages.SUCCESS, msg) @@ -777,6 +798,7 @@ class PresencaView(FormMixin, PresencaMixin, DetailView): class PainelView(PermissionRequiredForAppCrudMixin, TemplateView): template_name = 'sessao/painel.html' app_label = 'painel' + logger = logging.getLogger(__name__) def get(self, request, *args, **kwargs): if request.user.is_anonymous(): @@ -798,6 +820,10 @@ class PainelView(PermissionRequiredForAppCrudMixin, TemplateView): if (not cronometro_discurso or not cronometro_aparte or not cronometro_ordem or not cronometro_consideracoes): + + username = self.request.user.username + self.logger.error('user=' + username + '. Você precisa primeiro configurar os cronômetros' + ' nas Configurações da Aplicação') msg = _( 'Você precisa primeiro configurar os cronômetros \ nas Configurações da Aplicação') @@ -834,6 +860,7 @@ class PresencaOrdemDiaView(FormMixin, PresencaMixin, DetailView): template_name = 'sessao/presenca_ordemdia.html' form_class = PresencaForm model = SessaoPlenaria + logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): context = FormMixin.get_context_data(self, **kwargs) @@ -869,6 +896,8 @@ class PresencaOrdemDiaView(FormMixin, PresencaMixin, DetailView): ordem.parlamentar = Parlamentar.objects.get(id=p) ordem.save() + username = request.user.username + self.logger.info('user=' + username + '. PresencaOrdemDia (parlamentar com id={}) salva com sucesso!'.format(p)) msg = _('Presença em Ordem do Dia salva com sucesso!') messages.add_message(request, messages.SUCCESS, msg) @@ -995,15 +1024,19 @@ class MesaView(FormMixin, DetailView): template_name = 'sessao/mesa.html' form_class = MesaForm model = SessaoPlenaria + logger = logging.getLogger(__name__) def get(self, request, *args, **kwargs): self.object = self.get_object() context = self.get_context_data(object=self.object) + username = request.user.username try: + self.logger.debug("user=" + username + ". Tentando obter SessaoPlenaria com id={}".format(kwargs['pk'])) sessao = SessaoPlenaria.objects.get( id=kwargs['pk']) except ObjectDoesNotExist: + self.logger.error("user=" + username + ". SessaoPlenaria com id={} não existe.".format(kwargs['pk'])) mensagem = _('Esta Sessão Plenária não existe!') messages.add_message(request, messages.INFO, mensagem) @@ -1055,10 +1088,14 @@ def atualizar_mesa(request): Esta função lida com qualquer alteração nos campos da Mesa Diretora, atualizando os campos após cada alteração """ + logger = logging.getLogger(__name__) + username = request.user.username try: + logger.debug("user=" + username + ". Tentando obter SessaoPlenaria com id={}.".format(request.GET['sessao'])) sessao = SessaoPlenaria.objects.get( id=int(request.GET['sessao'])) except ObjectDoesNotExist: + logger.error("user=" + username + ". SessaoPlenaria com id={} inexistente.".format(request.GET['sessao'])) return JsonResponse({'msg': ('Sessão Inexistente!', 0)}) # Atualiza os componentes da view após a mudança @@ -1097,6 +1134,8 @@ def insere_parlamentar_composicao(request): Esta função lida com qualquer operação de inserção na composição da Mesa Diretora """ + logger = logging.getLogger(__name__) + username = request.user.username if request.user.has_perm( '%s.add_%s' % ( AppConfig.label, IntegranteMesa._meta.model_name)): @@ -1104,15 +1143,19 @@ def insere_parlamentar_composicao(request): composicao = IntegranteMesa() try: + logger.debug("user=" + username + ". Tentando obter SessaoPlenaria com id={}.".format(request.POST['sessao'])) composicao.sessao_plenaria = SessaoPlenaria.objects.get( id=int(request.POST['sessao'])) except MultiValueDictKeyError: + logger.error("user=" + username + ". SessaoPlenaria com id={} não existe.".format(request.POST['sessao'])) return JsonResponse({'msg': ('A Sessão informada não existe!', 0)}) try: + logger.debug("user=" + username + ". Tentando obter Parlamentar com id={}.".format(request.POST['parlamentar'])) composicao.parlamentar = Parlamentar.objects.get( id=int(request.POST['parlamentar'])) except MultiValueDictKeyError: + logger.error("user=" + username + ". Parlamentar com id={} não existe.".format(request.POST['parlamentar'])) return JsonResponse({ 'msg': ('Nenhum parlamentar foi inserido!', 0)}) @@ -1124,13 +1167,17 @@ def insere_parlamentar_composicao(request): cargo_id=composicao.cargo.id).exists() if parlamentar_ja_inserido: + logger.debug("user=" + username + ". Parlamentar (id={}) já inserido na sessao_plenaria(id={}) e cargo(ìd={})." + .format(request.POST['parlamentar'], composicao.sessao_plenaria.id, composicao.cargo.id)) return JsonResponse({'msg': ('Parlamentar já inserido!', 0)}) composicao.save() - except MultiValueDictKeyError: + except MultiValueDictKeyError as e: + logger.error("user=" + username + ". Nenhum cargo foi inserido! " + str(e)) return JsonResponse({'msg': ('Nenhum cargo foi inserido!', 0)}) + logger.info("user=" + username + ". Parlamentar (id={}) inserido com sucesso na sessao_plenaria(id={}) e cargo(ìd={}).") return JsonResponse({'msg': ('Parlamentar inserido com sucesso!', 1)}) else: @@ -1143,23 +1190,30 @@ def remove_parlamentar_composicao(request): Essa função lida com qualquer operação de remoção na composição da Mesa Diretora """ + logger = logging.getLogger(__name__) + username = request.user.username if request.POST and request.user.has_perm( '%s.delete_%s' % ( AppConfig.label, IntegranteMesa._meta.model_name)): if 'composicao_mesa' in request.POST: try: + logger.debug("user=" + username + ". Tentando remover IntegranteMesa com id={}".format(request.POST['composicao_mesa'])) IntegranteMesa.objects.get( id=int(request.POST['composicao_mesa'])).delete() except ObjectDoesNotExist: + logger.error("user=" + username + ". IntegranteMesa com id={} não existe e não pôde ser removido." + .format(request.POST['composicao_mesa'])) return JsonResponse( {'msg': ( 'Composição da Mesa não pôde ser removida!', 0)}) + logger.info("user=" + username + ". IntegranteMesa com id={} removido com sucesso.") return JsonResponse( {'msg': ( 'Parlamentar excluido com sucesso!', 1)}) else: + logger.debug("user=" + username + ". Nenhum parlamentar selecionado para ser excluido!") return JsonResponse( {'msg': ( 'Selecione algum parlamentar para ser excluido!', 0)}) @@ -1481,6 +1535,8 @@ class ResumoView(DetailView): class ResumoAtaView(ResumoView): template_name = 'sessao/resumo_ata.html' + logger = logging.getLogger(__name__) + logger.debug('Gerando Resumo.') class ExpedienteView(FormMixin, DetailView): @@ -1488,6 +1544,8 @@ class ExpedienteView(FormMixin, DetailView): form_class = ExpedienteForm model = SessaoPlenaria + logger = logging.getLogger(__name__) + def get_context_data(self, **kwargs): context = FormMixin.get_context_data(self, **kwargs) context['title'] = '%s (%s)' % ( @@ -1498,10 +1556,12 @@ class ExpedienteView(FormMixin, DetailView): def post(self, request, *args, **kwargs): self.object = self.get_object() form = ExpedienteForm(request.POST) + username = request.user.username if 'apagar-expediente' in request.POST: ExpedienteSessao.objects.filter( sessao_plenaria_id=self.object.id).delete() + self.logger.info('user=' + username + '. ExpedienteSessao de sessao_plenaria_id={} deletado.'.format(self.object.id)) return self.form_valid(form) if form.is_valid(): @@ -1522,9 +1582,13 @@ class ExpedienteView(FormMixin, DetailView): msg = _('Registro salvo com sucesso') messages.add_message(self.request, messages.SUCCESS, msg) + self.logger.info('user=' + username + '. ExpedienteSessao(sessao_plenaria_id={} e tipo_id={}) salvo com sucesso.' + .format(self.object.id, tipo)) + return self.form_valid(form) else: - msg = _('Erro ao salvar registro') + self.logger.error("user=" + username + ". Erro ao salvar registro (sessao_plenaria_id={}).".format(self.object.id)) + msg = _('Erro ao salvar ExpedienteSessao') messages.add_message(self.request, messages.SUCCESS, msg) return self.form_invalid(form) @@ -1568,8 +1632,14 @@ class OcorrenciaSessaoView(FormMixin, DetailView): form_class = OcorrenciaSessaoForm model = SessaoPlenaria + logger = logging.getLogger(__name__) + def delete(self): OcorrenciaSessao.objects.filter(sessao_plenaria=self.object).delete() + + username = self.request.user.username + self.logger.info('user=' + username + '. OcorrenciaSessao com SessaoPlenaria de id={} deletada.' + .format(self.object.id)) msg = _('Registro deletado com sucesso') messages.add_message(self.request, messages.SUCCESS, msg) @@ -1586,6 +1656,9 @@ class OcorrenciaSessaoView(FormMixin, DetailView): msg = _('Registro salvo com sucesso') messages.add_message(self.request, messages.SUCCESS, msg) + + username = self.request.user.username + self.logger.info('user=' + username + '. OcorrenciaSessao de sessao_plenaria_id={} atualizada com sucesso.'.format(self.object.id)) @method_decorator(permission_required('sessao.add_ocorrenciasessao')) def post(self, request, *args, **kwargs): @@ -1599,7 +1672,7 @@ class OcorrenciaSessaoView(FormMixin, DetailView): self.delete() elif request.POST.get('save'): - self.save(form) + self.save(form) return self.form_valid(form) @@ -1688,6 +1761,8 @@ class VotacaoView(SessaoPermissionMixin): template_name = 'sessao/votacao/votacao.html' form_class = VotacaoForm + logger = logging.getLogger(__name__) + def get(self, request, *args, **kwargs): self.object = self.get_object() context = self.get_context_data(object=self.object) @@ -1772,7 +1847,10 @@ class VotacaoView(SessaoPermissionMixin): votacao.tipo_resultado_votacao_id = int( request.POST['resultado_votacao']) votacao.save() - except: + except Exception as e: + username = request.user.username + self.logger.error('user=' + username + '. Problemas ao salvar RegistroVotacao da materia de id={} ' + 'e da ordem de id={}. '.format(materia_id, ordem_id) + str(e)) return self.form_invalid(form) else: ordem = OrdemDia.objects.get( @@ -1820,18 +1898,23 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): expediente = None form_class = VotacaoNominalForm + logger = logging.getLogger(__name__) + def get(self, request, *args, **kwargs): + username = request.user.username if self.ordem: ordem_id = kwargs['oid'] if RegistroVotacao.objects.filter(ordem_id=ordem_id).exists(): msg = _('Esta matéria já foi votada!') messages.add_message(request, messages.ERROR, msg) + self.logger.info('user=' + username + '. Matéria (ordem_id={}) já votada!'.format(ordem_id)) return HttpResponseRedirect(reverse( 'sapl.sessao:ordemdia_list', kwargs={'pk': kwargs['pk']})) try: ordem = OrdemDia.objects.get(id=ordem_id) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto OrdemDia (pk={}) não existe.'.format(ordem_id)) raise Http404() presentes = PresencaOrdemDia.objects.filter( @@ -1841,6 +1924,7 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): materia_votacao = ordem if not ordem.votacao_aberta: + self.logger.error('user=' + username + '. A votação para esta OrdemDia (id={}) encontra-se fechada!'.format(ordem_id)) msg = _('A votação para esta matéria encontra-se fechada!') messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(reverse( @@ -1853,6 +1937,7 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): expediente_id = kwargs['oid'] if (RegistroVotacao.objects.filter( expediente_id=expediente_id).exists()): + self.logger.error("user=" + username + ". RegistroVotacao (expediente_id={}) já existe.".format(expediente_id)) msg = _('Esta matéria já foi votada!') messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(reverse( @@ -1860,8 +1945,10 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): kwargs={'pk': kwargs['pk']})) try: + self.logger.debug("user=" + username + ". Tentando obter Objeto ExpedienteMateria com id={}.".format(expediente_id)) expediente = ExpedienteMateria.objects.get(id=expediente_id) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto ExpedienteMateria com id={} não existe.'.format(expediente_id)) raise Http404() presentes = SessaoPlenariaPresenca.objects.filter( @@ -1871,7 +1958,7 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): materia_votacao = expediente if not expediente.votacao_aberta: - msg = _('A votação para esta matéria encontra-se fechada!') + msg = _('A votação para este ExpedienteMateria (id={}) encontra-se fechada!'.format(expediente_id)) messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(reverse( 'sapl.sessao:expedientemateria_list', @@ -1894,19 +1981,24 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): def post(self, request, *args, **kwargs): self.object = self.get_object() form = self.get_form() + username = request.user.username if self.ordem: ordem_id = kwargs['oid'] try: + self.logger.debug("user=" + username + ". Tentando obter objeto OrdemDia com id={}.".format(ordem_id)) materia_votacao = OrdemDia.objects.get(id=ordem_id) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto OrdemDia com id={} não existe.'.format(ordem_id)) raise Http404() elif self.expediente: expediente_id = kwargs['oid'] try: + self.logger.debug("user=" + username + ". Tentando obter ExpedienteMateria com id={}.".format(expediente_id)) materia_votacao = ExpedienteMateria.objects.get( id=expediente_id) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto ExpedienteMateria com id={} não existe.'.format(expediente_id)) raise Http404() @@ -1947,6 +2039,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): # Caso todas as opções sejam 'Não votou', fecha a votação if nao_votou == len(request.POST.getlist('voto_parlamentar')): + self.logger.error('user=' + username + '. Não é possível finalizar a votação sem ' + 'nenhum voto') form.add_error(None, 'Não é possível finalizar a votação sem ' 'nenhum voto') return self.form_invalid(form) @@ -2057,6 +2151,9 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): voto = voto_parlamentar.get( parlamentar=parlamentar) except ObjectDoesNotExist: + username = self.request.user.username + self.logger.error('user=' + username + '. Objeto voto_parlamentar do ' + + 'parlamentar de id={} não existe.'.format(parlamentar.pk)) yield [parlamentar, None] else: yield [parlamentar, voto.voto] @@ -2075,8 +2172,11 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): class VotacaoNominalEditAbstract(SessaoPermissionMixin): template_name = 'sessao/votacao/nominal_edit.html' + logger = logging.getLogger(__name__) + def get(self, request, *args, **kwargs): context = {} + username = request.user.username if self.ordem: ordem_id = kwargs['oid'] @@ -2085,6 +2185,7 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): votacao = RegistroVotacao.objects.filter(ordem_id=ordem_id).last() if not ordem or not votacao: + self.logger.error('user=' + username + '. Objeto OrdemDia com id={} ou RegistroVotacao de OrdemDia não existe.'.format(ordem_id)) raise Http404() materia = ordem.materia @@ -2099,6 +2200,8 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): expediente_id=expediente_id).last() if not expediente or not votacao: + self.logger.error('user=' + username + '. Objeto ExpedienteMateria com id={} ou RegistroVotacao de ' + + 'ExpedienteMateria não existe.'.format(expediente_id)) raise Http404() materia = expediente.materia @@ -2147,6 +2250,7 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): def post(self, request, *args, **kwargs): self.object = self.get_object() form = VotacaoEditForm(request.POST) + username = request.user.username if self.ordem: ordem_id = kwargs['oid'] @@ -2154,6 +2258,7 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): try: materia_votacao = OrdemDia.objects.get(id=ordem_id) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto OrdemDia com id={} não existe.'.format(ordem_id)) raise Http404() elif self.expediente: @@ -2163,6 +2268,7 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): materia_votacao = ExpedienteMateria.objects.get( id=expediente_id) except ObjectDoesNotExist: + self.logger.error('user=' + username + '. Objeto ExpedienteMateria com id={} não existe.'.format(expediente_id)) raise Http404() if(int(request.POST['anular_votacao']) == 1): @@ -2338,6 +2444,7 @@ class VotacaoExpedienteView(SessaoPermissionMixin): template_name = 'sessao/votacao/votacao.html' form_class = VotacaoForm + logger = logging.getLogger(__name__) def get(self, request, *args, **kwargs): self.object = self.get_object() @@ -2425,7 +2532,9 @@ class VotacaoExpedienteView(SessaoPermissionMixin): votacao.tipo_resultado_votacao_id = int( request.POST['resultado_votacao']) votacao.save() - except: + except Exception as e: + username = request.user.username + self.logger.error("user=" + username + ". " + str(e)) return self.form_invalid(form) else: expediente = ExpedienteMateria.objects.get( @@ -2694,6 +2803,8 @@ class PesquisarSessaoPlenariaView(FilterView): filterset_class = SessaoPlenariaFilterSet paginate_by = 10 + logger = logging.getLogger(__name__) + def get_filterset_kwargs(self, filterset_class): super(PesquisarSessaoPlenariaView, self).get_filterset_kwargs(filterset_class) @@ -2749,6 +2860,9 @@ class PesquisarSessaoPlenariaView(FilterView): context['show_results'] = show_results_filter_set( self.request.GET.copy()) + username = request.user.username + self.logger.debug('user=' + username + '. Pesquisa de SessaoPlenaria.') + return self.render_to_response(context) @@ -2756,6 +2870,9 @@ class PesquisarPautaSessaoView(PesquisarSessaoPlenariaView): filterset_class = PautaSessaoFilterSet template_name = 'sessao/pauta_sessao_filter.html' + logger = logging.getLogger(__name__) + logger.debug('Pesquisa de PautaSessao.') + def get_context_data(self, **kwargs): context = super(PesquisarPautaSessaoView, self).get_context_data(**kwargs) @@ -2776,6 +2893,8 @@ class AdicionarVariasMateriasExpediente(PermissionRequiredForAppCrudMixin, template_name = 'sessao/adicionar_varias_materias_expediente.html' app_label = AppConfig.label + logger = logging.getLogger(__name__) + def get_filterset_kwargs(self, filterset_class): super(AdicionarVariasMateriasExpediente, self).get_filterset_kwargs(filterset_class) @@ -2818,6 +2937,7 @@ class AdicionarVariasMateriasExpediente(PermissionRequiredForAppCrudMixin, def post(self, request, *args, **kwargs): marcadas = request.POST.getlist('materia_id') + username = request.user.username for m in marcadas: try: @@ -2825,11 +2945,14 @@ class AdicionarVariasMateriasExpediente(PermissionRequiredForAppCrudMixin, msg = _('%s adicionado(a) com sucesso!' % MateriaLegislativa.objects.get(id=m)) messages.add_message(request, messages.SUCCESS, msg) + self.logger.info("user=" + username + ". MateriaLegislativa de id={} adicionado(a) com sucesso!".format(m)) except MultiValueDictKeyError: msg = _('Formulário Inválido. Você esqueceu de selecionar ' + - 'o tipo de votação de %s' % + '%s' % MateriaLegislativa.objects.get(id=m)) messages.add_message(request, messages.ERROR, msg) + self.logger.error("user=" + username + '. Formulário Inválido. Você esqueceu de ' + + 'selecionar o tipo de votação de MateriaLegislativa de id={}.'.format(m)) return self.get(request, self.kwargs) if tipo_votacao: @@ -2861,6 +2984,8 @@ class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente): filterset_class = AdicionarVariasMateriasFilterSet template_name = 'sessao/adicionar_varias_materias_ordem.html' + logger = logging.getLogger(__name__) + def get_filterset_kwargs(self, filterset_class): super(AdicionarVariasMateriasExpediente, self).get_filterset_kwargs(filterset_class) @@ -2887,6 +3012,7 @@ class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente): def post(self, request, *args, **kwargs): marcadas = request.POST.getlist('materia_id') + username = request.user.username for m in marcadas: try: @@ -2894,11 +3020,15 @@ class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente): msg = _('%s adicionado(a) com sucesso!' % MateriaLegislativa.objects.get(id=m)) messages.add_message(request, messages.SUCCESS, msg) + self.logger.debug('user=' + username + '. MateriaLegislativa de id={} adicionado(a) com sucesso!'.format(m)) except MultiValueDictKeyError: msg = _('Formulário Inválido. Você esqueceu de selecionar ' + 'o tipo de votação de %s' % MateriaLegislativa.objects.get(id=m)) messages.add_message(request, messages.ERROR, msg) + self.logger.error('user=' + username + '. Formulário Inválido. Você esqueceu de selecionar ' + 'o tipo de votação de MateriaLegislativa com id={}'.format(m)) + return self.get(request, self.kwargs) if tipo_votacao: @@ -2932,6 +3062,7 @@ def mudar_ordem_materia_sessao(request): posicao_inicial = int(request.POST['pos_ini']) + 1 posicao_final = int(request.POST['pos_fim']) + 1 pk_sessao = int(request.POST['pk_sessao']) + logger = logging.getLogger(__name__) materia = request.POST['materia'] @@ -2949,6 +3080,8 @@ def mudar_ordem_materia_sessao(request): sessao_plenaria=pk_sessao, numero_ordem=posicao_inicial) except ObjectDoesNotExist: + username = request.user.username + logger.error("user=" + username + ". Materia com sessao_plenaria={} e numero_ordem={}.".format(pk_sessao, posicao_inicial)) raise # TODO tratar essa exceção # Se a posição inicial for menor que a final, todos que diff --git a/sapl/settings.py b/sapl/settings.py old mode 100644 new mode 100755 index 6cc34401e..7e382fc4e --- a/sapl/settings.py +++ b/sapl/settings.py @@ -13,6 +13,8 @@ Quick-start development settings - unsuitable for production See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ """ +import socket +import logging from decouple import config from dj_database_url import parse as db_url @@ -22,10 +24,11 @@ from unipath import Path from .temp_suppress_crispy_form_warnings import \ SUPRESS_CRISPY_FORM_WARNINGS_LOGGING +host = socket.gethostbyname_ex(socket.gethostname())[0] + BASE_DIR = Path(__file__).ancestor(1) PROJECT_DIR = Path(__file__).ancestor(2) - # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = config('SECRET_KEY', default='') # SECURITY WARNING: don't run with debug turned on in production! @@ -293,34 +296,40 @@ SASS_PROCESSOR_INCLUDE_DIRS = (BOWER_COMPONENTS_ROOT.child( # suprime texto de ajuda default do django-filter FILTERS_HELP_TEXT_FILTER = False - -# FIXME update cripy-forms and remove this -# hack to suppress many annoying warnings from crispy_forms -# see sapl.temp_suppress_crispy_form_warnings -LOGGING = SUPRESS_CRISPY_FORM_WARNINGS_LOGGING - - -# FIXME: gerando problemas na alternancia entre django 1.9.13 e 1.10.8 -# Issue 52 https://github.com/interlegis/sapl/issues/52 -LOGGING_CONSOLE = config('LOGGING_CONSOLE', default=False, cast=bool) -"""if DEBUG and LOGGING_CONSOLE: - # Descomentar linha abaixo fará com que logs aparecam, inclusive SQL - # LOGGING['handlers']['console']['level'] = 'DEBUG' - LOGGING['loggers']['django']['level'] = 'DEBUG' - LOGGING['formatters'].update({ +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { 'verbose': { - 'format': '%(levelname)s %(asctime)s %(pathname)s ' - '%(funcName)s %(message)s' + 'format': '%(levelname)s %(asctime)s ' + host + ' %(pathname)s %(name)s:%(funcName)s:%(lineno)d %(message)s' }, 'simple': { - 'format': '%(levelname)s %(message)s' + 'format': '%(levelname)s %(asctime)s - %(message)s' + }, + }, + 'handlers': { + 'console': { + 'level': 'INFO', + 'class': 'logging.StreamHandler', + 'formatter': 'simple', + }, + 'applogfile': { + 'level':'INFO', + 'class':'logging.handlers.RotatingFileHandler', + 'filename': 'sapl.log', + 'maxBytes': 1024*1024*15, # 15MB + 'backupCount': 10, + 'formatter': 'verbose', + }, + }, + 'loggers': { + 'sapl': { + 'handlers': ['applogfile'], + 'level': 'INFO', + 'propagate': True, }, - }) - LOGGING['handlers']['console']['formatter'] = 'verbose' - LOGGING['loggers'][BASE_DIR.name] = { - 'handlers': ['console'], - 'level': 'DEBUG', } +} def excepthook(*args):