Browse Source

Fix #3464

- 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
pull/3468/head
Leandro Roberto 3 years ago
parent
commit
ebe1312246
  1. 1
      docker/docker-compose.yml
  2. 22
      sapl/base/forms.py
  3. 15
      sapl/base/search_indexes.py
  4. 4
      sapl/base/templatetags/common_tags.py
  5. 27
      sapl/base/views.py
  6. 26
      sapl/sessao/migrations/0059_sessaoplenaria_data_ultima_atualizacao.py
  7. 3
      sapl/sessao/models.py
  8. 11
      sapl/sessao/views.py
  9. 7
      sapl/templates/search/indexes/sessao/sessaoplenaria_text.txt
  10. 34
      sapl/templates/search/search.html
  11. 9
      sapl/templates/sessao/sessaoplenaria_filter.html

1
docker/docker-compose.yml

@ -41,7 +41,6 @@ services:
NAME: "sapl" NAME: "sapl"
restart: always restart: always
environment: environment:
LOGGING_CONSOLE_VERBOSE: 'True'
ADMIN_PASSWORD: interlegis ADMIN_PASSWORD: interlegis
ADMIN_EMAIL: email@dominio.net ADMIN_EMAIL: email@dominio.net
DEBUG: 'False' DEBUG: 'False'

22
sapl/base/forms.py

