From c4eea181fbd301956f300238b7900254f8e2290c Mon Sep 17 00:00:00 2001 From: Matheus Veleci dos Santos Date: Mon, 10 Apr 2017 12:48:51 -0300 Subject: [PATCH 01/26] Ajusta Docker do SAPL com NGINX e GUNICORN. (#997) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adiciona Docker baseado em Alpine-Python3 com Ngnix e Gunicorn * Atualiza docker-compose com gunicorn, ngnix e postgres * Ajusta gitignore para ignorar postgres-data * Adiciona script bash para conexao ao banco * Ajusta busy-wait.sh script para sincronizar o banco(postgres) com a aplicação django no docker * Add alias to sapldb --- .gitignore | 3 +- .travis.yml | 4 +++ Dockerfile | 59 ++++++++++-------------------------- busy-wait.sh | 10 ++++++ config/nginx/sapl.conf | 39 ++++++++++++++++++++++++ docker-compose.yml | 21 ++++++++++--- gunicorn_start.sh | 12 ++------ sapl/.env_test | 2 +- scripts_docker/shell_sapl.sh | 3 +- 9 files changed, 93 insertions(+), 60 deletions(-) create mode 100644 busy-wait.sh create mode 100644 config/nginx/sapl.conf diff --git a/.gitignore b/.gitignore index 83de47a86..e8bac47aa 100644 --- a/.gitignore +++ b/.gitignore @@ -92,4 +92,5 @@ collected_static bower bower_components media -whoosh/ \ No newline at end of file +whoosh/ +postgres-data/ diff --git a/.travis.yml b/.travis.yml index bf5ee38fd..0e0a27ad4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,3 +20,7 @@ script: - ./manage.py bower install - py.test --create-db # - ./test_and_check_qa.sh + +addons: + hosts: + - 127.0.0.1 sapldb diff --git a/Dockerfile b/Dockerfile index 9880dc4ef..a7bf01657 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,53 +1,26 @@ -FROM ubuntu:15.04 +FROM alpine:3.5 -RUN locale-gen en_US.UTF-8 -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 +ENV BUILD_PACKAGES postgresql-dev graphviz-dev graphviz build-base git pkgconfig \ +python3-dev libxml2-dev jpeg-dev libressl-dev libffi-dev libxslt-dev nodejs py3-lxml \ +py3-magic postgresql-client -RUN mkdir /sapl +RUN apk add --no-cache python3 && \ + python3 -m ensurepip && \ + rm -r /usr/lib/python*/ensurepip && \ + pip3 install --upgrade pip setuptools && \ + rm -r /root/.cache -RUN echo "deb http://archive.ubuntu.com/ubuntu/ vivid universe" | tee -a "/etc/apt/sources.list" - -RUN \ - apt-get update && \ - apt-get install -y -f \ - software-properties-common \ - libpq-dev \ - graphviz-dev \ - graphviz \ - build-essential \ - git \ - pkg-config \ - python3-dev \ - libxml2-dev \ - libjpeg-dev \ - libssl-dev \ - libffi-dev \ - libxslt1-dev \ - python3-setuptools \ - curl - -# use python3 in pip -RUN easy_install3 pip lxml - -# install nodejs -RUN DEBIAN_FRONTEND=noninteractive curl -sL https://deb.nodesource.com/setup_5.x | bash - -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs - -# install bower -RUN npm install -g bower +RUN mkdir /sapl && apk add --update --no-cache $BUILD_PACKAGES && npm install -g bower # Bower aceitar root -RUN touch /root/.bowerrc -RUN chmod 751 /root/.bowerrc -RUN echo "{ \"allow_root\": true }" >> /root/.bowerrc +RUN touch /root/.bowerrc \ +&& chmod 751 /root/.bowerrc \ +&& echo "{ \"allow_root\": true }" >> /root/.bowerrc \ +&& npm cache clean WORKDIR /sapl ADD . /sapl -RUN pip install -r requirements/dev-requirements.txt -RUN pip install --upgrade setuptools - -# RUN python3 manage.py bower install +RUN pip install -r requirements/dev-requirements.txt --upgrade setuptools --no-cache-dir \ +&& python3 manage.py bower install diff --git a/busy-wait.sh b/busy-wait.sh new file mode 100644 index 000000000..128592ffc --- /dev/null +++ b/busy-wait.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +while true; do + COUNT_PG=`psql --dbname=postgresql://sapl:sapl@sapldb/sapl -c '\l \q' | grep sapl | wc -l` + if ! [ "$COUNT_PG" -eq "0" ]; then + break + fi + echo "Esperando Database Setup" + sleep 10 +done diff --git a/config/nginx/sapl.conf b/config/nginx/sapl.conf new file mode 100644 index 000000000..513188ed9 --- /dev/null +++ b/config/nginx/sapl.conf @@ -0,0 +1,39 @@ +upstream sapl_server { + + server unix:/sapl/run/gunicorn.sock fail_timeout=0; + +} + +server { + + listen 80; + server_name sapl.test; + + client_max_body_size 4G; + + location /static/ { + alias /sapl/collected_static/; + } + + location /media/ { + alias /sapl/media/; + } + + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header Host $http_host; + + proxy_redirect off; + + + if (!-f $request_filename) { + proxy_pass http://sapl_server; + break; + } + } + error_page 500 502 503 504 /500.html; + location = /500.html { + root /sapl/sapl/static/; + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 06c9d2cec..ce5c283fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,28 @@ -localhost: +server: + image: nginx:latest + ports: + - "80:80" + volumes: + - ./config/nginx:/etc/nginx/conf.d + volumes_from: + - web + links: + - web +sapldb: image: postgres environment: POSTGRES_PASSWORD: sapl POSTGRES_USER: sapl POSTGRES_DB: sapl + PGDATA : /var/lib/postgresql/data/ + volumes: + - ./postgres-data/data/:/var/lib/postgresql/data/ ports: - "5532:5432" web: build: . - command: bash -c "python3 manage.py bower install && python3 manage.py migrate && python3 manage.py runserver 0.0.0.0:8000" + command: /bin/sh -c "/bin/sh busy-wait.sh && python3 manage.py bower install && python3 manage.py migrate && /bin/sh gunicorn_start.sh" volumes: - .:/sapl - ports: - - "8000:8000" links: - - localhost + - sapldb diff --git a/gunicorn_start.sh b/gunicorn_start.sh index 904d76a3a..aebd45c83 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -3,23 +3,17 @@ # As seen in http://tutos.readthedocs.org/en/latest/source/ndg.html NAME="SAPL" # Name of the application (*) -DJANGODIR=/var/interlegis/sapl # Django project directory (*) -SOCKFILE=/var/interlegis/sapl/run/gunicorn.sock # we will communicate using this unix socket (*) +DJANGODIR=/sapl/ # Django project directory (*) +SOCKFILE=/sapl/run/gunicorn.sock # we will communicate using this unix socket (*) USER=`whoami` # the user to run as (*) GROUP=`whoami` # the group to run as (*) -NUM_WORKERS=9 # how many worker processes should Gunicorn spawn (*) +NUM_WORKERS=3 # how many worker processes should Gunicorn spawn (*) # NUM_WORKERS = 2 * CPUS + 1 DJANGO_SETTINGS_MODULE=sapl.settings # which settings file should Django use (*) DJANGO_WSGI_MODULE=sapl.wsgi # WSGI module name (*) echo "Starting $NAME as `whoami`" -# Activate the virtual environment -cd $DJANGODIR -source /var/interlegis/.virtualenvs/sapl/bin/activate -export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE -export PYTHONPATH=$DJANGODIR:$PYTHONPATH - # Create the run directory if it doesn't exist RUNDIR=$(dirname $SOCKFILE) test -d $RUNDIR || mkdir -p $RUNDIR diff --git a/sapl/.env_test b/sapl/.env_test index 5c2c60ec1..9416d402d 100644 --- a/sapl/.env_test +++ b/sapl/.env_test @@ -1,4 +1,4 @@ -DATABASE_URL = postgresql://postgres:@localhost:/sapl +DATABASE_URL = postgresql://postgres:@sapldb:/sapl SECRET_KEY=TravisTest DEBUG=False EMAIL_USE_TLS = True diff --git a/scripts_docker/shell_sapl.sh b/scripts_docker/shell_sapl.sh index cfddefcdc..4c993a61d 100755 --- a/scripts_docker/shell_sapl.sh +++ b/scripts_docker/shell_sapl.sh @@ -1,2 +1,3 @@ #!/bin/bash -docker run -ti sapl_web /bin/bash + +docker run --rm -ti sapl_web /bin/sh From 39d0645c923beab7ffa940007e9bd6753c07921a Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 10 Apr 2017 11:22:30 -0300 Subject: [PATCH 02/26] Conserta erros de QA --- sapl/base/search_indexes.py | 3 ++- .../templatetags/compilacao_filters.py | 3 ++- sapl/crispy_layout_mixin.py | 2 +- sapl/crud/base.py | 2 +- sapl/legacy/migration.py | 2 +- sapl/materia/models.py | 3 +-- sapl/materia/signals.py | 7 +++--- sapl/materia/urls.py | 7 +++--- sapl/materia/views.py | 24 +++++++++---------- sapl/norma/models.py | 4 ++-- sapl/norma/signals.py | 5 ++-- sapl/norma/views.py | 1 + sapl/parlamentares/views.py | 1 - sapl/protocoloadm/forms.py | 4 ++-- sapl/relatorios/views.py | 11 ++++----- sapl/sessao/views.py | 4 ++-- 16 files changed, 41 insertions(+), 42 deletions(-) diff --git a/sapl/base/search_indexes.py b/sapl/base/search_indexes.py index 1b2944f48..c85be523b 100644 --- a/sapl/base/search_indexes.py +++ b/sapl/base/search_indexes.py @@ -1,8 +1,9 @@ import os.path -import textract +import textract from django.template import Context, loader from haystack import indexes + from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa from sapl.norma.models import NormaJuridica diff --git a/sapl/compilacao/templatetags/compilacao_filters.py b/sapl/compilacao/templatetags/compilacao_filters.py index f3965c43d..941ec5fe1 100644 --- a/sapl/compilacao/templatetags/compilacao_filters.py +++ b/sapl/compilacao/templatetags/compilacao_filters.py @@ -211,7 +211,7 @@ def heranca(request, d, ignore_ultimo=0, ignore_primeiro=0): ta_id = str(d.ta_id) d_pk = str(d.pk) if ta_id not in ta_dpts_parents or d_pk not in ta_dpts_parents[ta_id]: - #print('recarregando estrutura temporaria de heranças') + # print('recarregando estrutura temporaria de heranças') dpts_parents = {} ta_dpts_parents[ta_id] = dpts_parents update_dispositivos_parents(dpts_parents, ta_id) @@ -296,6 +296,7 @@ def urldetail_content_type(obj): def list(obj): return [obj, ] + @register.filter def can_use_dynamic_editing(texto_articulado, user): return texto_articulado.can_use_dynamic_editing(user) diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index e9dbc3f01..369b6fe9e 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -1,12 +1,12 @@ from math import ceil +import rtyaml from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit from django import template from django.utils import formats from django.utils.translation import ugettext as _ -import rtyaml def heads_and_tails(list_of_lists): diff --git a/sapl/crud/base.py b/sapl/crud/base.py index b2223c31f..1a1225cfc 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -842,7 +842,7 @@ class CrudDeleteView(PermissionRequiredContainerCrudMixin, def delete(self, request, *args, **kwargs): try: - return super(CrudDeleteView, self).delete(request, args, kwargs) + return super(CrudDeleteView, self).delete(request, args, kwargs) except models.ProtectedError as err: error_msg = 'Registro não pode ser removido, pois\ é referenciado por outros registros:
\ diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 99d14f8a7..ef87a3960 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -19,7 +19,7 @@ from model_mommy.mommy import foreign_key_required, make from sapl.base.models import Autor, ProblemaMigracao from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.legacy.models import Protocolo as ProtocoloLegado -from sapl.materia.models import (Proposicao, StatusTramitacao, TipoDocumento, +from sapl.materia.models import (StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) from sapl.norma.models import (AssuntoNorma, NormaJuridica, diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 6b48613ee..1a9d2afff 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -1,5 +1,6 @@ from datetime import datetime +import reversion from django.contrib.auth.models import Group from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType @@ -7,7 +8,6 @@ from django.db import models from django.utils import formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import Autor from sapl.comissoes.models import Comissao @@ -18,7 +18,6 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericForeignKey, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) - EM_TRAMITACAO = [(1, 'Sim'), (0, 'Não')] diff --git a/sapl/materia/signals.py b/sapl/materia/signals.py index 96ff85dea..d913e9cd8 100644 --- a/sapl/materia/signals.py +++ b/sapl/materia/signals.py @@ -1,10 +1,11 @@ -from django.db.models.signals import post_delete, post_save -from sapl.settings import PROJECT_DIR from subprocess import PIPE, call from threading import Thread +from django.db.models.signals import post_delete, post_save + +from sapl.settings import PROJECT_DIR -from .models import MateriaLegislativa, DocumentoAcessorio +from .models import DocumentoAcessorio, MateriaLegislativa class UpdateIndexCommand(Thread): diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index 1de8cd689..7eac42e5c 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -4,10 +4,9 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, AcompanhamentoExcluirView, AcompanhamentoMateriaView, AdicionarVariasAutorias, AnexadaCrud, - AssuntoMateriaCrud, - AutoriaCrud, ConfirmarProposicao, - CriarProtocoloMateriaView, DespachoInicialCrud, - DocumentoAcessorioCrud, + AssuntoMateriaCrud, AutoriaCrud, + ConfirmarProposicao, CriarProtocoloMateriaView, + DespachoInicialCrud, DocumentoAcessorioCrud, DocumentoAcessorioEmLoteView, LegislacaoCitadaCrud, MateriaAssuntoCrud, MateriaLegislativaCrud, diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 305b4b7b0..b93d81289 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -43,21 +43,19 @@ from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm, - DocumentoAcessorioForm, - MateriaAssuntoForm, MateriaLegislativaFilterSet, - MateriaSimplificadaForm, PrimeiraTramitacaoEmLoteFilterSet, - ReceberProposicaoForm, RelatoriaForm, - TramitacaoEmLoteFilterSet, filtra_tramitacao_destino, + DocumentoAcessorioForm, MateriaAssuntoForm, + MateriaLegislativaFilterSet, MateriaSimplificadaForm, + PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm, + RelatoriaForm, TramitacaoEmLoteFilterSet, + filtra_tramitacao_destino, filtra_tramitacao_destino_and_status, filtra_tramitacao_status) -from .models import (AssuntoMateria, AcompanhamentoMateria, - Anexada, Autoria, DespachoInicial, - DocumentoAcessorio, MateriaLegislativa, - MateriaAssunto, Numeracao, Orgao, - Origem, Proposicao, RegimeTramitacao, Relatoria, - StatusTramitacao, TipoDocumento, TipoFimRelatoria, - TipoMateriaLegislativa, TipoProposicao, Tramitacao, - UnidadeTramitacao) +from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, + DespachoInicial, DocumentoAcessorio, MateriaAssunto, + MateriaLegislativa, Numeracao, Orgao, Origem, Proposicao, + RegimeTramitacao, Relatoria, StatusTramitacao, + TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa, + TipoProposicao, Tramitacao, UnidadeTramitacao) AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') diff --git a/sapl/norma/models.py b/sapl/norma/models.py index 20b59956f..d91ee2da2 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -7,8 +7,8 @@ from model_utils import Choices from sapl.compilacao.models import TextoArticulado from sapl.materia.models import MateriaLegislativa -from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, texto_upload_path, - restringe_tipos_de_arquivo_txt) +from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, + restringe_tipos_de_arquivo_txt, texto_upload_path) @reversion.register() diff --git a/sapl/norma/signals.py b/sapl/norma/signals.py index fc16f89b4..20d405e49 100644 --- a/sapl/norma/signals.py +++ b/sapl/norma/signals.py @@ -1,8 +1,9 @@ -from django.db.models.signals import post_delete, post_save -from sapl.settings import PROJECT_DIR from subprocess import PIPE, call from threading import Thread +from django.db.models.signals import post_delete, post_save + +from sapl.settings import PROJECT_DIR from .models import NormaJuridica diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 461c1b9ef..9120da4e9 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -4,6 +4,7 @@ from django.http import JsonResponse from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import RedirectView from django_filters.views import FilterView + from sapl.base.models import AppConfig from sapl.compilacao.views import IntegracaoTaView from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index a4f698b5a..d703e1c2c 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -22,7 +22,6 @@ from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, SituacaoMilitar, TipoAfastamento, TipoDependente, Votante) - CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa') PartidoCrud = CrudAux.build(Partido, 'partidos') SessaoLegislativaCrud = CrudAux.build(SessaoLegislativa, 'sessao_legislativa') diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index bca51df31..d8f996fe3 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -544,10 +544,10 @@ class DocumentoAdministrativoForm(ModelForm): ano_protocolo = forms.ChoiceField(required=False, label=Protocolo._meta. - get_field('ano').verbose_name, + get_field('ano').verbose_name, choices=RANGE_ANOS, widget=forms.Select( - attrs={'class': 'selector'})) + attrs={'class': 'selector'})) class Meta: model = DocumentoAdministrativo diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 53b9ef54b..9e482abda 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -8,15 +8,14 @@ from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao from sapl.materia.models import (Autoria, MateriaLegislativa, Numeracao, Tramitacao, UnidadeTramitacao) -from sapl.parlamentares.models import (CargoMesa, ComposicaoMesa, Filiacao, - Parlamentar) +from sapl.parlamentares.models import CargoMesa, Filiacao, Parlamentar from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, TramitacaoAdministrativo) from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, - IntegranteMesa, Orador, - OradorExpediente, OrdemDia, PresencaOrdemDia, - RegistroVotacao, SessaoPlenaria, - SessaoPlenariaPresenca, TipoExpediente) + IntegranteMesa, Orador, OradorExpediente, + OrdemDia, PresencaOrdemDia, RegistroVotacao, + SessaoPlenaria, SessaoPlenariaPresenca, + TipoExpediente) from sapl.settings import STATIC_ROOT from sapl.utils import UF diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index fedc8829e..e56cb749e 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -604,7 +604,7 @@ class PainelView(PermissionRequiredForAppCrudMixin, TemplateView): cronometro_ordem = AppsAppConfig.attr('cronometro_ordem') if (not cronometro_discurso or not cronometro_aparte - or not cronometro_ordem): + or not cronometro_ordem): msg = _( 'Você precisa primeiro configurar os cronômetros \ nas Configurações da Aplicação') @@ -2436,7 +2436,7 @@ def mudar_ordem_materia_sessao(request): sessao_plenaria=pk_sessao, numero_ordem=posicao_inicial) except ObjectDoesNotExist: - raise # TODO tratar essa exceção + raise # TODO tratar essa exceção # Se a posição inicial for menor que a final, todos que # estiverem acima da nova posição devem ter sua ordem decrementada From 9e185ed56597f2581f7df13635277bb4029bf537 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 10 Apr 2017 13:25:15 -0300 Subject: [PATCH 03/26] Desliga teste lento demais (TODO: consertar) --- sapl/test_urls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sapl/test_urls.py b/sapl/test_urls.py index bcddfcc9e..40339cef7 100644 --- a/sapl/test_urls.py +++ b/sapl/test_urls.py @@ -361,6 +361,7 @@ for item in _lista_urls: __lista_urls.append((oper, item))""" +@pytest.mark.skip(reason="TODO: Lento demais. Precisa ser refatorado") @pytest.mark.django_db(transaction=False) @pytest.mark.parametrize('url_item', _lista_urls) def test_permissions_urls_for_users_by_apps(url_item, client): @@ -402,7 +403,7 @@ def test_permissions_urls_for_users_by_apps(url_item, client): container, como é o caso de proposições que possui restrição por usuário e não só por, ou não tem, o campo permission_required """ - if PermissionRequiredForAppCrudMixin in type.mro(key.view_class): + if issubclass(key.view_class, PermissionRequiredForAppCrudMixin): # essa classe deve informar app_label assert hasattr(key.view_class, 'app_label') # app_label deve ter conteudo From 96911c997f6c7d57b1d9ac45a97e33394900cd83 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 15 Mar 2017 12:21:13 -0300 Subject: [PATCH 04/26] Adiciona models para recriar constraints Signed-off-by: Luciano Almeida --- sapl/base/models.py | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/sapl/base/models.py b/sapl/base/models.py index 8825ea2a4..9dd0f5ec3 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -61,16 +61,45 @@ class ProblemaMigracao(models.Model): content_object = GenericForeignKey('content_type', 'object_id') nome_campo = models.CharField(max_length=100, blank=True, - verbose_name='Nome do(s) Campo(s)') + verbose_name=_('Nome do(s) Campo(s)')) problema = models.CharField(max_length=300, verbose_name=_('Problema')) descricao = models.CharField(max_length=300, verbose_name=_('Descrição')) - eh_stub = models.BooleanField(verbose_name='É stub?') + eh_stub = models.BooleanField(verbose_name=_('É stub?')) + eh_importante = models.BooleanField( + default=False, verbose_name=_('É importante?')) class Meta: verbose_name = _('Problema na Migração') verbose_name_plural = _('Problemas na Migração') +@reversion.register() +class Constraint(models.Model): + nome_tabela = models.CharField( + max_length=50, verbose_name=_('Nome da tabela')) + nome_constraint = models.CharField( + max_length=100, verbose_name=_('Nome da constraint')) + nome_model = models.CharField( + max_length=50, verbose_name=_('Nome da model')) + tipo_constraint = models.CharField( + max_length=50, verbose_name=_('Tipo da constraint')) + + class Meta: + verbose_name = _('Constraint removida') + verbose_name_plural = _('Constraints removidas') + + +@reversion.register() +class Argumento(models.Model): + constraint = models.ForeignKey(Constraint) + argumento = models.CharField( + max_length=50, verbose_name=_('Argumento')) + + class Meta: + verbose_name = _('Argumento da constraint') + verbose_name_plural = _('Argumentos da constraint') + + @reversion.register() class AppConfig(models.Model): From f4224f3326a330074da66535a159daf6ef81a368 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 15 Mar 2017 12:22:11 -0300 Subject: [PATCH 05/26] =?UTF-8?q?Muda=20m=C3=A9todo=20de=20recriar=20const?= =?UTF-8?q?raints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 64 +++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index ef87a3960..c4c7d0f77 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -16,7 +16,7 @@ from django.db.models.base import ModelBase from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make -from sapl.base.models import Autor, ProblemaMigracao +from sapl.base.models import Autor, ProblemaMigracao, Constraint, Argumento from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.legacy.models import Protocolo as ProtocoloLegado from sapl.materia.models import (StatusTramitacao, TipoDocumento, @@ -109,6 +109,10 @@ def warn(msg): print('CUIDADO! ' + msg) +def erro(msg): + print('ERRO: ' + msg) + + def get_fk_related(field, value, label=None): if value is None and field.null is False: value = 0 @@ -210,40 +214,66 @@ def delete_constraints(model): for r in result: if r[0].endswith('key'): words_list = r[0].split('_') - one_to_one_constraints.append([table, r[0], words_list, model]) + constraint = Constraint.objects.create( + nome_tabela=table, nome_constraint=r[0], + nome_model=model.__name__, tipo_constraint='one_to_one') + for w in words_list: + Argumento.objects.create(constraint=constraint, argumento=w) else: args = None - args_list = [] if model._meta.unique_together: args = model._meta.unique_together[0] args_list = list(args) - unique_constraints.append([table, r[0], args_list, model]) + constraint = Constraint.objects.create( + nome_tabela=table, nome_constraint=r[0], + nome_model=model.__name__, + tipo_constraint='unique_together') + for a in args_list: + Argumento.objects.create(constraint=constraint, + argumento=a) warn('Excluindo unique constraint de nome %s' % r[0]) exec_sql("ALTER TABLE %s DROP CONSTRAINT %s;" % (table, r[0])) def recreate_constraints(): - if one_to_one_constraints: - for constraint in one_to_one_constraints: - table, name, args, model = constraint + constraints = Constraint.objects.all() + for con in constraints: + if con.tipo_constraint == 'one_to_one': + nome_tabela = con.nome_tabela + nome_constraint = con.nome_constraint + args = [a.argumento for a in con.argumento_set.all()] args_string = '' args_string = "(" + "_".join(map(str, args[2:-1])) + ")" - exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" % - (table, name, args_string)) - if unique_constraints: - for constraint in unique_constraints: - table, name, args, model = constraint + try: + exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" % + (nome_tabela, nome_constraint, args_string)) + except ProgrammingError: + info('A constraint %s já foi recriada!' % nome_constraint) + if con.tipo_constraint == 'unique_together': + nome_tabela = con.nome_tabela + nome_constraint = con.nome_constraint + model = ContentType.objects.get( + model=con.nome_model.lower()).model_class() + args = [a.argumento for a in con.argumento_set.all()] for i in range(len(args)): if isinstance(model._meta.get_field(args[i]), models.ForeignKey): args[i] = args[i] + '_id' args_string = '' args_string += "(" + ', '.join(map(str, args)) + ")" - exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" % - (table, name, args_string)) - one_to_one_constraints.clear() - unique_constraints.clear() + try: + exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" % + (nome_tabela, nome_constraint, args_string)) + except ProgrammingError: + info('A constraint %s já foi recriada!' % nome_constraint) + except Exception as err: + problema = re.findall('\(.*?\)', err.args[0]) + erro('A constraint [%s] da tabela [%s] não pode ser recriada' % + (nome_constraint, nome_tabela)) + erro('Os dados %s = %s estão duplicados. ' + 'Arrume antes de recriar as constraints!' % + (problema[0], problema[1])) def obj_desnecessario(obj): @@ -435,8 +465,6 @@ class DataMigrator: info('Deletando stubs desnecessários...') while self.delete_stubs(): pass - info('Recriando unique constraints...') - # recreate_constraints() def _do_migrate(self, obj): if isinstance(obj, AppConfig): From e276d87d19c95350a96805e27a48687af413338b Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 3 Apr 2017 13:53:45 -0300 Subject: [PATCH 06/26] =?UTF-8?q?Arruma=20problema=20da=20recria=C3=A7?= =?UTF-8?q?=C3=A3o=20das=20constraints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- .../migrations/0002_auto_20170331_1900.py | 51 +++++++++++++++++++ sapl/legacy/migration.py | 6 ++- 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 sapl/base/migrations/0002_auto_20170331_1900.py diff --git a/sapl/base/migrations/0002_auto_20170331_1900.py b/sapl/base/migrations/0002_auto_20170331_1900.py new file mode 100644 index 000000000..5ee726647 --- /dev/null +++ b/sapl/base/migrations/0002_auto_20170331_1900.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.12 on 2017-03-31 19:00 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Argumento', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('argumento', models.CharField(max_length=50, verbose_name='Argumento')), + ], + options={ + 'verbose_name': 'Argumento da constraint', + 'verbose_name_plural': 'Argumentos da constraint', + }, + ), + migrations.CreateModel( + name='Constraint', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nome_tabela', models.CharField(max_length=50, verbose_name='Nome da tabela')), + ('nome_constraint', models.CharField(max_length=100, verbose_name='Nome da constraint')), + ('nome_model', models.CharField(max_length=50, verbose_name='Nome da model')), + ('tipo_constraint', models.CharField(max_length=50, verbose_name='Tipo da constraint')), + ], + options={ + 'verbose_name': 'Constraint removida', + 'verbose_name_plural': 'Constraints removidas', + }, + ), + migrations.AddField( + model_name='problemamigracao', + name='eh_importante', + field=models.BooleanField(default=False, verbose_name='É importante?'), + ), + migrations.AddField( + model_name='argumento', + name='constraint', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.Constraint'), + ), + ] diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index c4c7d0f77..60ab48e23 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -253,8 +253,10 @@ def recreate_constraints(): if con.tipo_constraint == 'unique_together': nome_tabela = con.nome_tabela nome_constraint = con.nome_constraint - model = ContentType.objects.get( - model=con.nome_model.lower()).model_class() + # Pegando explicitamente o primeiro valor do filter, + # pois pode ser que haja mais de uma ocorrência + model = ContentType.objects.filter( + model=con.nome_model.lower())[0].model_class() args = [a.argumento for a in con.argumento_set.all()] for i in range(len(args)): if isinstance(model._meta.get_field(args[i]), From 7f24bea073ed3242533f3e86c217ec11816f5f46 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 3 Apr 2017 14:24:47 -0300 Subject: [PATCH 07/26] Comando do manage.py para recriar constraints Signed-off-by: Luciano Almeida --- .../legacy/management/commands/recria_constraints.py | 12 ++++++++++++ sapl/legacy/migration.py | 4 ++-- sapl/legacy/scripts/migra_um_db.sh | 6 ++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 sapl/legacy/management/commands/recria_constraints.py diff --git a/sapl/legacy/management/commands/recria_constraints.py b/sapl/legacy/management/commands/recria_constraints.py new file mode 100644 index 000000000..9e999e5f6 --- /dev/null +++ b/sapl/legacy/management/commands/recria_constraints.py @@ -0,0 +1,12 @@ +from django.core.management.base import BaseCommand + +from sapl.legacy.migration import recria_constraints + + +class Command(BaseCommand): + + help = (u'Recria constraints do PostgreSQL excluidas durante ' + 'migração de dados') + + def handle(self, *args, **options): + recria_constraints() diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 60ab48e23..cb24664b0 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -236,7 +236,7 @@ def delete_constraints(model): (table, r[0])) -def recreate_constraints(): +def recria_constraints(): constraints = Constraint.objects.all() for con in constraints: if con.tipo_constraint == 'one_to_one': @@ -459,7 +459,7 @@ class DataMigrator: for obj in self.to_delete: msg = 'A entrada de PK %s da model %s não pode ser ' \ 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Um ou mais objetos protegidos ' + descricao = 'Um ou mais objetos protegidos' warn(msg + ' => ' + descricao) save_relation(obj=obj, problema=msg, descricao=descricao, eh_stub=False) diff --git a/sapl/legacy/scripts/migra_um_db.sh b/sapl/legacy/scripts/migra_um_db.sh index 26240d8d4..f55dfb53a 100755 --- a/sapl/legacy/scripts/migra_um_db.sh +++ b/sapl/legacy/scripts/migra_um_db.sh @@ -23,3 +23,9 @@ echo "--- MIGRACAO DE DADOS ---" | tee -a $LOG echo >> $LOG DATABASE_NAME=$1 ./manage.py migracao_25_31 -f --settings sapl.legacy_migration_settings |& tee -a $LOG echo >> $LOG + + +echo "--- RECRIANDO CONSTRAINTS ---" | tee -a $LOG +echo >> $LOG +DATABASE_NAME=$1 ./manage.py recria_constraints --settings sapl.legacy_migration_settings |& tee -a $LOG +echo >> $LOG From 9a0e16b6098f14b86aaa3eeada3c74ce82c3296a Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 10 Apr 2017 14:00:56 -0300 Subject: [PATCH 08/26] =?UTF-8?q?Desconecta=20sinais=20de=20indexa=C3=A7?= =?UTF-8?q?=C3=A3o=20durante=20migra=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 38 +++++++++++++++++++++++++++++++------- sapl/materia/signals.py | 22 +--------------------- sapl/norma/signals.py | 22 +--------------------- sapl/utils.py | 20 +++++++++++++++++++- 4 files changed, 52 insertions(+), 50 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index cb24664b0..9fee4683e 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -13,22 +13,23 @@ from django.core.exceptions import ObjectDoesNotExist from django.db import OperationalError, ProgrammingError, connections, models from django.db.models import CharField, Max, ProtectedError, TextField from django.db.models.base import ModelBase +from django.db.models.signals import post_delete, post_save from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make from sapl.base.models import Autor, ProblemaMigracao, Constraint, Argumento from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.legacy.models import Protocolo as ProtocoloLegado -from sapl.materia.models import (StatusTramitacao, TipoDocumento, +from sapl.materia.models import (StatusTramitacao, TipoDocumento, Tramitacao, TipoMateriaLegislativa, TipoProposicao, - Tramitacao) + DocumentoAcessorio, MateriaLegislativa) from sapl.norma.models import (AssuntoNorma, NormaJuridica, TipoVinculoNormaJuridica) from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia from sapl.settings import PROJECT_DIR -from sapl.utils import normalize +from sapl.utils import normalize, save_texto, delete_texto # BASE ###################################################################### # apps to be migrated, in app dependency order (very important) @@ -294,8 +295,8 @@ def get_last_value(model): def alter_sequence(model, id): sequence_name = '%s_id_seq' % model._meta.db_table - exec_sql('ALTER SEQUENCE %s RESTART WITH %s MINVALUE %s;' % ( - sequence_name, id, id)) + exec_sql('ALTER SEQUENCE %s RESTART WITH %s MINVALUE -1;' % ( + sequence_name, id)) def save_with_id(new, id): @@ -310,8 +311,7 @@ def save_relation(obj, nome_campo='', problema='', descricao='', eh_stub=False): link = ProblemaMigracao( content_object=obj, nome_campo=nome_campo, problema=problema, - descricao=descricao, eh_stub=eh_stub, - ) + descricao=descricao, eh_stub=eh_stub,) link.save() @@ -448,6 +448,8 @@ class DataMigrator: call([PROJECT_DIR.child('manage.py'), 'flush', '--database=default', '--no-input'], stdout=PIPE) + disconecta_sinais_indexacao() + info('Começando migração: %s...' % obj) self._do_migrate(obj) @@ -468,6 +470,8 @@ class DataMigrator: while self.delete_stubs(): pass + conecta_sinais_indexacao() + def _do_migrate(self, obj): if isinstance(obj, AppConfig): models_to_migrate = (model for model in obj.models.values() @@ -761,3 +765,23 @@ def make_with_log(model, _quantity=None, make_m2m=False, **attrs): return stub make_with_log.required = foreign_key_required + +# DISCONNECT SIGNAL ######################################################## + + +def disconecta_sinais_indexacao(): + post_save.disconnect(save_texto, NormaJuridica) + post_save.disconnect(save_texto, DocumentoAcessorio) + post_save.disconnect(save_texto, MateriaLegislativa) + post_delete.disconnect(delete_texto, NormaJuridica) + post_delete.disconnect(delete_texto, DocumentoAcessorio) + post_delete.disconnect(delete_texto, MateriaLegislativa) + + +def conecta_sinais_indexacao(): + post_save.connect(save_texto, NormaJuridica) + post_save.connect(save_texto, DocumentoAcessorio) + post_save.connect(save_texto, MateriaLegislativa) + post_delete.connect(delete_texto, NormaJuridica) + post_delete.connect(delete_texto, DocumentoAcessorio) + post_delete.connect(delete_texto, MateriaLegislativa) diff --git a/sapl/materia/signals.py b/sapl/materia/signals.py index d913e9cd8..9f08b104c 100644 --- a/sapl/materia/signals.py +++ b/sapl/materia/signals.py @@ -1,29 +1,9 @@ -from subprocess import PIPE, call -from threading import Thread - from django.db.models.signals import post_delete, post_save - -from sapl.settings import PROJECT_DIR +from sapl.utils import save_texto, delete_texto from .models import DocumentoAcessorio, MateriaLegislativa -class UpdateIndexCommand(Thread): - def run(self): - call([PROJECT_DIR.child('manage.py'), 'update_index'], - stdout=PIPE) - - -def save_texto(sender, instance, **kwargs): - update_index = UpdateIndexCommand() - update_index.start() - - -def delete_texto(sender, instance, **kwargs): - update_index = UpdateIndexCommand() - update_index.start() - - post_save.connect(save_texto, sender=MateriaLegislativa) post_save.connect(save_texto, sender=DocumentoAcessorio) post_delete.connect(delete_texto, sender=MateriaLegislativa) diff --git a/sapl/norma/signals.py b/sapl/norma/signals.py index 20d405e49..3089e563e 100644 --- a/sapl/norma/signals.py +++ b/sapl/norma/signals.py @@ -1,28 +1,8 @@ -from subprocess import PIPE, call -from threading import Thread - from django.db.models.signals import post_delete, post_save - -from sapl.settings import PROJECT_DIR +from sapl.utils import save_texto, delete_texto from .models import NormaJuridica -class UpdateIndexCommand(Thread): - def run(self): - call([PROJECT_DIR.child('manage.py'), 'update_index'], - stdout=PIPE) - - -def save_texto(sender, instance, **kwargs): - update_index = UpdateIndexCommand() - update_index.start() - - -def delete_texto(sender, instance, **kwargs): - update_index = UpdateIndexCommand() - update_index.start() - - post_save.connect(save_texto, sender=NormaJuridica) post_delete.connect(delete_texto, sender=NormaJuridica) diff --git a/sapl/utils.py b/sapl/utils.py index 3a857f337..81ebea6cc 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -5,6 +5,8 @@ import re from datetime import date from functools import wraps from unicodedata import normalize as unicodedata_normalize +from subprocess import PIPE, call +from threading import Thread import django_filters import magic @@ -22,7 +24,7 @@ from floppyforms import ClearableFileInput from reversion.admin import VersionAdmin from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row -from sapl.settings import BASE_DIR +from sapl.settings import BASE_DIR, PROJECT_DIR sapl_logger = logging.getLogger(BASE_DIR.name) @@ -632,3 +634,19 @@ def texto_upload_path(instance, filename, subpath=''): } return path + + +class UpdateIndexCommand(Thread): + def run(self): + call([PROJECT_DIR.child('manage.py'), 'update_index'], + stdout=PIPE) + + +def save_texto(sender, instance, **kwargs): + update_index = UpdateIndexCommand() + update_index.start() + + +def delete_texto(sender, instance, **kwargs): + update_index = UpdateIndexCommand() + update_index.start() From 12a3d6995e25201e5035ec9e95659883f66422b0 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 10 Apr 2017 14:18:22 -0300 Subject: [PATCH 09/26] =?UTF-8?q?Modifica=20scripts=20para=20voltar=20dire?= =?UTF-8?q?t=C3=B3rio=20padr=C3=A3o=20do=20gunicorn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 +- gunicorn_start.sh | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index ce5c283fb..74d345791 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ sapldb: - "5532:5432" web: build: . - command: /bin/sh -c "/bin/sh busy-wait.sh && python3 manage.py bower install && python3 manage.py migrate && /bin/sh gunicorn_start.sh" + command: /bin/sh -c "/bin/sh busy-wait.sh && python3 manage.py bower install && python3 manage.py migrate && /bin/sh gunicorn_start.sh /sapl" volumes: - .:/sapl links: diff --git a/gunicorn_start.sh b/gunicorn_start.sh index aebd45c83..ebbae1725 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -2,9 +2,18 @@ # As seen in http://tutos.readthedocs.org/en/latest/source/ndg.html +SAPL_DIR=/var/interlegis/sapl + +# Seta um novo diretório foi passado como raiz para o SAPL +# caso esse tenha sido passado como parâmetro +if [ "$1" ] +then + SAPL_DIR="$1" +fi + NAME="SAPL" # Name of the application (*) -DJANGODIR=/sapl/ # Django project directory (*) -SOCKFILE=/sapl/run/gunicorn.sock # we will communicate using this unix socket (*) +DJANGODIR=$SAPL_DIR # Django project directory (*) +SOCKFILE=$SAPL_DIR/gunicorn.sock # we will communicate using this unix socket (*) USER=`whoami` # the user to run as (*) GROUP=`whoami` # the group to run as (*) NUM_WORKERS=3 # how many worker processes should Gunicorn spawn (*) From d6384f631714fd9ab4930e8b7c66e1dcf360a788 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 10 Apr 2017 14:23:29 -0300 Subject: [PATCH 10/26] HOT-FIX: changes to fix gunicorn --- gunicorn_start.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gunicorn_start.sh b/gunicorn_start.sh index ebbae1725..437a15168 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -2,7 +2,7 @@ # As seen in http://tutos.readthedocs.org/en/latest/source/ndg.html -SAPL_DIR=/var/interlegis/sapl +SAPL_DIR="/var/interlegis/sapl" # Seta um novo diretório foi passado como raiz para o SAPL # caso esse tenha sido passado como parâmetro @@ -12,8 +12,8 @@ then fi NAME="SAPL" # Name of the application (*) -DJANGODIR=$SAPL_DIR # Django project directory (*) -SOCKFILE=$SAPL_DIR/gunicorn.sock # we will communicate using this unix socket (*) +DJANGODIR=$SAPL_DIR # Django project directory (*) +SOCKFILE="$SAPL_DIR/gunicorn.sock" # we will communicate using this unix socket (*) USER=`whoami` # the user to run as (*) GROUP=`whoami` # the group to run as (*) NUM_WORKERS=3 # how many worker processes should Gunicorn spawn (*) @@ -21,7 +21,7 @@ NUM_WORKERS=3 # how many worker processes shou DJANGO_SETTINGS_MODULE=sapl.settings # which settings file should Django use (*) DJANGO_WSGI_MODULE=sapl.wsgi # WSGI module name (*) -echo "Starting $NAME as `whoami`" +echo "Starting $NAME as `whoami` on base dir $SAPL_DIR" # Create the run directory if it doesn't exist RUNDIR=$(dirname $SOCKFILE) From 3a88bbba8dbc90b819cb6ae19c424964e6d1530a Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 10 Apr 2017 14:43:12 -0300 Subject: [PATCH 11/26] =?UTF-8?q?Revertendo=20a=20altera=C3=A7=C3=A3o=20do?= =?UTF-8?q?=20Dockerfile.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .travis.yml | 4 --- Dockerfile | 59 ++++++++++++++++++++++++++---------- busy-wait.sh | 10 ------ config/nginx/sapl.conf | 39 ------------------------ docker-compose.yml | 19 +++--------- gunicorn_start.sh | 12 ++++++-- sapl/.env_test | 2 +- scripts_docker/shell_sapl.sh | 3 +- 9 files changed, 59 insertions(+), 92 deletions(-) delete mode 100644 busy-wait.sh delete mode 100644 config/nginx/sapl.conf diff --git a/.gitignore b/.gitignore index e8bac47aa..83de47a86 100644 --- a/.gitignore +++ b/.gitignore @@ -92,5 +92,4 @@ collected_static bower bower_components media -whoosh/ -postgres-data/ +whoosh/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 0e0a27ad4..bf5ee38fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,3 @@ script: - ./manage.py bower install - py.test --create-db # - ./test_and_check_qa.sh - -addons: - hosts: - - 127.0.0.1 sapldb diff --git a/Dockerfile b/Dockerfile index a7bf01657..9880dc4ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,53 @@ -FROM alpine:3.5 +FROM ubuntu:15.04 -ENV BUILD_PACKAGES postgresql-dev graphviz-dev graphviz build-base git pkgconfig \ -python3-dev libxml2-dev jpeg-dev libressl-dev libffi-dev libxslt-dev nodejs py3-lxml \ -py3-magic postgresql-client +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 -RUN apk add --no-cache python3 && \ - python3 -m ensurepip && \ - rm -r /usr/lib/python*/ensurepip && \ - pip3 install --upgrade pip setuptools && \ - rm -r /root/.cache +RUN mkdir /sapl -RUN mkdir /sapl && apk add --update --no-cache $BUILD_PACKAGES && npm install -g bower +RUN echo "deb http://archive.ubuntu.com/ubuntu/ vivid universe" | tee -a "/etc/apt/sources.list" + +RUN \ + apt-get update && \ + apt-get install -y -f \ + software-properties-common \ + libpq-dev \ + graphviz-dev \ + graphviz \ + build-essential \ + git \ + pkg-config \ + python3-dev \ + libxml2-dev \ + libjpeg-dev \ + libssl-dev \ + libffi-dev \ + libxslt1-dev \ + python3-setuptools \ + curl + +# use python3 in pip +RUN easy_install3 pip lxml + +# install nodejs +RUN DEBIAN_FRONTEND=noninteractive curl -sL https://deb.nodesource.com/setup_5.x | bash - +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs + +# install bower +RUN npm install -g bower # Bower aceitar root -RUN touch /root/.bowerrc \ -&& chmod 751 /root/.bowerrc \ -&& echo "{ \"allow_root\": true }" >> /root/.bowerrc \ -&& npm cache clean +RUN touch /root/.bowerrc +RUN chmod 751 /root/.bowerrc +RUN echo "{ \"allow_root\": true }" >> /root/.bowerrc WORKDIR /sapl ADD . /sapl -RUN pip install -r requirements/dev-requirements.txt --upgrade setuptools --no-cache-dir \ -&& python3 manage.py bower install +RUN pip install -r requirements/dev-requirements.txt +RUN pip install --upgrade setuptools + +# RUN python3 manage.py bower install diff --git a/busy-wait.sh b/busy-wait.sh deleted file mode 100644 index 128592ffc..000000000 --- a/busy-wait.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -while true; do - COUNT_PG=`psql --dbname=postgresql://sapl:sapl@sapldb/sapl -c '\l \q' | grep sapl | wc -l` - if ! [ "$COUNT_PG" -eq "0" ]; then - break - fi - echo "Esperando Database Setup" - sleep 10 -done diff --git a/config/nginx/sapl.conf b/config/nginx/sapl.conf deleted file mode 100644 index 513188ed9..000000000 --- a/config/nginx/sapl.conf +++ /dev/null @@ -1,39 +0,0 @@ -upstream sapl_server { - - server unix:/sapl/run/gunicorn.sock fail_timeout=0; - -} - -server { - - listen 80; - server_name sapl.test; - - client_max_body_size 4G; - - location /static/ { - alias /sapl/collected_static/; - } - - location /media/ { - alias /sapl/media/; - } - - location / { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - proxy_set_header Host $http_host; - - proxy_redirect off; - - - if (!-f $request_filename) { - proxy_pass http://sapl_server; - break; - } - } - error_page 500 502 503 504 /500.html; - location = /500.html { - root /sapl/sapl/static/; - } -} diff --git a/docker-compose.yml b/docker-compose.yml index 74d345791..8de57e3aa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,22 +1,9 @@ -server: - image: nginx:latest - ports: - - "80:80" - volumes: - - ./config/nginx:/etc/nginx/conf.d - volumes_from: - - web - links: - - web -sapldb: +localhost: image: postgres environment: POSTGRES_PASSWORD: sapl POSTGRES_USER: sapl POSTGRES_DB: sapl - PGDATA : /var/lib/postgresql/data/ - volumes: - - ./postgres-data/data/:/var/lib/postgresql/data/ ports: - "5532:5432" web: @@ -24,5 +11,7 @@ web: command: /bin/sh -c "/bin/sh busy-wait.sh && python3 manage.py bower install && python3 manage.py migrate && /bin/sh gunicorn_start.sh /sapl" volumes: - .:/sapl + ports: + - "8000:8000" links: - - sapldb + - localhost diff --git a/gunicorn_start.sh b/gunicorn_start.sh index 437a15168..34147cb97 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -12,17 +12,23 @@ then fi NAME="SAPL" # Name of the application (*) -DJANGODIR=$SAPL_DIR # Django project directory (*) -SOCKFILE="$SAPL_DIR/gunicorn.sock" # we will communicate using this unix socket (*) +DJANGODIR=/var/interlegis/sapl # Django project directory (*) +SOCKFILE=/var/interlegis/sapl/run/gunicorn.sock # we will communicate using this unix socket (*) USER=`whoami` # the user to run as (*) GROUP=`whoami` # the group to run as (*) -NUM_WORKERS=3 # how many worker processes should Gunicorn spawn (*) +NUM_WORKERS=9 # how many worker processes should Gunicorn spawn (*) # NUM_WORKERS = 2 * CPUS + 1 DJANGO_SETTINGS_MODULE=sapl.settings # which settings file should Django use (*) DJANGO_WSGI_MODULE=sapl.wsgi # WSGI module name (*) echo "Starting $NAME as `whoami` on base dir $SAPL_DIR" +# Activate the virtual environment +cd $DJANGODIR +source /var/interlegis/.virtualenvs/sapl/bin/activate +export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE +export PYTHONPATH=$DJANGODIR:$PYTHONPATH + # Create the run directory if it doesn't exist RUNDIR=$(dirname $SOCKFILE) test -d $RUNDIR || mkdir -p $RUNDIR diff --git a/sapl/.env_test b/sapl/.env_test index 9416d402d..5c2c60ec1 100644 --- a/sapl/.env_test +++ b/sapl/.env_test @@ -1,4 +1,4 @@ -DATABASE_URL = postgresql://postgres:@sapldb:/sapl +DATABASE_URL = postgresql://postgres:@localhost:/sapl SECRET_KEY=TravisTest DEBUG=False EMAIL_USE_TLS = True diff --git a/scripts_docker/shell_sapl.sh b/scripts_docker/shell_sapl.sh index 4c993a61d..cfddefcdc 100755 --- a/scripts_docker/shell_sapl.sh +++ b/scripts_docker/shell_sapl.sh @@ -1,3 +1,2 @@ #!/bin/bash - -docker run --rm -ti sapl_web /bin/sh +docker run -ti sapl_web /bin/bash From 8675c4203e88e465cb6dd7f578530a25f0a5b7a2 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 10 Apr 2017 15:13:45 -0300 Subject: [PATCH 12/26] Concerta testes do app rules para novos models em base Signed-off-by: Luciano Almeida --- sapl/rules/map_rules.py | 2 ++ sapl/rules/tests/test_rules.py | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py index 906592fd0..05d869fd8 100644 --- a/sapl/rules/map_rules.py +++ b/sapl/rules/map_rules.py @@ -197,6 +197,8 @@ rules_group_geral = { (base.CasaLegislativa, __listdetailchange__), (base.ProblemaMigracao, []), + (base.Argumento, []), + (base.Constraint, []), (base.TipoAutor, __base__), (base.Autor, __base__), diff --git a/sapl/rules/tests/test_rules.py b/sapl/rules/tests/test_rules.py index 3662477b9..6fc7eb3fe 100644 --- a/sapl/rules/tests/test_rules.py +++ b/sapl/rules/tests/test_rules.py @@ -6,7 +6,8 @@ from django.contrib.contenttypes.models import ContentType from django.utils import six from django.utils.translation import ugettext_lazy as _ -from sapl.base.models import CasaLegislativa, ProblemaMigracao +from sapl.base.models import (CasaLegislativa, ProblemaMigracao, Argumento, + Constraint) from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, TipoDispositivo, TipoDispositivoRelationship) @@ -56,11 +57,15 @@ def test_models_in_rules_patterns(model_item): __fp__in__test_permission_of_models_in_rules_patterns = { map_rules.RP_ADD: [CasaLegislativa, ProblemaMigracao, + Argumento, + Constraint, TipoDispositivo, TipoDispositivoRelationship, PerfilEstruturalTextoArticulado], map_rules.RP_CHANGE: [ProblemaMigracao, + Argumento, + Constraint, AcompanhamentoMateria, TipoDispositivo, TipoDispositivoRelationship, @@ -68,17 +73,23 @@ __fp__in__test_permission_of_models_in_rules_patterns = { map_rules.RP_DELETE: [CasaLegislativa, ProblemaMigracao, + Argumento, + Constraint, TipoDispositivo, TipoDispositivoRelationship, PerfilEstruturalTextoArticulado], map_rules.RP_LIST: [ProblemaMigracao, + Argumento, + Constraint, AcompanhamentoMateria, TipoDispositivo, TipoDispositivoRelationship, PerfilEstruturalTextoArticulado], map_rules.RP_DETAIL: [ProblemaMigracao, + Argumento, + Constraint, AcompanhamentoMateria, TipoDispositivo, TipoDispositivoRelationship, From 1f74371cd3189720efe04269698edefc4d709999 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 11 Apr 2017 15:19:42 -0300 Subject: [PATCH 13/26] Closes #1008 --- sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index 24796bb13..a4648b71d 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -182,7 +182,7 @@ def expediente_materia(lst_expediente_materia): tmp += '' + txt_ementa + '\n' tmp += '' + \ str(expediente_materia['nom_resultado']) + '\n' + '' + \ - str(expediente_materia['votacao_observacao']) + '\n' + '\n' tmp += '\t\t\n' return tmp @@ -237,7 +237,7 @@ def votacao(lst_votacao): tmp += '' + txt_ementa + '\n' tmp += '' + \ str(votacao['nom_resultado']) + '\n' + '' + \ - str(votacao['votacao_observacao']) + '\n' + '\n' tmp += '\t\t\n' return tmp From 1b37465be4de0478b2c5d4ba7ae9c25ac5bbc61f Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 11 Apr 2017 15:45:58 -0300 Subject: [PATCH 14/26] downgrade trml2pdf --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 3a0e5b446..6d7592cda 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -19,7 +19,7 @@ django-sass-processor==0.4.6 djangorestframework drfdocs easy-thumbnails==2.3 -trml2pdf==0.4.2 +git+git://github.com/interlegis/trml2pdf.git libsass==0.11.1 psycopg2==2.6.2 python-decouple==3.0 From 575a47af4cbaf77044a8fb9ac439cd5cc96cd863 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Wed, 12 Apr 2017 11:24:46 -0300 Subject: [PATCH 15/26] =?UTF-8?q?Dinamiza=20pesquisa=20por=20Sess=C3=A3o?= =?UTF-8?q?=20Plen=C3=A1ria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/settings.py | 1 + sapl/templates/base.html | 2 + .../sessao/sessaoplenaria_filter.html | 49 ++++++++++++++++--- .../templates/sessao/sessaoplenaria_form.html | 1 - 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/sapl/settings.py b/sapl/settings.py index d9875994b..11b94b3de 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -237,6 +237,7 @@ BOWER_INSTALLED_APPS = ( 'jQuery-Mask-Plugin#1.14.0', 'jsdiff#2.2.2', 'https://github.com/interlegis/drunken-parrot-flat-ui.git', + 'jquery-query-object#2.2.3', ) # Additional search paths for SASS files when using the @import statement diff --git a/sapl/templates/base.html b/sapl/templates/base.html index a96815f62..51351e7a0 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -224,6 +224,8 @@ + + {% block extra_js %}{% endblock %} {% endblock foot_js %} diff --git a/sapl/templates/sessao/sessaoplenaria_filter.html b/sapl/templates/sessao/sessaoplenaria_filter.html index b4aa4ca98..ac39d87fa 100644 --- a/sapl/templates/sessao/sessaoplenaria_filter.html +++ b/sapl/templates/sessao/sessaoplenaria_filter.html @@ -9,16 +9,11 @@ {% blocktrans with verbose_name=view.verbose_name %} Adicionar Sessão Plenária {% endblocktrans %} {% endif %} - {% if filter_url %} - {% trans 'Fazer nova pesquisa' %} - {% endif %} {% endblock %} {% block detail_content %} - {% if not filter_url %} - {% crispy filter.form %} - {% endif %} + {% crispy filter.form %} {% if filter_url %}

