From ebe13122469476841b8b16a9560ecb0f3b3302b9 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Thu, 21 Oct 2021 23:18:41 -0300
Subject: [PATCH] Fix #3464
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Adição o model SessaoPlenaria à pesquisa textual
- cria SaplSearchForm e fixa ordem da listagem decr por last_updated
- aplica paginação padrão do Sapl à pesquisa textual
---
docker/docker-compose.yml | 1 -
sapl/base/forms.py | 22 ++++++++++++
sapl/base/search_indexes.py | 15 +++++++-
sapl/base/templatetags/common_tags.py | 4 ++-
sapl/base/views.py | 27 ++++++++++++++-
..._sessaoplenaria_data_ultima_atualizacao.py | 26 ++++++++++++++
sapl/sessao/models.py | 3 ++
sapl/sessao/views.py | 15 +++++---
.../indexes/sessao/sessaoplenaria_text.txt | 7 ++++
sapl/templates/search/search.html | 34 +++++++++++++------
.../sessao/sessaoplenaria_filter.html | 9 +++--
11 files changed, 142 insertions(+), 21 deletions(-)
create mode 100644 sapl/sessao/migrations/0059_sessaoplenaria_data_ultima_atualizacao.py
create mode 100644 sapl/templates/search/indexes/sessao/sessaoplenaria_text.txt
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index f731f3956..e466ad173 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -41,7 +41,6 @@ services:
NAME: "sapl"
restart: always
environment:
- LOGGING_CONSOLE_VERBOSE: 'True'
ADMIN_PASSWORD: interlegis
ADMIN_EMAIL: email@dominio.net
DEBUG: 'False'
diff --git a/sapl/base/forms.py b/sapl/base/forms.py
index 1dd54e3a7..b6d6c6c6d 100644
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -2,6 +2,7 @@ import logging
import os
from crispy_forms.bootstrap import FieldWithButtons, InlineRadios, StrictButton, FormActions
+from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row, Submit
from django import forms
from django.conf import settings
@@ -16,6 +17,7 @@ from django.forms import Form, ModelForm
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
+from haystack.forms import ModelSearchForm
import django_filters
from sapl.audiencia.models import AudienciaPublica
@@ -1888,3 +1890,23 @@ class RelatorioNormasPorAutorFilterSet(django_filters.FilterSet):
row3,
form_actions(label='Pesquisar'))
)
+
+
+class SaplSearchForm(ModelSearchForm):
+
+ def search(self):
+ sqs = super().search()
+
+ return sqs.order_by('-last_update')
+
+ """def get_models(self):
+ Return a list of the selected models.
+ search_models = []
+
+ if self.is_valid():
+ for model in self.cleaned_data['models']:
+ search_models.append(haystack_get_model(*model.split('.')))
+
+ return search_models
+
+ return ModelSearchForm.get_models(self)"""
diff --git a/sapl/base/search_indexes.py b/sapl/base/search_indexes.py
index 359fbd44b..7e5df5737 100644
--- a/sapl/base/search_indexes.py
+++ b/sapl/base/search_indexes.py
@@ -1,5 +1,5 @@
-import os.path
import logging
+import os.path
from django.db.models import F, Q, Value
from django.db.models.fields import TextField
@@ -15,6 +15,7 @@ from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
STATUS_TA_PUBLIC, Dispositivo)
from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa
from sapl.norma.models import NormaJuridica
+from sapl.sessao.models import SessaoPlenaria
from sapl.settings import SOLR_URL
from sapl.utils import RemoveTag
@@ -168,3 +169,15 @@ class MateriaLegislativaIndex(DocumentoAcessorioIndex):
('observacao', 'string_extractor'),
)
)
+
+
+class SessaoPlenariaIndex(DocumentoAcessorioIndex):
+ model = SessaoPlenaria
+ text = TextExtractField(
+ document=True, use_template=True,
+ model_attr=(
+ ('upload_ata', 'file_extractor'),
+ ('upload_anexo', 'file_extractor'),
+ ('upload_pauta', 'file_extractor'),
+ )
+ )
diff --git a/sapl/base/templatetags/common_tags.py b/sapl/base/templatetags/common_tags.py
index 4a34ad646..10b1a7054 100644
--- a/sapl/base/templatetags/common_tags.py
+++ b/sapl/base/templatetags/common_tags.py
@@ -1,4 +1,3 @@
-from _functools import reduce
import re
from django import template
@@ -10,6 +9,7 @@ from sapl.base.models import AppConfig
from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa, Proposicao
from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import Filiacao
+from sapl.sessao.models import SessaoPlenaria
from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO
register = template.Library()
@@ -311,6 +311,8 @@ def search_get_model(object):
return 'd'
elif type(object) == NormaJuridica:
return 'n'
+ elif type(object) == SessaoPlenaria:
+ return 's'
return None
diff --git a/sapl/base/views.py b/sapl/base/views.py
index 8dfc6df28..dab5b1f2d 100644
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -38,7 +38,7 @@ from sapl import settings
from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
from sapl.base.forms import (AutorForm, TipoAutorForm, AutorFilterSet, RecuperarSenhaForm,
NovaSenhaForm, UserAdminForm,
- OperadorAutorForm, LoginForm)
+ OperadorAutorForm, LoginForm, SaplSearchForm)
from sapl.base.models import Autor, TipoAutor, OperadorAutor
from sapl.comissoes.models import Comissao, Reuniao
from sapl.crud.base import CrudAux, make_pagination, Crud,\
@@ -2163,15 +2163,40 @@ class AppConfigCrud(CrudAux):
class SaplSearchView(SearchView):
results_per_page = 10
+ def __init__(self, template=None, load_all=True, form_class=None, searchqueryset=None, results_per_page=None):
+ super().__init__(
+ template=template,
+ load_all=load_all,
+ form_class=SaplSearchForm,
+ searchqueryset=None,
+ results_per_page=results_per_page
+ )
+
def get_context(self):
context = super(SaplSearchView, self).get_context()
+ data = self.request.GET or self.request.POST
+ data = data.copy()
+
if 'models' in self.request.GET:
models = self.request.GET.getlist('models')
else:
models = []
context['models'] = ''
+ context['is_paginated'] = True
+
+ page_obj = context['page']
+ context['page_obj'] = page_obj
+ paginator = context['paginator']
+ context['page_range'] = make_pagination(
+ page_obj.number, paginator.num_pages)
+
+ if 'page' in data:
+ del data['page']
+
+ context['filter_url'] = (
+ '&' + data.urlencode()) if len(data) > 0 else ''
for m in models:
context['models'] = context['models'] + '&models=' + m
diff --git a/sapl/sessao/migrations/0059_sessaoplenaria_data_ultima_atualizacao.py b/sapl/sessao/migrations/0059_sessaoplenaria_data_ultima_atualizacao.py
new file mode 100644
index 000000000..106945740
--- /dev/null
+++ b/sapl/sessao/migrations/0059_sessaoplenaria_data_ultima_atualizacao.py
@@ -0,0 +1,26 @@
+# Generated by Django 2.2.24 on 2021-10-22 00:36
+
+from django.core.management import call_command
+from django.db import migrations, models
+
+
+def update_solr(*args, **kwargs):
+ call_command('update_index', 'sessao', verbosity=3, batchsize=100)
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sessao', '0058_corrige_data_ordem'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='sessaoplenaria',
+ name='data_ultima_atualizacao',
+ field=models.DateTimeField(
+ auto_now=True, null=True, verbose_name='Data'),
+ ),
+ migrations.RunPython(update_solr),
+
+ ]
diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py
index c7b7d54cb..ada5310bb 100644
--- a/sapl/sessao/models.py
+++ b/sapl/sessao/models.py
@@ -229,6 +229,9 @@ class SessaoPlenaria(models.Model):
tema_solene = models.TextField(
blank=True, max_length=500, verbose_name=_('Tema da Sessão Solene'))
+ data_ultima_atualizacao = models.DateTimeField(
+ blank=True, null=True, auto_now=True, verbose_name=_('Data'))
+
class Meta:
verbose_name = _('Sessão Plenária')
verbose_name_plural = _('Sessões Plenárias')
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 4b27d1272..77e0bd23b 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -3,6 +3,7 @@ from collections import OrderedDict
from re import sub
import logging
+from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -52,6 +53,7 @@ from .models import (Bancada, CargoBancada, CargoMesa,
RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia,
ORDENACAO_RESUMO, RegistroLeitura)
+
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa')
CargoBancadaCrud = CrudAux.build(CargoBancada, '')
@@ -1348,7 +1350,7 @@ class PresencaView(FormMixin, PresencaMixin, DetailView):
# Id dos parlamentares presentes
marcados = request.POST.getlist('presenca_ativos') \
- +request.POST.getlist('presenca_inativos')
+ + request.POST.getlist('presenca_inativos')
# Deletar os que foram desmarcados
deletar = set(presentes_banco) - set(marcados)
@@ -1463,7 +1465,7 @@ class PresencaOrdemDiaView(FormMixin, PresencaMixin, DetailView):
# Id dos parlamentares presentes
marcados = request.POST.getlist('presenca_ativos') \
- +request.POST.getlist('presenca_inativos')
+ + request.POST.getlist('presenca_inativos')
# Deletar os que foram desmarcados
deletar = set(presentes_banco) - set(marcados)
@@ -2537,7 +2539,8 @@ class ConsideracoesFinaisView(FormMixin, DetailView):
return context
def delete(self):
- ConsideracoesFinais.objects.filter(sessao_plenaria=self.object).delete()
+ ConsideracoesFinais.objects.filter(
+ sessao_plenaria=self.object).delete()
username = self.request.user.username
self.logger.info('user=' + username + '. ConsideracoesFinais com SessaoPlenaria de id={} deletada.'
@@ -2549,7 +2552,8 @@ class ConsideracoesFinaisView(FormMixin, DetailView):
def save(self, form):
conteudo = form.cleaned_data['conteudo']
- ConsideracoesFinais.objects.filter(sessao_plenaria=self.object).delete()
+ ConsideracoesFinais.objects.filter(
+ sessao_plenaria=self.object).delete()
consideracao = ConsideracoesFinais()
consideracao.sessao_plenaria_id = self.object.id
@@ -3830,6 +3834,9 @@ class PesquisarSessaoPlenariaView(FilterView):
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
+ context['USE_SOLR'] = settings.USE_SOLR if hasattr(
+ settings, 'USE_SOLR') else False
+
return context
def get(self, request, *args, **kwargs):
diff --git a/sapl/templates/search/indexes/sessao/sessaoplenaria_text.txt b/sapl/templates/search/indexes/sessao/sessaoplenaria_text.txt
new file mode 100644
index 000000000..0f9218324
--- /dev/null
+++ b/sapl/templates/search/indexes/sessao/sessaoplenaria_text.txt
@@ -0,0 +1,7 @@
+{% for k, v in extracted.metadata.items %}
+ {% for val in v %}
+ {{ k }}: {{ val|safe }}
+ {% endfor %}
+{% endfor %}
+
+{{ extracted|striptags|safe }}
\ No newline at end of file
diff --git a/sapl/templates/search/search.html b/sapl/templates/search/search.html
index 302a666ef..ef35ef4b8 100644
--- a/sapl/templates/search/search.html
+++ b/sapl/templates/search/search.html
@@ -81,7 +81,26 @@
Texto Articulado: Clique aqui
{% endif %}
+ {% elif result.object|search_get_model == 's' %}
+
+ Sessão Plenária: {{ result.object }}
+ Abertura: {{result.object.data_inicio}}
+ Legislatura: {{result.object.legislatura}}
+ Sessão Legislativa: {{result.object.sessao_legislativa}}
+ Tipo: {{result.object.tipo}}
+ {% if result.object.upload_ata %}
+ Ata: Clique aqui
+ {% endif %}
+ {% if result.object.upload_pauta %}
+ Pauta: Clique aqui
+ {% endif %}
+ {% if result.object.upload_anexo %}
+ Anexo: Clique aqui
+ {% endif %}
+
{% endif %}
+
+
@@ -93,18 +112,11 @@
{% endfor %}
-
- {% if page.has_previous or page.has_next %}
-
+ {% if page.object_list %}
+ {% include "paginacao.html" %}
{% endif %}
+
+
{% else %}
{% if 'q=' in request.get_full_path %}
Favor informar um conjunto de caracteres na caixa 'Pesquisar' para realizar a busca
diff --git a/sapl/templates/sessao/sessaoplenaria_filter.html b/sapl/templates/sessao/sessaoplenaria_filter.html
index 86b08c941..8d0957d51 100644
--- a/sapl/templates/sessao/sessaoplenaria_filter.html
+++ b/sapl/templates/sessao/sessaoplenaria_filter.html
@@ -1,14 +1,19 @@
{% extends "crud/detail.html" %}
{% load i18n %}
-{% load crispy_forms_tags %}
+{% load crispy_forms_tags common_tags %}
{% block actions %}
{% endblock %}