@ -2,6 +2,7 @@ import logging
import os import os
from crispy_forms.bootstrap import FieldWithButtons, InlineRadios, StrictButton, FormActions 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 crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row, Submit
from django import forms from django import forms
from django.conf import settings from django.conf import settings
@ -16,6 +17,7 @@ from django.forms import Form, ModelForm
from django.utils import timezone from django.utils import timezone
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from haystack.forms import ModelSearchForm
import django_filters import django_filters
from sapl.audiencia.models import AudienciaPublica from sapl.audiencia.models import AudienciaPublica
@ -1888,3 +1890,23 @@ class RelatorioNormasPorAutorFilterSet(django_filters.FilterSet):
row3, row3,
form_actions(label='Pesquisar')) 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)"""

15
sapl/base/search_indexes.py

@ -1,5 +1,5 @@
import os.path
import logging import logging
import os.path
from django.db.models import F, Q, Value from django.db.models import F, Q, Value
from django.db.models.fields import TextField from django.db.models.fields import TextField
@ -15,6 +15,7 @@ from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
STATUS_TA_PUBLIC, Dispositivo) STATUS_TA_PUBLIC, Dispositivo)
from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa
from sapl.norma.models import NormaJuridica from sapl.norma.models import NormaJuridica
from sapl.sessao.models import SessaoPlenaria
from sapl.settings import SOLR_URL from sapl.settings import SOLR_URL
from sapl.utils import RemoveTag from sapl.utils import RemoveTag
@ -168,3 +169,15 @@ class MateriaLegislativaIndex(DocumentoAcessorioIndex):
('observacao', 'string_extractor'), ('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'),
)
)

4
sapl/base/templatetags/common_tags.py

@ -1,4 +1,3 @@
from _functools import reduce
import re import re
from django import template from django import template
@ -10,6 +9,7 @@ from sapl.base.models import AppConfig
from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa, Proposicao from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa, Proposicao
from sapl.norma.models import NormaJuridica from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import Filiacao from sapl.parlamentares.models import Filiacao
from sapl.sessao.models import SessaoPlenaria
from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO
register = template.Library() register = template.Library()
@ -311,6 +311,8 @@ def search_get_model(object):
return 'd' return 'd'
elif type(object) == NormaJuridica: elif type(object) == NormaJuridica:
return 'n' return 'n'
elif type(object) == SessaoPlenaria:
return 's'
return None return None

27
sapl/base/views.py

@ -38,7 +38,7 @@ from sapl import settings
from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
from sapl.base.forms import (AutorForm, TipoAutorForm, AutorFilterSet, RecuperarSenhaForm, from sapl.base.forms import (AutorForm, TipoAutorForm, AutorFilterSet, RecuperarSenhaForm,
NovaSenhaForm, UserAdminForm, NovaSenhaForm, UserAdminForm,
OperadorAutorForm, LoginForm) OperadorAutorForm, LoginForm, SaplSearchForm)
from sapl.base.models import Autor, TipoAutor, OperadorAutor from sapl.base.models import Autor, TipoAutor, OperadorAutor
from sapl.comissoes.models import Comissao, Reuniao from sapl.comissoes.models import Comissao, Reuniao
from sapl.crud.base import CrudAux, make_pagination, Crud,\ from sapl.crud.base import CrudAux, make_pagination, Crud,\
@ -2163,15 +2163,40 @@ class AppConfigCrud(CrudAux):
class SaplSearchView(SearchView): class SaplSearchView(SearchView):
results_per_page = 10 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): def get_context(self):
context = super(SaplSearchView, self).get_context() context = super(SaplSearchView, self).get_context()
data = self.request.GET or self.request.POST
data = data.copy()
if 'models' in self.request.GET: if 'models' in self.request.GET:
models = self.request.GET.getlist('models') models = self.request.GET.getlist('models')
else: else:
models = [] models = []
context['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: for m in models:
context['models'] = context['models'] + '&models=' + m context['models'] = context['models'] + '&models=' + m

26
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),
]

3
sapl/sessao/models.py

@ -229,6 +229,9 @@ class SessaoPlenaria(models.Model):
tema_solene = models.TextField( tema_solene = models.TextField(
blank=True, max_length=500, verbose_name=_('Tema da Sessão Solene')) 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: class Meta:
verbose_name = _('Sessão Plenária') verbose_name = _('Sessão Plenária')
verbose_name_plural = _('Sessões Plenárias') verbose_name_plural = _('Sessões Plenárias')

11
sapl/sessao/views.py

@ -3,6 +3,7 @@ from collections import OrderedDict
from re import sub from re import sub
import logging import logging
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
@ -52,6 +53,7 @@ from .models import (Bancada, CargoBancada, CargoMesa,
RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia, RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia,
ORDENACAO_RESUMO, RegistroLeitura) ORDENACAO_RESUMO, RegistroLeitura)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa') TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa')
CargoBancadaCrud = CrudAux.build(CargoBancada, '') CargoBancadaCrud = CrudAux.build(CargoBancada, '')
@ -2537,7 +2539,8 @@ class ConsideracoesFinaisView(FormMixin, DetailView):
return context return context
def delete(self): def delete(self):
ConsideracoesFinais.objects.filter(sessao_plenaria=self.object).delete() ConsideracoesFinais.objects.filter(
sessao_plenaria=self.object).delete()
username = self.request.user.username username = self.request.user.username
self.logger.info('user=' + username + '. ConsideracoesFinais com SessaoPlenaria de id={} deletada.' self.logger.info('user=' + username + '. ConsideracoesFinais com SessaoPlenaria de id={} deletada.'
@ -2549,7 +2552,8 @@ class ConsideracoesFinaisView(FormMixin, DetailView):
def save(self, form): def save(self, form):
conteudo = form.cleaned_data['conteudo'] conteudo = form.cleaned_data['conteudo']
ConsideracoesFinais.objects.filter(sessao_plenaria=self.object).delete() ConsideracoesFinais.objects.filter(
sessao_plenaria=self.object).delete()
consideracao = ConsideracoesFinais() consideracao = ConsideracoesFinais()
consideracao.sessao_plenaria_id = self.object.id consideracao.sessao_plenaria_id = self.object.id
@ -3830,6 +3834,9 @@ class PesquisarSessaoPlenariaView(FilterView):
context['page_range'] = make_pagination( context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context['USE_SOLR'] = settings.USE_SOLR if hasattr(
settings, 'USE_SOLR') else False
return context return context
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):

7
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 }}

34
sapl/templates/search/search.html

@ -81,7 +81,26 @@
<strong>Texto Articulado:</strong> <a href="{% url 'sapl.norma:norma_ta' result.object.pk %}"> Clique aqui </a></br> <strong>Texto Articulado:</strong> <a href="{% url 'sapl.norma:norma_ta' result.object.pk %}"> Clique aqui </a></br>
{% endif %} {% endif %}
</p> </p>
{% elif result.object|search_get_model == 's' %}
<p>
<strong>Sessão Plenária: </strong><a href="{% url 'sapl.sessao:sessaoplenaria_detail' result.object.pk %}">{{ result.object }}</a></br>
<strong>Abertura:</strong> {{result.object.data_inicio}}</br>
<strong>Legislatura:</strong> {{result.object.legislatura}}</br>
<strong>Sessão Legislativa:</strong> {{result.object.sessao_legislativa}}</br>
<strong>Tipo:</strong> {{result.object.tipo}}</br>
{% if result.object.upload_ata %}
<strong>Ata:</strong> <a href="{{result.object.upload_ata.url}}"> Clique aqui </a></br>
{% endif %}
{% if result.object.upload_pauta %}
<strong>Pauta:</strong> <a href="{{result.object.upload_pauta.url}}"> Clique aqui </a></br>
{% endif %}
{% if result.object.upload_anexo %}
<strong>Anexo:</strong> <a href="{{result.object.upload_anexo.url}}"> Clique aqui </a></br>
{% endif %} {% endif %}
</p>
{% endif %}
</td> </td>
</tr> </tr>
@ -93,18 +112,11 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
{% if page.object_list %}
{% if page.has_previous or page.has_next %} {% include "paginacao.html" %}
<div>
{% if page.has_previous %}
<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}{{ models }}">
{% endif %}&laquo; Anterior{% if page.has_previous %}</a>{% endif %}
|
{% if page.has_next %}
<a href="?q={{ query }}&amp;page={{ page.next_page_number }}{{ models }}">
{% endif %}Próxima &raquo;{% if page.has_next %}</a>{% endif %}
</div>
{% endif %} {% endif %}
{% else %} {% else %}
{% if 'q=' in request.get_full_path %} {% if 'q=' in request.get_full_path %}
<strong><h2>Favor informar um conjunto de caracteres na caixa 'Pesquisar' para realizar a busca</h2></strong> <strong><h2>Favor informar um conjunto de caracteres na caixa 'Pesquisar' para realizar a busca</h2></strong>

9
sapl/templates/sessao/sessaoplenaria_filter.html

@ -1,14 +1,19 @@
{% extends "crud/detail.html" %} {% extends "crud/detail.html" %}
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags common_tags %}
{% block actions %} {% block actions %}
<div class="actions btn-group float-right" role="group"> <div class="actions btn-group float-right" role="group">
{% if USE_SOLR %}
<a href="{% url 'sapl.base:haystack_search' %}" class="btn btn-outline-primary">
Pesquisa Textual
</a>
{% endif %}
{% if perms.sessao %} {% if perms.sessao %}
<a href="{% url 'sapl.sessao:sessaoplenaria_create' %}" class="btn btn-outline-primary"> <a href="{% url 'sapl.sessao:sessaoplenaria_create' %}" class="btn btn-outline-primary">
{% blocktrans with verbose_name=view.verbose_name %} Adicionar Sessão Plenária {% endblocktrans %} {% blocktrans with verbose_name=view.verbose_name %} Adicionar Sessão Plenária {% endblocktrans %}
{% endif %}
</a> </a>
{% endif %}
</div> </div>
{% endblock %} {% endblock %}

Loading…
Cancel
Save