@@ -51,3 +46,45 @@ {% endblock detail_content %} {% block table_content %} {% endblock table_content %} + + +{% block extra_js %} + + + +{% endblock %} \ No newline at end of file diff --git a/sapl/templates/sessao/sessaoplenaria_form.html b/sapl/templates/sessao/sessaoplenaria_form.html index cf8cbd64f..81057ba57 100644 --- a/sapl/templates/sessao/sessaoplenaria_form.html +++ b/sapl/templates/sessao/sessaoplenaria_form.html @@ -31,7 +31,6 @@ $(function() { function altera_legislatura(){ - console.debug('hey'); var id_legislatura = $("#id_legislatura").val(); var id_sessao_leg = $("#id_sessao_legislativa").val(); $("#id_sessao_legislativa option").remove(); From 323604bf1bf360be7feeba91624e38ebe96baf17 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Wed, 12 Apr 2017 11:24:46 -0300 Subject: [PATCH 16/26] =?UTF-8?q?Dinamiza=20pesquisa=20por=20Sess=C3=A3o?= =?UTF-8?q?=20Plen=C3=A1ria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/settings.py | 1 + sapl/templates/base.html | 2 + .../sessao/sessaoplenaria_filter.html | 45 ++++++++++++++++--- .../templates/sessao/sessaoplenaria_form.html | 1 - 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/sapl/settings.py b/sapl/settings.py index d9875994b..11b94b3de 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -237,6 +237,7 @@ BOWER_INSTALLED_APPS = ( 'jQuery-Mask-Plugin#1.14.0', 'jsdiff#2.2.2', 'https://github.com/interlegis/drunken-parrot-flat-ui.git', + 'jquery-query-object#2.2.3', ) # Additional search paths for SASS files when using the @import statement diff --git a/sapl/templates/base.html b/sapl/templates/base.html index a96815f62..51351e7a0 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -224,6 +224,8 @@ + + {% block extra_js %}{% endblock %} {% endblock foot_js %} diff --git a/sapl/templates/sessao/sessaoplenaria_filter.html b/sapl/templates/sessao/sessaoplenaria_filter.html index b4aa4ca98..8c77a3ee2 100644 --- a/sapl/templates/sessao/sessaoplenaria_filter.html +++ b/sapl/templates/sessao/sessaoplenaria_filter.html @@ -9,16 +9,11 @@ {% blocktrans with verbose_name=view.verbose_name %} Adicionar Sessão Plenária {% endblocktrans %} {% endif %} - {% if filter_url %} - {% trans 'Fazer nova pesquisa' %} - {% endif %} {% endblock %} {% block detail_content %} - {% if not filter_url %} - {% crispy filter.form %} - {% endif %} + {% crispy filter.form %} {% if filter_url %}

@@ -51,3 +46,41 @@ {% endblock detail_content %} {% block table_content %} {% endblock table_content %} + + +{% block extra_js %} + + + +{% endblock %} \ No newline at end of file diff --git a/sapl/templates/sessao/sessaoplenaria_form.html b/sapl/templates/sessao/sessaoplenaria_form.html index cf8cbd64f..81057ba57 100644 --- a/sapl/templates/sessao/sessaoplenaria_form.html +++ b/sapl/templates/sessao/sessaoplenaria_form.html @@ -31,7 +31,6 @@ $(function() { function altera_legislatura(){ - console.debug('hey'); var id_legislatura = $("#id_legislatura").val(); var id_sessao_leg = $("#id_sessao_legislativa").val(); $("#id_sessao_legislativa option").remove(); From 451e2949a544524dbaaa30baae3e4b5abcc4f7f9 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 12 Apr 2017 13:14:40 -0300 Subject: [PATCH 17/26] Verifica qtd de constraints unique together --- sapl/legacy/migration.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 9fee4683e..4a748d49f 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -17,19 +17,20 @@ from django.db.models.signals import post_delete, post_save from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make -from sapl.base.models import Autor, ProblemaMigracao, Constraint, Argumento +from sapl.base.models import Argumento, Autor, Constraint, ProblemaMigracao from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.legacy.models import Protocolo as ProtocoloLegado -from sapl.materia.models import (StatusTramitacao, TipoDocumento, Tramitacao, +from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, + StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, - DocumentoAcessorio, MateriaLegislativa) + Tramitacao) from sapl.norma.models import (AssuntoNorma, NormaJuridica, TipoVinculoNormaJuridica) from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia from sapl.settings import PROJECT_DIR -from sapl.utils import normalize, save_texto, delete_texto +from sapl.utils import delete_texto, normalize, save_texto # BASE ###################################################################### # apps to be migrated, in app dependency order (very important) @@ -202,6 +203,12 @@ def iter_sql_records(sql, db): record.__dict__.update(zip(fieldnames, row)) yield record +# Todos os models têm no máximo uma constraint unique together +# Isso é necessário para que o método delete_constraints funcione corretamente +assert all(len(model._meta.unique_together) <= 1 + for app in appconfs + for model in app.models.values()) + def delete_constraints(model): # pega nome da unique constraint dado o nome da tabela @@ -221,10 +228,8 @@ def delete_constraints(model): for w in words_list: Argumento.objects.create(constraint=constraint, argumento=w) else: - args = None if model._meta.unique_together: - args = model._meta.unique_together[0] - args_list = list(args) + args_list = model._meta.unique_together[0] constraint = Constraint.objects.create( nome_tabela=table, nome_constraint=r[0], nome_model=model.__name__, From e98032d2271f0509a95bb4be207c324b80a65147 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 12 Apr 2017 18:11:13 -0300 Subject: [PATCH 18/26] =?UTF-8?q?Conserta=20bug=20que=20pegava=20o=20resul?= =?UTF-8?q?tado=20das=20vota=C3=A7=C3=B5es=20do=20lugar=20errado.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/views.py | 15 ++++++--------- sapl/sessao/views.py | 40 ++++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 9e482abda..a5b129118 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -594,11 +594,9 @@ def get_sessao_plenaria(sessao, casa): dic_expediente_materia["nom_autor"] = 'Desconhecido' dic_expediente_materia["votacao_observacao"] = ' ' - if not expediente_materia.resultado: - resultado = RegistroVotacao.objects.filter( - tipo_resultado_votacao=expediente_materia.tipo_votacao) - - for i in resultado: + resultados = expediente_materia.registrovotacao_set.all() + if resultados: + for i in resultados: dic_expediente_materia["nom_resultado"] = ( i.tipo_resultado_votacao.nome) dic_expediente_materia["votacao_observacao"] = ( @@ -710,10 +708,9 @@ def get_sessao_plenaria(sessao, casa): dic_votacao["nom_autor"] = 'Desconhecido' dic_votacao["votacao_observacao"] = ' ' - if not votacao.resultado: - resultado = RegistroVotacao.objects.filter( - tipo_resultado_votacao=votacao.tipo_votacao) - for i in resultado: + resultados = votacao.registrovotacao_set.all() + if resultados: + for i in resultados: dic_votacao["nom_resultado"] = i.tipo_resultado_votacao.nome if votacao.observacao: dic_votacao["votacao_observacao"] = votacao.observacao diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index e56cb749e..25f72499f 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -164,7 +164,8 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): def get_rows(self, object_list): for obj in object_list: - if not obj.resultado: + resultados = obj.registrovotacao_set.all() + if not resultados: if obj.votacao_aberta: url = '' if obj.tipo_votacao == 1: @@ -208,6 +209,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): else: obj.resultado = '''Não há resultado''' else: + resultado = resultados[0].tipo_resultado_votacao.nome if self.request.user.has_module_perms(AppConfig.label): url = '' if obj.tipo_votacao == 1: @@ -229,9 +231,9 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): 'oid': obj.materia_id, 'mid': obj.pk}) obj.resultado = '%s' % (url, - obj.resultado) + resultado) else: - obj.resultado = '%s' % (obj.resultado) + obj.resultado = '%s' % (resultado) return [self._as_row(obj) for obj in object_list] @@ -268,7 +270,8 @@ class ExpedienteMateriaCrud(MasterDetailCrud): def get_rows(self, object_list): for obj in object_list: - if not obj.resultado: + resultados = obj.registrovotacao_set.all() + if not resultados: if obj.votacao_aberta: url = '' if obj.tipo_votacao == 1: @@ -310,7 +313,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud): obj.resultado = btn_abrir else: url = '' - + resultado = resultados[0].tipo_resultado_votacao.nome if self.request.user.has_module_perms(AppConfig.label): if obj.tipo_votacao == 1: url = reverse( @@ -332,7 +335,9 @@ class ExpedienteMateriaCrud(MasterDetailCrud): 'oid': obj.materia_id, 'mid': obj.pk}) obj.resultado = '%s' % (url, - obj.resultado) + resultado) + else: + obj.resultado = '%s' % (resultado) return [self._as_row(obj) for obj in object_list] class CreateView(MasterDetailCrud.CreateView): @@ -982,12 +987,14 @@ class ResumoView(DetailView): materias_expediente = [] for m in materias: + ementa = m.observacao titulo = m.materia numero = m.numero_ordem - if m.resultado: - resultado = m.resultado + resultado = m.registrovotacao_set.all() + if resultado: + resultado = resultado[0].tipo_resultado_votacao.nome else: resultado = _('Matéria não votada') @@ -1039,7 +1046,6 @@ class ResumoView(DetailView): # Matérias Ordem do Dia ordem = OrdemDia.objects.filter( sessao_plenaria_id=self.object.id) - materias_ordem = [] for o in ordem: ementa = o.observacao @@ -1047,8 +1053,9 @@ class ResumoView(DetailView): numero = o.numero_ordem # Verificar resultado - if o.resultado: - resultado = o.resultado + resultado = o.registrovotacao_set.all() + if resultado: + resultado = resultado[0].tipo_resultado_votacao.nome else: resultado = _('Matéria não votada') @@ -2065,9 +2072,9 @@ class PautaSessaoDetailView(DetailView): situacao = m.materia.tramitacao_set.last().status if situacao is None: situacao = _("Não informada") - - if m.resultado: - resultado = m.resultado + resultado = m.registrovotacao_set.all() + if resultado: + resultado = resultado[0].tipo_resultado_votacao.nome else: resultado = _('Matéria não votada') @@ -2118,8 +2125,9 @@ class PautaSessaoDetailView(DetailView): numero = o.numero_ordem # Verificar resultado - if o.resultado: - resultado = o.resultado + resultado = o.registrovotacao_set.all() + if resultado: + resultado = resultado[0].tipo_resultado_votacao.nome else: resultado = _('Matéria não votada') From 25be37eb0dc69b9962d49ebc2b42c0847956f824 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 12 Apr 2017 19:40:22 -0300 Subject: [PATCH 19/26] =?UTF-8?q?Ajusta=20a=20ordem=20das=20partes=20do=20?= =?UTF-8?q?expediente=20no=20relat=C3=B3rio=20para=20ficar=20em=20conformi?= =?UTF-8?q?dade=20com=20o=20resumo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/views.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index a5b129118..0ae5bb39f 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -518,14 +518,14 @@ def get_sessao_plenaria(sessao, casa): # Exibe os Expedientes lst_expedientes = [] - for tip_expediente in TipoExpediente.objects.all(): - for expediente in ExpedienteSessao.objects.filter( - sessao_plenaria=sessao, tipo=tip_expediente): - dic_expedientes = {} - dic_expedientes["nom_expediente"] = str(tip_expediente) - dic_expedientes["txt_expediente"] = (expediente.conteudo) - if dic_expedientes: - lst_expedientes.append(dic_expedientes) + expedientes = ExpedienteSessao.objects.filter( + sessao_plenaria=sessao).order_by('tipo__nome') + for e in expedientes: + dic_expedientes = {} + dic_expedientes["nom_expediente"] = str(e.tipo) + dic_expedientes["txt_expediente"] = (e.conteudo) + if dic_expedientes: + lst_expedientes.append(dic_expedientes) # Lista das matérias do Expediente, incluindo o resultado das votacoes lst_expediente_materia = [] From b11596167371f4716fd779756e002dc7e11835a6 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 12 Apr 2017 19:49:47 -0300 Subject: [PATCH 20/26] =?UTF-8?q?Adiciona=20quebra=20de=20linha=20em=20rel?= =?UTF-8?q?at=C3=B3rio=20de=20sess=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py | 2 +- sapl/relatorios/views.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index a4648b71d..ec465b485 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -155,7 +155,7 @@ def expedientes(lst_expedientes): tmp += '\t\t\t \n' tmp += '\t\t\n' for expediente in lst_expedientes: - tmp += '\t\t' + \ + tmp += '\t\t' + '
' + \ expediente['nom_expediente'] + ':
\n' + \ '' + \ expediente['txt_expediente'] + '\n' diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 0ae5bb39f..4a76eee3a 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -522,8 +522,8 @@ def get_sessao_plenaria(sessao, casa): sessao_plenaria=sessao).order_by('tipo__nome') for e in expedientes: dic_expedientes = {} - dic_expedientes["nom_expediente"] = str(e.tipo) - dic_expedientes["txt_expediente"] = (e.conteudo) + dic_expedientes["nom_expediente"] = e.tipo.nome + dic_expedientes["txt_expediente"] = e.conteudo if dic_expedientes: lst_expedientes.append(dic_expedientes) From 940fa8166cc30e6282b8d7ffeabe5a3df22cf743 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 17 Apr 2017 13:21:18 -0300 Subject: [PATCH 21/26] =?UTF-8?q?Fixes=20#1011=20e=20ainda=20mant=C3=A9m?= =?UTF-8?q?=20#1008?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/pdf_sessao_plenaria_gerar.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index ec465b485..b2287d989 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -154,10 +154,10 @@ def expedientes(lst_expedientes): tmp += '\t\t\n' tmp += '\t\t\t \n' tmp += '\t\t\n' - for expediente in lst_expedientes: + for idx, expediente in enumerate(lst_expedientes): tmp += '\t\t' + '
' + \ expediente['nom_expediente'] + ':
\n' + \ - '' + \ + '' + \ expediente['txt_expediente'] + '\n' tmp += '\t\t\n' tmp += '\t\t\t \n' @@ -181,8 +181,12 @@ def expediente_materia(lst_expediente_materia): txt_ementa = expediente_materia['txt_ementa'].replace('&', '&') tmp += '' + txt_ementa + '\n' tmp += '' + \ - str(expediente_materia['nom_resultado']) + '\n' + '' + \ - '\n' + str(expediente_materia['nom_resultado']) + '
\n' + '' + if expediente_materia['votacao_observacao'] != txt_ementa: + tmp += str(expediente_materia['votacao_observacao']) + else: + tmp += 'Vazio' + tmp += '\n' tmp += '\t\t\n' return tmp @@ -236,8 +240,12 @@ def votacao(lst_votacao): txt_ementa = votacao['txt_ementa'].replace('&', '&') tmp += '' + txt_ementa + '\n' tmp += '' + \ - str(votacao['nom_resultado']) + '\n' + '' + \ - '\n' + str(votacao['nom_resultado']) + '\n' + '' + if votacao['votacao_observacao'] != txt_ementa: + tmp += str(votacao['votacao_observacao']) + else: + tmp += 'Vazio' + tmp += '\n' tmp += '\t\t\n' return tmp @@ -290,6 +298,7 @@ def principal(cabecalho_dic, rodape_dic, imagem, sessao, inf_basicas_dic, lst_me tmp += oradores(lst_oradores) tmp += '\t\n' tmp += '\n' + tmp_pdf = parseString(tmp) return tmp_pdf # if hasattr(context.temp_folder,arquivoPdf): From b4a8591294a47567835299b9df87520764dadddc Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 17 Apr 2017 14:21:00 -0300 Subject: [PATCH 22/26] =?UTF-8?q?Conserta=20bug=20onde=20observa=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20vota=C3=A7=C3=A3o=20pega=20de=20lugar=20errado.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bug.txt | 0 sapl/relatorios/views.py | 6 ++++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 bug.txt diff --git a/bug.txt b/bug.txt new file mode 100644 index 000000000..e69de29bb diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 4a76eee3a..bdd3fc1d9 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -600,7 +600,7 @@ def get_sessao_plenaria(sessao, casa): dic_expediente_materia["nom_resultado"] = ( i.tipo_resultado_votacao.nome) dic_expediente_materia["votacao_observacao"] = ( - expediente_materia.observacao) + i.observacao) else: dic_expediente_materia["nom_resultado"] = _("Matéria não votada") dic_expediente_materia["votacao_observacao"] = _("Vazio") @@ -713,7 +713,7 @@ def get_sessao_plenaria(sessao, casa): for i in resultados: dic_votacao["nom_resultado"] = i.tipo_resultado_votacao.nome if votacao.observacao: - dic_votacao["votacao_observacao"] = votacao.observacao + dic_votacao["votacao_observacao"] = i.observacao else: dic_votacao["nom_resultado"] = _("Matéria não votada") dic_votacao["votacao_observacao"] = _("Vazio") @@ -779,6 +779,8 @@ def relatorio_sessao_plenaria(request, pk): lst_votacao, lst_oradores) = get_sessao_plenaria(sessao, casa) +# import ipdb; ipdb.set_trace() + pdf = pdf_sessao_plenaria_gerar.principal( cabecalho, rodape, From 924f02de04de63cdf5c970e2e68bc559dfd5cbf5 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 17 Apr 2017 15:26:15 -0300 Subject: [PATCH 23/26] =?UTF-8?q?Adiciona=20observa=C3=A7=C3=A3o=20do=20re?= =?UTF-8?q?sultado=20da=20vota=C3=A7=C3=A3o=20em=20tela=20de=20ordem=20do?= =?UTF-8?q?=20dia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/views.py | 2 -- sapl/sessao/views.py | 10 +++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index bdd3fc1d9..9ffdd443e 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -779,8 +779,6 @@ def relatorio_sessao_plenaria(request, pk): lst_votacao, lst_oradores) = get_sessao_plenaria(sessao, casa) -# import ipdb; ipdb.set_trace() - pdf = pdf_sessao_plenaria_gerar.principal( cabecalho, rodape, diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 25f72499f..419ea4fa0 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -210,6 +210,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): obj.resultado = '''Não há resultado''' else: resultado = resultados[0].tipo_resultado_votacao.nome + resultado_observacao = resultados[0].observacao if self.request.user.has_module_perms(AppConfig.label): url = '' if obj.tipo_votacao == 1: @@ -230,10 +231,13 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): 'pk': obj.sessao_plenaria_id, 'oid': obj.materia_id, 'mid': obj.pk}) - obj.resultado = '%s' % (url, - resultado) + obj.resultado = ('%s
%s' % + (url, + resultado, + resultado_observacao)) else: - obj.resultado = '%s' % (resultado) + obj.resultado = ('%s
%s' % + (resultado, resultado_observacao)) return [self._as_row(obj) for obj in object_list] From 0f8e37ea876220ed457957d92e8134dcafc2d7fc Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 17 Apr 2017 15:36:32 -0300 Subject: [PATCH 24/26] Fixes #1002 --- .../templates/pdf_sessao_plenaria_gerar.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index b2287d989..d474bc8c4 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -101,7 +101,7 @@ def inf_basicas(inf_basicas_dic): tmp += '\t\tInformações Básicas\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' tmp += '\t\tTipo da Sessão: ' + \ nom_sessao + '\n' @@ -120,7 +120,7 @@ def mesa(lst_mesa): tmp = '' tmp += '\t\tMesa Diretora\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' for mesa in lst_mesa: tmp += '\t\t' + \ @@ -136,7 +136,7 @@ def presenca(lst_presenca_sessao): tmp = '' tmp += '\t\tLista de Presença da Sessão\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' for presenca in lst_presenca_sessao: tmp += '\t\t' + \ @@ -171,7 +171,7 @@ def expediente_materia(lst_expediente_materia): tmp = '' tmp += '\t\tMatérias do Expediente\n\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' tmp += '\n' tmp += 'MatériaEmentaResultado da Votação\n' @@ -199,7 +199,7 @@ def oradores_expediente(lst_oradores_expediente): tmp = '' tmp += '\t\tOradores do Expediente\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' for orador_expediente in lst_oradores_expediente: tmp += '\t\t' + str(orador_expediente['num_ordem']) + ' - ' + orador_expediente[ @@ -214,7 +214,7 @@ def presenca_ordem_dia(lst_presenca_ordem_dia): tmp = '' tmp += '\t\tLista de Presença da Ordem do Dia\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' for presenca_ordem_dia in lst_presenca_ordem_dia: tmp += '\t\t' + \ @@ -230,7 +230,7 @@ def votacao(lst_votacao): tmp = '' tmp += 'Matérias da Ordem do Dia\n\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' tmp += '\n' tmp += 'MatériaEmentaResultado da Votação\n' @@ -258,7 +258,7 @@ def oradores(lst_oradores): tmp = '' tmp += '\t\tOradores das Explicações Pessoais\n' tmp += '\t\t\n' - tmp += '\t\t\t \n' + tmp += '\t\t\t
\n' tmp += '\t\t
\n' for orador in lst_oradores: tmp += '\t\t' + \ From 69a8472ff3d361a356d779fae789b2d9f27713e6 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 17 Apr 2017 15:54:49 -0300 Subject: [PATCH 25/26] =?UTF-8?q?Remove=20a=20palavra=20'Vazio'=20quando?= =?UTF-8?q?=20n=C3=A3o=20existe=20observa=C3=A7=C3=A3o=20em=20resultado=20?= =?UTF-8?q?de=20vota=C3=A7=C3=A3o.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py | 4 ++-- sapl/relatorios/views.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index d474bc8c4..5917d0f8b 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -185,7 +185,7 @@ def expediente_materia(lst_expediente_materia): if expediente_materia['votacao_observacao'] != txt_ementa: tmp += str(expediente_materia['votacao_observacao']) else: - tmp += 'Vazio' + tmp += ' ' tmp += '\n' tmp += '\t\t
\n' @@ -244,7 +244,7 @@ def votacao(lst_votacao): if votacao['votacao_observacao'] != txt_ementa: tmp += str(votacao['votacao_observacao']) else: - tmp += 'Vazio' + tmp += ' ' tmp += '
\n' tmp += '\t\t
\n' diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 9ffdd443e..3a2ccd047 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -603,7 +603,7 @@ def get_sessao_plenaria(sessao, casa): i.observacao) else: dic_expediente_materia["nom_resultado"] = _("Matéria não votada") - dic_expediente_materia["votacao_observacao"] = _("Vazio") + dic_expediente_materia["votacao_observacao"] = _(" ") lst_expediente_materia.append(dic_expediente_materia) # Lista dos oradores do Expediente @@ -716,7 +716,7 @@ def get_sessao_plenaria(sessao, casa): dic_votacao["votacao_observacao"] = i.observacao else: dic_votacao["nom_resultado"] = _("Matéria não votada") - dic_votacao["votacao_observacao"] = _("Vazio") + dic_votacao["votacao_observacao"] = _(" ") lst_votacao.append(dic_votacao) # Lista dos oradores nas Explicações Pessoais From e007c5e33baed76cc815f9954c54bdff18ec75ca Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 17 Apr 2017 16:36:39 -0300 Subject: [PATCH 26/26] =?UTF-8?q?Desliga=20indexa=C3=A7=C3=A3o=20ao=20migr?= =?UTF-8?q?ar=20documentos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migracao_documentos.py | 28 ++++++++++++++++++++++++++++ sapl/legacy/migration.py | 4 ++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sapl/legacy/migracao_documentos.py b/sapl/legacy/migracao_documentos.py index 4d9877fa7..21697dc4f 100644 --- a/sapl/legacy/migracao_documentos.py +++ b/sapl/legacy/migracao_documentos.py @@ -4,6 +4,7 @@ import re import magic +from django.db.models.signals import post_delete, post_save from sapl.base.models import CasaLegislativa from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, Proposicao) @@ -12,6 +13,8 @@ from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import DocumentoAdministrativo from sapl.sessao.models import SessaoPlenaria from sapl.settings import MEDIA_ROOT +from sapl.utils import delete_texto, save_texto + # MIGRAÇÃO DE DOCUMENTOS ################################################### EXTENSOES = { @@ -160,7 +163,29 @@ def migrar_docs_por_ids(tipo): tipo.__name__, id, destino)) +def desconecta_sinais_indexacao(): + post_save.disconnect(save_texto, NormaJuridica) + post_save.disconnect(save_texto, DocumentoAcessorio) + post_save.disconnect(save_texto, MateriaLegislativa) + post_delete.disconnect(delete_texto, NormaJuridica) + post_delete.disconnect(delete_texto, DocumentoAcessorio) + post_delete.disconnect(delete_texto, MateriaLegislativa) + + +def conecta_sinais_indexacao(): + post_save.connect(save_texto, NormaJuridica) + post_save.connect(save_texto, DocumentoAcessorio) + post_save.connect(save_texto, MateriaLegislativa) + post_delete.connect(delete_texto, NormaJuridica) + post_delete.connect(delete_texto, DocumentoAcessorio) + post_delete.connect(delete_texto, MateriaLegislativa) + + def migrar_documentos(): + # precisamos excluir os sinais de post_save e post_delete para não que o + # computador não trave com a criação de threads desnecessárias + desconecta_sinais_indexacao() + # aqui supomos que uma pasta chamada sapl_documentos está em MEDIA_ROOT # com o conteúdo da pasta de mesmo nome do zope # Os arquivos da pasta serão movidos para a nova estrutura e a pasta será @@ -186,3 +211,6 @@ def migrar_documentos(): len(sobrando))) for doc in sobrando: print(' {}'. format(doc)) + # + # reconexão dos sinais desligados no inicio da migração de documentos + conecta_sinais_indexacao() diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 4a748d49f..8cfa25a4e 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -453,7 +453,7 @@ class DataMigrator: call([PROJECT_DIR.child('manage.py'), 'flush', '--database=default', '--no-input'], stdout=PIPE) - disconecta_sinais_indexacao() + desconecta_sinais_indexacao() info('Começando migração: %s...' % obj) self._do_migrate(obj) @@ -774,7 +774,7 @@ make_with_log.required = foreign_key_required # DISCONNECT SIGNAL ######################################################## -def disconecta_sinais_indexacao(): +def desconecta_sinais_indexacao(): post_save.disconnect(save_texto, NormaJuridica) post_save.disconnect(save_texto, DocumentoAcessorio) post_save.disconnect(save_texto, MateriaLegislativa)